1 /* 2 * db - main command loop and error/interrupt handling 3 */ 4 #include "defs.h" 5 #include "fns.h" 6 7 int wtflag = OREAD; 8 BOOL kflag; 9 10 BOOL mkfault; 11 ADDR maxoff; 12 13 int xargc; /* bullshit */ 14 15 extern BOOL executing; 16 extern int infile; 17 int exitflg; 18 extern int eof; 19 20 int alldigs(char*); 21 void fault(void*, char*); 22 23 extern char *Ipath; 24 jmp_buf env; 25 static char *errmsg; 26 27 void 28 main(int argc, char **argv) 29 { 30 char b1[100]; 31 char b2[100]; 32 char *s; 33 char *name; 34 35 name = 0; 36 outputinit(); 37 maxoff = MAXOFF; 38 ARGBEGIN{ 39 case 'k': 40 kflag = 1; 41 break; 42 case 'w': 43 wtflag = ORDWR; /* suitable for open() */ 44 break; 45 case 'I': 46 s = ARGF(); 47 if(s == 0) 48 dprint("missing -I argument\n"); 49 else 50 Ipath = s; 51 break; 52 case 'm': 53 name = ARGF(); 54 if(name == 0) 55 dprint("missing -m argument\n"); 56 break; 57 }ARGEND 58 symfil = 0; 59 corfil = 0; 60 if (argc > 0 && !alldigs(argv[0])) { 61 symfil = argv[0]; 62 argv++; 63 argc--; 64 } 65 if(argc==1 && alldigs(argv[0])){ 66 char *cpu, *p, *q; 67 68 pid = atoi(argv[0]); 69 pcsactive = 0; 70 if (!symfil) { 71 if(kflag){ 72 cpu = getenv("cputype"); 73 if(cpu == 0){ 74 cpu = "386"; 75 dprint("$cputype not set; assuming %s\n", cpu); 76 } 77 p = getenv("terminal"); 78 if(p==0 || (p=strchr(p, ' '))==0 || p[1]==' ' || p[1]==0){ 79 strcpy(b1, "/386/9pc"); 80 dprint("missing or bad $terminal; assuming %s\n", b1); 81 }else{ 82 p++; 83 q = strchr(p, ' '); 84 if(q) 85 *q = 0; 86 sprint(b1, "/%s/9%s", cpu, p); 87 88 } 89 }else 90 sprint(b1, "/proc/%s/text", argv[0]); 91 symfil = b1; 92 } 93 sprint(b2, "/proc/%s/mem", argv[0]); 94 corfil = b2; 95 } else if (argc > 0) { 96 fprint(2, "Usage: db [-kw] [-m machine] [-I dir] [symfile] [pid]\n"); 97 exits("usage"); 98 } 99 if (!symfil) 100 symfil = "8.out"; 101 xargc = argc; 102 notify(fault); 103 setsym(); 104 dotmap = dumbmap(-1); 105 if (name && machbyname(name) == 0) 106 dprint ("unknown machine %s", name); 107 dprint("%s binary\n", mach->name); 108 if(setjmp(env) == 0){ 109 if (corfil) { 110 setcor(); /* could get error */ 111 dprint("%s\n", machdata->excep(cormap, rget)); 112 printpc(); 113 } 114 } 115 116 setjmp(env); 117 if (executing) 118 delbp(); 119 executing = FALSE; 120 for (;;) { 121 flushbuf(); 122 if (errmsg) { 123 dprint(errmsg); 124 printc('\n'); 125 errmsg = 0; 126 exitflg = 0; 127 } 128 if (mkfault) { 129 mkfault=0; 130 printc('\n'); 131 prints(DBNAME); 132 } 133 clrinp(); 134 rdc(); 135 reread(); 136 if (eof) { 137 if (infile == STDIN) 138 done(); 139 iclose(-1, 0); 140 eof = 0; 141 longjmp(env, 1); 142 } 143 exitflg = 0; 144 command(0, 0); 145 reread(); 146 if (rdc() != '\n') 147 error("newline expected"); 148 } 149 } 150 151 int 152 alldigs(char *s) 153 { 154 while(*s){ 155 if(*s<'0' || '9'<*s) 156 return 0; 157 s++; 158 } 159 return 1; 160 } 161 162 void 163 done(void) 164 { 165 if (pid) 166 endpcs(); 167 exits(exitflg? "error": 0); 168 } 169 170 /* 171 * An error occurred; save the message for later printing, 172 * close open files, and reset to main command loop. 173 */ 174 void 175 error(char *n) 176 { 177 errmsg = n; 178 iclose(0, 1); 179 oclose(); 180 flush(); 181 delbp(); 182 ending = 0; 183 longjmp(env, 1); 184 } 185 186 void 187 errors(char *m, char *n) 188 { 189 static char buf[128]; 190 191 sprint(buf, "%s: %s", m, n); 192 error(buf); 193 } 194 195 /* 196 * An interrupt occurred; 197 * seek to the end of the current file 198 * and remember that there was a fault. 199 */ 200 void 201 fault(void *a, char *s) 202 { 203 USED(a); 204 if(strncmp(s, "interrupt", 9) == 0){ 205 seek(infile, 0L, 2); 206 mkfault++; 207 noted(NCONT); 208 } 209 noted(NDFLT); 210 } 211