Blob
1 /*2 * db - main command loop and error/interrupt handling3 */4 #include "defs.h"5 #include "fns.h"7 int wtflag = OREAD;8 BOOL kflag;10 BOOL mkfault;11 ADDR maxoff;13 int xargc; /* bullshit */15 extern BOOL executing;16 extern int infile;17 int exitflg;18 extern int eof;20 int alldigs(char*);21 void fault(void*, char*);23 extern char *Ipath;24 jmp_buf env;25 static char *errmsg;27 Fhdr *symhdr, *corhdr;29 void30 usage(void)31 {32 fprint(2, "usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n");33 exits("usage");34 }36 void37 main(int argc, char **argv)38 {39 int i, omode;40 char *s;41 char *name;42 Fhdr *hdr;44 name = 0;45 outputinit();46 maxoff = MAXOFF;47 omode = OREAD;48 ARGBEGIN{49 default:50 usage();51 case 'A':52 abort();53 case 'k':54 kflag = 1;55 break;56 case 'w':57 omode = ORDWR;58 break;59 case 'I':60 s = ARGF();61 if(s == 0)62 dprint("missing -I argument\n");63 else64 Ipath = s;65 break;66 case 'm':67 name = ARGF();68 if(name == 0)69 dprint("missing -m argument\n");70 break;71 }ARGEND73 /*74 * Unix and Plan 9 differ on what the right order of pid, text, and core is.75 * I never remember anyway. Let's just accept them in any order.76 */77 for(i=0; i<argc; i++){78 if(alldigs(argv[i])){79 if(pid){80 dprint("already have pid %d; ignoring pid %d\n", pid, argv[i]);81 continue;82 }83 if(corhdr){84 dprint("already have core %s; ignoring pid %d\n", corfil, pid);85 continue;86 }87 pid = atoi(argv[i]);88 continue;89 }90 if((hdr = crackhdr(argv[i], omode)) == nil){91 dprint("crackhdr %s: %r\n", argv[i]);92 continue;93 }94 dprint("%s: %s %s %s\n", argv[i], hdr->aname, hdr->mname, hdr->fname);95 if(hdr->ftype == FCORE){96 if(pid){97 dprint("already have pid %d; ignoring core %s\n", pid, argv[i]);98 uncrackhdr(hdr);99 continue;100 }101 if(corhdr){102 dprint("already have core %s; ignoring core %s\n", corfil, argv[i]);103 uncrackhdr(hdr);104 continue;105 }106 corhdr = hdr;107 corfil = argv[i];108 }else{109 if(symhdr){110 dprint("already have text %s; ignoring text %s\n", symfil, argv[i]);111 uncrackhdr(hdr);112 continue;113 }114 symhdr = hdr;115 symfil = argv[i];116 }117 }119 if(symhdr==nil){120 symfil = "a.out";121 if(pid){122 if((s = proctextfile(pid)) != nil){123 dprint("pid %d: text %s\n", pid, s);124 symfil = s;125 }126 }127 /* XXX pull command from core */129 if((symhdr = crackhdr(symfil, omode)) == nil){130 dprint("crackhdr %s: %r\n", symfil);131 symfil = nil;132 }133 }135 if(!mach)136 mach = machcpu;138 /*139 * Set up maps.140 */141 symmap = allocmap();142 cormap = allocmap();143 if(symmap == nil || cormap == nil)144 sysfatal("allocating maps: %r");146 if(symhdr){147 if(mapfile(symhdr, 0, symmap, nil) < 0)148 dprint("mapping %s: %r\n", symfil);149 mapfile(symhdr, 0, cormap, nil);150 }152 dotmap = dumbmap(-1);154 /*155 * show initial state and drop into the execution loop.156 */157 notify(fault);158 setsym();159 if(setjmp(env) == 0){160 if (pid || corhdr)161 setcor(); /* could get error */162 if (correg) {163 dprint("%s\n", mach->exc(cormap, correg));164 printpc();165 }166 }168 setjmp(env);169 if (executing)170 delbp();171 executing = FALSE;172 for (;;) {173 flushbuf();174 if (errmsg) {175 dprint(errmsg);176 printc('\n');177 errmsg = 0;178 exitflg = 0;179 }180 if (mkfault) {181 mkfault=0;182 printc('\n');183 prints(DBNAME);184 }185 clrinp();186 rdc();187 reread();188 if (eof) {189 if (infile == STDIN)190 done();191 iclose(-1, 0);192 eof = 0;193 longjmp(env, 1);194 }195 exitflg = 0;196 command(0, 0);197 reread();198 if (rdc() != '\n')199 error("newline expected");200 }201 }203 int204 alldigs(char *s)205 {206 while(*s){207 if(*s<'0' || '9'<*s)208 return 0;209 s++;210 }211 return 1;212 }214 void215 done(void)216 {217 if (pid)218 endpcs();219 exits(exitflg? "error": 0);220 }222 /*223 * An error occurred; save the message for later printing,224 * close open files, and reset to main command loop.225 */226 void227 error(char *n)228 {229 errmsg = n;230 iclose(0, 1);231 oclose();232 flush();233 delbp();234 ending = 0;235 longjmp(env, 1);236 }238 void239 errors(char *m, char *n)240 {241 static char buf[128];243 sprint(buf, "%s: %s", m, n);244 error(buf);245 }247 /*248 * An interrupt occurred;249 * seek to the end of the current file250 * and remember that there was a fault.251 */252 void253 fault(void *a, char *s)254 {255 USED(a);256 if(strncmp(s, "interrupt", 9) == 0){257 seek(infile, 0L, 2);258 mkfault++;259 noted(NCONT);260 }261 noted(NDFLT);262 }