📄 debug.c
字号:
/************************************************************* * File: mon/debug.c * Purpose: Part of core Monitor * Author: Phil Bunce (pjb@carmel.com) * Revision History: * 970304 Start of revision history * 970311 Changed dbxmode to gdbmode * 970331 Added 'b', 'a' and 'v' commands. * 970410 Added code to set reg a1 to zero * 970520 Added code to B and A to return error codes * 980619 Removed 'dbx' from help message * 990304 Added close of hostfd on 'x'. Fixes fd leak w sde3. *//************************************************************* * This module provides dbx support, permitting PMON to be used as * an execution vehicle when source-level debugging with MIPS' dbx. * It also permits operation with gdb using the 'target mips' command. To use this feature perform the following steps: 1. Create the file /etc/remote.pdbx which should contain the following single line. pmon:dv=/dev/tty1:br#9600 2. Create the file ~/.dbxinit which should contain the following, set $pdbxport="pmon" set $usesockets=0 set $manual_load=1 3. Download the program to the target system 4. Invoke dbx using the following command, dbx -prom <obj_file> 5. Optionally set breakpoints e.g., "bp main". 6. Start execution using the dbx command "run". 7. Type "debug" on the target system's console.*************************************************************//* * Messages are transmitted over an RS232 serial link, and are of the * form: * ^V type+len sequence# data checkSum * These messages are transmitted by the routine putpkt and received by * getpkt. */#include <setjmp.h>#include <fcntl.h>#include <mon.h>#include <stdio.h>#define DATA 0#define ACKPKT 0x20#define nextseq(x) (((x)>=63)?0:x+1)#define TIMEOUT 300000Optdesc debug_opts[] = { {"[-svV] [-c args]","enter gdb mode"}, {"-s","don't set client sp"}, {"-c <args>","args to be passed to client"}, {"-v","report protocol errors"}, {"-V","verbose mode"}, {0}};int myseq;int hisseq;int hostfd;int Vflag;jmp_buf pktstart;jmp_buf timeout;int gdbmode;jmp_buf dbx_jmpbuf;extern char clientcmd[LINESZ];extern FILE *dfp;extern int verbose;static void do_req();static putmsg();static getmsg();static putpkt();static getpkt();static readc();/************************************************************** debug(ac,av)* The 'debug' command*/debug(ac,av)int ac;char *av[];{char *hostport;int i,j,sflag;strcpy(clientcmd,av[0]);strcat(clientcmd," ");if (dfp == 0) dfp = stdout;vflag = Vflag = verbose;sflag = 0;for (i=1;i<ac;i++) { if (av[i][0] == '-') { for (j=1;av[i][j] != 0;j++) { if (av[i][j] == 'v') vflag = 1; else if (av[i][j] == 'V') Vflag = 1; else if (av[i][j] == 's') sflag = 1; else if (av[i][j] == 'c') { for (i++;i<ac;i++) { strcat(clientcmd,av[i]); strcat(clientcmd," "); } break; } else printf("%c: unknown option\n",av[i][j]); } } else printf("%s: unrecognized argument\n",av[i]); }hostport = getMonEnv("hostport");if (Vflag) printf("hostport=%s\n",hostport);hostfd = open(hostport,O_RDWR);if (hostfd == -1) { printf("can't open %s\n",hostport); return(1); }if (Vflag) printf("hostfd=%d\n",hostfd);ioctl_cbreak(hostfd);#ifdef NEWVERSION/* the idea is to make the startup easier. However, this won'twork the old way. So it's commented out for now. */for (;;) { write(hostfd,"\r",1); for (i=0;i<1000000;i++) ; i = ioctl_fionread(hostfd); if (i > 0) break; for (i=0;i<1000000;i++) ; if (Vflag) putchar('.'); }#elsewrite(hostfd,"\r",1);#endifmyseq = hisseq = 0;if (!sflag) putGpr(29,clienttos());putGpr(5,0); /* set a1 to zero *//* This stops a crash in crt1.s when attempting to see * if timing was requested.*/gdbmode = 1;dbgmode(0);}/************************************************************** dbgmode(type) * enter dbx mode* dbgmode(0) -- initial condition* dbgmode(1) -- after a continue* dbgmode(2) -- after a single-step*/dbgmode(type)int type;{char rxstr[80],*rxarg[8];int ac,n;if (n=setjmp(dbx_jmpbuf)) type = n;switch (type) { case 0 : putmsg(hostfd,&myseq,"0x1 b 0x0 0x57F"); break; case 1 : putmsg(hostfd,&myseq,"0x1 c 0x0 0x57f"); break; case 2 : putmsg(hostfd,&myseq,"0x1 s 0x0 0x57f"); break; case 3 : putmsg(hostfd,&myseq,"0x1 c 0x0 0x57f 0x1"); break; /* wasbda */ }for (;;) { getmsg(hostfd,&hisseq,rxstr); ac = argvize(rxarg,rxstr); do_req(hostfd,ac,rxarg); }}/************************************************************** void gdbstop(int n)* n should be 1, 2 or 3.*/gdbstop(n)int n;{longjmp(dbx_jmpbuf,n);}/************************************************************** static putmsg(fd,seq,msg) * send msg, including wait for the ACK*/static putmsg(fd,seq,msg) int fd,*seq;char *msg;{int type,ts,ns;ns = nextseq(*seq);for (;;) { setjmp(timeout); putpkt(fd,*seq,msg); if ((type = getpkt(fd,&ts,0)) == ACKPKT && ts == ns) break; if (vflag) fprintf(dfp,"bad ACK type=%02x got seq=%d wanted seq=%d\n", type,ts,ns); if (ts != ns) putpkt(fd,nextseq(ts),0); }*seq = ns;if (Vflag) fprintf(dfp,"\n");}/************************************************************** static getmsg(fd,seq,msg) * get msg, including send the ACK*/static getmsg(fd,seq,msg)int fd,*seq;char *msg;{int type,ts;for (;;) { if ((type = getpkt(fd,&ts,msg)) == DATA && ts == *seq) break; if (vflag) fprintf(dfp,"bad DATA type=%02x seq=%d msg=%s\n",type,ts,msg); }*seq = nextseq(*seq);putpkt(fd,*seq,0);}/************************************************************** static putpkt(fd,seq,msg) * send a packet, if msg == 0, type = ACK*/static putpkt(fd,seq,msg) int fd; /* file descriptor */int seq; /* sequence number to be sent */char *msg; /* message to be sent */{int len,type,type_len,i;int csum,csum1,csum2,csum3;char tmp[80];if (Vflag) fprintf(dfp,"putpkt: fd=%d seq=%d msg=%s\n",fd,seq,msg); if (msg == 0) type = ACKPKT;else type = DATA;if (msg) len = strlen(msg);else len = 0;type_len = type | (len>>6);type_len |= 0x40;csum = type_len;len &= 0x3f;len |= 0x40;csum += len;seq |= 0x40;csum += seq;if (msg) for (i=0;msg[i] != 0;i++) csum += msg[i];csum1 = csum>>12;csum1 |= 0x40;csum2 = (csum>>6)&0x3f;csum2 |= 0x40;csum3 = csum&0x3f;csum3 |= 0x40;if (msg) sprintf(tmp,"%c%c%c%c%s%c%c%c",CNTRL('v'),type_len,len,seq,msg, csum1,csum2,csum3);else sprintf(tmp,"%c%c%c%c%c%c%c",CNTRL('v'),type_len,len,seq, csum1,csum2,csum3);write(fd,tmp,strlen(tmp));}/************************************************************** static getpkt(fd,seq,msg) * get a packet as a string, returns type*/static getpkt(fd,seq,msg) int fd; /* file descriptor */int *seq; /* received sequence number */char *msg; /* destination for message */{int len,type,csum,rsum,n,i;char ch;type = DATA;setjmp(pktstart);ch = readc(fd,msg);csum = ch;if (ch&ACKPKT) { type = ACKPKT; ch &= ~ACKPKT; }len = ch - '@';ch = readc(fd,msg);csum += ch;len = (len<<6) + (ch - '@');ch = readc(fd,msg);csum += ch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -