|
|
1.1 ! root 1: /* Copyright (c) 1982 Regents of the University of California */ ! 2: ! 3: static char sccsid[] = "@(#)main.c 1.6 8/16/83"; ! 4: ! 5: /* ! 6: * Debugger main routine. ! 7: */ ! 8: ! 9: #include "defs.h" ! 10: #include <setjmp.h> ! 11: #include <signal.h> ! 12: #include <errno.h> ! 13: #include "main.h" ! 14: #include "symbols.h" ! 15: #include "scanner.h" ! 16: #include "process.h" ! 17: #include "source.h" ! 18: #include "object.h" ! 19: #include "mappings.h" ! 20: ! 21: #ifndef public ! 22: ! 23: #define isterm(file) (interactive or isatty(fileno(file))) ! 24: ! 25: #include <sgtty.h> ! 26: ! 27: typedef struct sgttyb Ttyinfo; ! 28: ! 29: #endif ! 30: ! 31: public Boolean coredump; /* true if using a core dump */ ! 32: public Boolean runfirst; /* run program immediately */ ! 33: public Boolean interactive; /* standard input IS a terminal */ ! 34: public Boolean lexdebug; /* trace yylex return values */ ! 35: public Boolean tracebpts; /* trace create/delete breakpoints */ ! 36: public Boolean traceexec; /* trace process execution */ ! 37: public Boolean tracesyms; /* print symbols as their read */ ! 38: ! 39: public File corefile; /* File id of core dump */ ! 40: ! 41: #define FIRST_TIME 0 /* initial value setjmp returns */ ! 42: ! 43: private Boolean initdone = false; /* true if initialization done */ ! 44: private jmp_buf env; /* setjmp/longjmp data */ ! 45: private char outbuf[BUFSIZ]; /* standard output buffer */ ! 46: private char namebuf[512]; /* possible name of object file */ ! 47: private int firstarg; /* first program argument (for -r) */ ! 48: ! 49: private Ttyinfo ttyinfo; ! 50: ! 51: private catchintr(); ! 52: ! 53: /* ! 54: * Main program. ! 55: */ ! 56: ! 57: main(argc, argv) ! 58: int argc; ! 59: String argv[]; ! 60: { ! 61: register Integer i; ! 62: extern String date; ! 63: ! 64: cmdname = argv[0]; ! 65: catcherrs(); ! 66: onsyserr(EINTR, nil); ! 67: setbuf(stdout, outbuf); ! 68: printf("dbx version of %s.\nType 'help' for help.\n", date); ! 69: fflush(stdout); ! 70: scanargs(argc, argv); ! 71: language_init(); ! 72: symbols_init(); ! 73: process_init(); ! 74: if (runfirst) { ! 75: if (setjmp(env) == FIRST_TIME) { ! 76: arginit(); ! 77: for (i = firstarg; i < argc; i++) { ! 78: newarg(argv[i]); ! 79: } ! 80: run(); ! 81: /* NOTREACHED */ ! 82: } else { ! 83: runfirst = false; ! 84: } ! 85: } else { ! 86: init(); ! 87: } ! 88: setjmp(env); ! 89: restoretty(stdout, &ttyinfo); ! 90: signal(SIGINT, catchintr); ! 91: yyparse(); ! 92: putchar('\n'); ! 93: quit(0); ! 94: } ! 95: ! 96: /* ! 97: * Initialize the world, including setting initial input file ! 98: * if the file exists. ! 99: */ ! 100: ! 101: public init() ! 102: { ! 103: File f; ! 104: String home; ! 105: char buf[100]; ! 106: extern String getenv(); ! 107: ! 108: savetty(stdout, &ttyinfo); ! 109: enterkeywords(); ! 110: scanner_init(); ! 111: if (not coredump and not runfirst) { ! 112: start(nil, nil, nil); ! 113: } ! 114: printf("reading symbolic information ..."); ! 115: fflush(stdout); ! 116: readobj(objname); ! 117: printf("\n"); ! 118: fflush(stdout); ! 119: if (coredump) { ! 120: curfunc = whatblock(pc); ! 121: } else { ! 122: curfunc = program; ! 123: } ! 124: bpinit(); ! 125: f = fopen(initfile, "r"); ! 126: if (f != nil) { ! 127: fclose(f); ! 128: setinput(initfile); ! 129: } else { ! 130: home = getenv("HOME"); ! 131: if (home != nil) { ! 132: sprintf(buf, "%s/%s", home, initfile); ! 133: f = fopen(buf, "r"); ! 134: if (f != nil) { ! 135: fclose(f); ! 136: setinput(strdup(buf)); ! 137: } ! 138: } ! 139: } ! 140: initdone = true; ! 141: } ! 142: ! 143: /* ! 144: * Re-initialize the world, first de-allocating all storage. ! 145: * This is necessary when the symbol information must be re-read ! 146: * from the object file when it has changed. ! 147: * ! 148: * Before "forgetting" things, we save the current tracing/breakpoint ! 149: * information to a temp file. Then after re-creating the world, ! 150: * we read the temp file as commands. This isn't always the right thing; ! 151: * if a procedure that was being traced is deleted, an error message ! 152: * will be generated. ! 153: * ! 154: * If the argument vector is not nil, then this is re-initialize is being ! 155: * done in preparation for running the program. Since we want to process ! 156: * the commands in the temp file before running the program, we add the ! 157: * run command at the end of the temp file. In this case, reinit longjmps ! 158: * back to parsing rather than returning. ! 159: */ ! 160: ! 161: public reinit(argv, infile, outfile) ! 162: String *argv; ! 163: String infile; ! 164: String outfile; ! 165: { ! 166: register Integer i; ! 167: String tmpfile; ! 168: extern String mktemp(); ! 169: ! 170: tmpfile = mktemp("/tmp/dbxXXXX"); ! 171: setout(tmpfile); ! 172: status(); ! 173: print_alias(nil); ! 174: if (argv != nil) { ! 175: printf("run"); ! 176: for (i = 1; argv[i] != nil; i++) { ! 177: printf(" %s", argv[i]); ! 178: } ! 179: if (infile != nil) { ! 180: printf(" < %s", infile); ! 181: } ! 182: if (outfile != nil) { ! 183: printf(" > %s", outfile); ! 184: } ! 185: putchar('\n'); ! 186: } ! 187: unsetout(); ! 188: bpfree(); ! 189: objfree(); ! 190: process_init(); ! 191: enterkeywords(); ! 192: scanner_init(); ! 193: readobj(objname); ! 194: bpinit(); ! 195: fflush(stdout); ! 196: setinput(tmpfile); ! 197: unlink(tmpfile); ! 198: if (argv != nil) { ! 199: longjmp(env, 1); ! 200: /* NOTREACHED */ ! 201: } ! 202: } ! 203: ! 204: /* ! 205: * After a non-fatal error we jump back to command parsing. ! 206: */ ! 207: ! 208: public erecover() ! 209: { ! 210: if (initdone) { ! 211: gobble(); ! 212: longjmp(env, 1); ! 213: } ! 214: } ! 215: ! 216: /* ! 217: * This routine is called when an interrupt occurs. ! 218: */ ! 219: ! 220: private catchintr() ! 221: { ! 222: putchar('\n'); ! 223: longjmp(env, 1); ! 224: } ! 225: ! 226: /* ! 227: * Scan the argument list. ! 228: */ ! 229: ! 230: private scanargs(argc, argv) ! 231: int argc; ! 232: String argv[]; ! 233: { ! 234: register int i, j; ! 235: register Boolean foundfile; ! 236: register File f; ! 237: char *tmp; ! 238: ! 239: runfirst = false; ! 240: interactive = false; ! 241: lexdebug = false; ! 242: tracebpts = false; ! 243: traceexec = false; ! 244: tracesyms = false; ! 245: foundfile = false; ! 246: corefile = nil; ! 247: coredump = true; ! 248: sourcepath = list_alloc(); ! 249: list_append(list_item("."), nil, sourcepath); ! 250: i = 1; ! 251: while (i < argc and (not foundfile or (corefile == nil and not runfirst))) { ! 252: if (argv[i][0] == '-') { ! 253: if (streq(argv[i], "-I")) { ! 254: ++i; ! 255: if (i >= argc) { ! 256: fatal("missing directory for -I"); ! 257: } ! 258: list_append(list_item(argv[i]), nil, sourcepath); ! 259: } else { ! 260: for (j = 1; argv[i][j] != '\0'; j++) { ! 261: setoption(argv[i][j]); ! 262: } ! 263: } ! 264: } else if (not foundfile) { ! 265: objname = argv[i]; ! 266: foundfile = true; ! 267: } else if (coredump and corefile == nil) { ! 268: corefile = fopen(argv[i], "r"); ! 269: if (corefile == nil) { ! 270: coredump = false; ! 271: } ! 272: } ! 273: ++i; ! 274: } ! 275: if (i < argc and not runfirst) { ! 276: fatal("extraneous argument %s", argv[i]); ! 277: } ! 278: firstarg = i; ! 279: if (not foundfile and isatty(0)) { ! 280: printf("enter object file name (default is `%s'): ", objname); ! 281: fflush(stdout); ! 282: gets(namebuf); ! 283: if (namebuf[0] != '\0') { ! 284: objname = namebuf; ! 285: } ! 286: } ! 287: f = fopen(objname, "r"); ! 288: if (f == nil) { ! 289: fatal("can't read %s", objname); ! 290: } else { ! 291: fclose(f); ! 292: } ! 293: if (rindex(objname, '/') != nil) { ! 294: tmp = strdup(objname); ! 295: *(rindex(tmp, '/')) = '\0'; ! 296: list_append(list_item(tmp), nil, sourcepath); ! 297: } ! 298: if (coredump and corefile == nil) { ! 299: corefile = fopen("core", "r"); ! 300: if (corefile == nil) { ! 301: coredump = false; ! 302: } ! 303: } ! 304: } ! 305: ! 306: /* ! 307: * Take appropriate action for recognized command argument. ! 308: */ ! 309: ! 310: private setoption(c) ! 311: char c; ! 312: { ! 313: switch (c) { ! 314: case 'r': /* run program before accepting commands */ ! 315: runfirst = true; ! 316: coredump = false; ! 317: break; ! 318: ! 319: case 'i': ! 320: interactive = true; ! 321: break; ! 322: ! 323: case 'b': ! 324: tracebpts = true; ! 325: break; ! 326: ! 327: case 'e': ! 328: traceexec = true; ! 329: break; ! 330: ! 331: case 's': ! 332: tracesyms = true; ! 333: break; ! 334: ! 335: case 'l': ! 336: # ifdef LEXDEBUG ! 337: lexdebug = true; ! 338: # else ! 339: fatal("\"-l\" only applicable when compiled with LEXDEBUG"); ! 340: # endif ! 341: break; ! 342: ! 343: default: ! 344: fatal("unknown option '%c'", c); ! 345: } ! 346: } ! 347: ! 348: /* ! 349: * Save/restore the state of a tty. ! 350: */ ! 351: ! 352: public savetty(f, t) ! 353: File f; ! 354: Ttyinfo *t; ! 355: { ! 356: gtty(fileno(f), t); ! 357: } ! 358: ! 359: public restoretty(f, t) ! 360: File f; ! 361: Ttyinfo *t; ! 362: { ! 363: stty(fileno(f), t); ! 364: } ! 365: ! 366: /* ! 367: * Exit gracefully. ! 368: */ ! 369: ! 370: public quit(r) ! 371: Integer r; ! 372: { ! 373: exit(r); ! 374: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.