diff options
author | rsc <devnull@localhost> | 2004-04-19 19:30:50 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-04-19 19:30:50 +0000 |
commit | 84114f06650ba3db950532b1d0cd1d7e18b4b6be (patch) | |
tree | 4a5aa4819d01f1798bf86c3420db542c74092a6f /src/cmd/db/main.c | |
parent | a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 (diff) | |
download | plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.tar.gz plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.tar.bz2 plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.zip |
debugger
Diffstat (limited to 'src/cmd/db/main.c')
-rw-r--r-- | src/cmd/db/main.c | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/src/cmd/db/main.c b/src/cmd/db/main.c new file mode 100644 index 00000000..8e574037 --- /dev/null +++ b/src/cmd/db/main.c @@ -0,0 +1,262 @@ +/* + * db - main command loop and error/interrupt handling + */ +#include "defs.h" +#include "fns.h" + +int wtflag = OREAD; +BOOL kflag; + +BOOL mkfault; +ADDR maxoff; + +int xargc; /* bullshit */ + +extern BOOL executing; +extern int infile; +int exitflg; +extern int eof; + +int alldigs(char*); +void fault(void*, char*); + +extern char *Ipath; +jmp_buf env; +static char *errmsg; + +Fhdr *symhdr, *corhdr; + +void +usage(void) +{ + fprint(2, "usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n"); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int i, omode; + char *s; + char *name; + Fhdr *hdr; + + name = 0; + outputinit(); + maxoff = MAXOFF; + omode = OREAD; + ARGBEGIN{ + default: + usage(); + case 'A': + abort(); + case 'k': + kflag = 1; + break; + case 'w': + omode = ORDWR; + break; + case 'I': + s = ARGF(); + if(s == 0) + dprint("missing -I argument\n"); + else + Ipath = s; + break; + case 'm': + name = ARGF(); + if(name == 0) + dprint("missing -m argument\n"); + break; + }ARGEND + + /* + * Unix and Plan 9 differ on what the right order of pid, text, and core is. + * I never remember anyway. Let's just accept them in any order. + */ + for(i=0; i<argc; i++){ + if(alldigs(argv[i])){ + if(pid){ + dprint("already have pid %d; ignoring pid %d\n", pid, argv[i]); + continue; + } + if(corhdr){ + dprint("already have core %s; ignoring pid %d\n", corfil, pid); + continue; + } + pid = atoi(argv[i]); + continue; + } + if((hdr = crackhdr(argv[i], omode)) == nil){ + dprint("crackhdr %s: %r\n", argv[i]); + continue; + } + dprint("%s: %s %s %s\n", argv[i], hdr->aname, hdr->mname, hdr->fname); + if(hdr->ftype == FCORE){ + if(pid){ + dprint("already have pid %d; ignoring core %s\n", pid, argv[i]); + uncrackhdr(hdr); + continue; + } + if(corhdr){ + dprint("already have core %s; ignoring core %s\n", corfil, argv[i]); + uncrackhdr(hdr); + continue; + } + corhdr = hdr; + corfil = argv[i]; + }else{ + if(symhdr){ + dprint("already have text %s; ignoring text %s\n", symfil, argv[i]); + uncrackhdr(hdr); + continue; + } + symhdr = hdr; + symfil = argv[i]; + } + } + + if(symhdr==nil){ + symfil = "a.out"; + if(pid){ + if((s = proctextfile(pid)) != nil){ + dprint("pid %d: text %s\n", pid, s); + symfil = s; + } + } + /* XXX pull command from core */ + + if((symhdr = crackhdr(symfil, omode)) == nil){ + dprint("crackhdr %s: %r\n", symfil); + symfil = nil; + } + } + + if(!mach) + mach = machcpu; + + /* + * Set up maps. + */ + symmap = allocmap(); + cormap = allocmap(); + if(symmap == nil || cormap == nil) + sysfatal("allocating maps: %r"); + + if(symhdr){ + if(mapfile(symhdr, 0, symmap, nil) < 0) + dprint("mapping %s: %r\n", symfil); + mapfile(symhdr, 0, cormap, nil); + } + + dotmap = dumbmap(-1); + + /* + * show initial state and drop into the execution loop. + */ + notify(fault); + setsym(); + if(setjmp(env) == 0){ + if (pid || corhdr) + setcor(); /* could get error */ + if (correg) { + dprint("%s\n", mach->exc(cormap, correg)); + printpc(); + } + } + + setjmp(env); + if (executing) + delbp(); + executing = FALSE; + for (;;) { + flushbuf(); + if (errmsg) { + dprint(errmsg); + printc('\n'); + errmsg = 0; + exitflg = 0; + } + if (mkfault) { + mkfault=0; + printc('\n'); + prints(DBNAME); + } + clrinp(); + rdc(); + reread(); + if (eof) { + if (infile == STDIN) + done(); + iclose(-1, 0); + eof = 0; + longjmp(env, 1); + } + exitflg = 0; + command(0, 0); + reread(); + if (rdc() != '\n') + error("newline expected"); + } +} + +int +alldigs(char *s) +{ + while(*s){ + if(*s<'0' || '9'<*s) + return 0; + s++; + } + return 1; +} + +void +done(void) +{ + if (pid) + endpcs(); + exits(exitflg? "error": 0); +} + +/* + * An error occurred; save the message for later printing, + * close open files, and reset to main command loop. + */ +void +error(char *n) +{ + errmsg = n; + iclose(0, 1); + oclose(); + flush(); + delbp(); + ending = 0; + longjmp(env, 1); +} + +void +errors(char *m, char *n) +{ + static char buf[128]; + + sprint(buf, "%s: %s", m, n); + error(buf); +} + +/* + * An interrupt occurred; + * seek to the end of the current file + * and remember that there was a fault. + */ +void +fault(void *a, char *s) +{ + USED(a); + if(strncmp(s, "interrupt", 9) == 0){ + seek(infile, 0L, 2); + mkfault++; + noted(NCONT); + } + noted(NDFLT); +} |