Annotation of 42BSD/ucb/dbx/main.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.