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

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)main.c     5.1 (Berkeley) 5/31/85";
                     15: #endif not lint
                     16: 
                     17: static char rcsid[] = "$Header: main.c,v 1.5 84/12/26 10:40:16 linton Exp $";
                     18: 
                     19: /*
                     20:  * Debugger main routine.
                     21:  */
                     22: 
                     23: #include "defs.h"
                     24: #include <setjmp.h>
                     25: #include <signal.h>
                     26: #include <errno.h>
                     27: #include "main.h"
                     28: #include "eval.h"
                     29: #include "debug.h"
                     30: #include "symbols.h"
                     31: #include "scanner.h"
                     32: #include "keywords.h"
                     33: #include "process.h"
                     34: #include "runtime.h"
                     35: #include "source.h"
                     36: #include "object.h"
                     37: #include "mappings.h"
                     38: #include "coredump.h"
                     39: 
                     40: #ifndef public
                     41: 
                     42: #define isterm(file)   (interactive or isatty(fileno(file)))
                     43: 
                     44: #include <sgtty.h>
                     45: #include <fcntl.h>
                     46: 
                     47: typedef struct {
                     48:     struct sgttyb sg;          /* standard sgttyb structure */
                     49:     struct tchars tc;          /* terminal characters */
                     50:     struct ltchars ltc;                /* local special characters */
                     51:     integer ldisc;             /* line discipline */
                     52:     integer local;             /* TIOCLGET */
                     53:     integer fcflags;           /* fcntl(2) F_GETFL, F_SETFL */
                     54: } Ttyinfo;
                     55: 
                     56: #endif
                     57: 
                     58: public boolean coredump;               /* true if using a core dump */
                     59: public boolean runfirst;               /* run program immediately */
                     60: public boolean interactive;            /* standard input IS a terminal */
                     61: public boolean lexdebug;               /* trace scanner return values */
                     62: public boolean tracebpts;              /* trace create/delete breakpoints */
                     63: public boolean traceexec;              /* trace execution */
                     64: public boolean tracesyms;              /* print symbols are they are read */
                     65: public boolean traceblocks;            /* trace blocks while reading symbols */
                     66: public boolean vaddrs;                 /* map addresses through page tables */
                     67: 
                     68: public File corefile;                  /* File id of core dump */
                     69: 
                     70: #define FIRST_TIME 0                   /* initial value setjmp returns */
                     71: 
                     72: private Boolean initdone = false;      /* true if initialization done */
                     73: private jmp_buf env;                   /* setjmp/longjmp data */
                     74: private char outbuf[BUFSIZ];           /* standard output buffer */
                     75: private char namebuf[512];             /* possible name of object file */
                     76: private int firstarg;                  /* first program argument (for -r) */
                     77: 
                     78: private Ttyinfo ttyinfo;
                     79: private String corename;               /* name of core file */
                     80: 
                     81: private catchintr();
                     82: 
                     83: /*
                     84:  * Main program.
                     85:  */
                     86: 
                     87: main(argc, argv)
                     88: int argc;
                     89: String argv[];
                     90: {
                     91:     register integer i;
                     92:     extern String date;
                     93:     extern integer versionNumber;
                     94: 
                     95:     cmdname = argv[0];
                     96:     catcherrs();
                     97:     onsyserr(EINTR, nil);
                     98:     setbuf(stdout, outbuf);
                     99:     printf("dbx version 3.%d of %s.\nType 'help' for help.\n",
                    100:        versionNumber, date);
                    101:     fflush(stdout);
                    102:     scanargs(argc, argv);
                    103:     language_init();
                    104:     symbols_init();
                    105:     process_init();
                    106:     if (runfirst) {
                    107:        if (setjmp(env) == FIRST_TIME) {
                    108:            arginit();
                    109:            for (i = firstarg; i < argc; i++) {
                    110:                newarg(argv[i]);
                    111:            }
                    112:            run();
                    113:            /* NOTREACHED */
                    114:        } else {
                    115:            runfirst = false;
                    116:        }
                    117:     } else {
                    118:        init();
                    119:     }
                    120:     if (setjmp(env) != FIRST_TIME) {
                    121:        restoretty(stdout, &ttyinfo);
                    122:     }
                    123:     signal(SIGINT, catchintr);
                    124:     yyparse();
                    125:     putchar('\n');
                    126:     quit(0);
                    127: }
                    128: 
                    129: /*
                    130:  * Initialize the world, including setting initial input file
                    131:  * if the file exists.
                    132:  */
                    133: 
                    134: public init()
                    135: {
                    136:     File f;
                    137:     String home;
                    138:     char buf[100];
                    139:     extern String getenv();
                    140: 
                    141:     savetty(stdout, &ttyinfo);
                    142:     enterkeywords();
                    143:     scanner_init();
                    144:     if (not coredump and not runfirst) {
                    145:        start(nil, nil, nil);
                    146:     }
                    147:     printf("reading symbolic information ...");
                    148:     fflush(stdout);
                    149:     readobj(objname);
                    150:     printf("\n");
                    151:     fflush(stdout);
                    152:     if (coredump) {
                    153:        printf("[using memory image in %s]\n", corename);
                    154:        if (vaddrs) {
                    155:            coredump_getkerinfo();
                    156:        }
                    157:        setcurfunc(whatblock(pc));
                    158:     } else {
                    159:        setcurfunc(program);
                    160:     }
                    161:     bpinit();
                    162:     f = fopen(initfile, "r");
                    163:     if (f != nil) {
                    164:        fclose(f);
                    165:        setinput(initfile);
                    166:     } else {
                    167:        home = getenv("HOME");
                    168:        if (home != nil) {
                    169:            sprintf(buf, "%s/%s", home, initfile);
                    170:            f = fopen(buf, "r");
                    171:            if (f != nil) {
                    172:                fclose(f);
                    173:                setinput(strdup(buf));
                    174:            }
                    175:        }
                    176:     }
                    177:     initdone = true;
                    178: }
                    179: 
                    180: /*
                    181:  * Re-initialize the world, first de-allocating all storage.
                    182:  * This is necessary when the symbol information must be re-read
                    183:  * from the object file when it has changed.
                    184:  *
                    185:  * Before "forgetting" things, we save the current tracing/breakpoint
                    186:  * information to a temp file.  Then after re-creating the world,
                    187:  * we read the temp file as commands.  This isn't always the right thing;
                    188:  * if a procedure that was being traced is deleted, an error message
                    189:  * will be generated.
                    190:  *
                    191:  * If the argument vector is not nil, then this is re-initialize is being
                    192:  * done in preparation for running the program.  Since we want to process
                    193:  * the commands in the temp file before running the program, we add the
                    194:  * run command at the end of the temp file.  In this case, reinit longjmps
                    195:  * back to parsing rather than returning.
                    196:  */
                    197: 
                    198: public reinit(argv, infile, outfile)
                    199: String *argv;
                    200: String infile;
                    201: String outfile;
                    202: {
                    203:     register Integer i;
                    204:     String tmpfile;
                    205:     extern String mktemp();
                    206: 
                    207:     tmpfile = mktemp("/tmp/dbxXXXX");
                    208:     setout(tmpfile);
                    209:     status();
                    210:     alias(nil, nil, nil);
                    211:     if (argv != nil) {
                    212:        printf("run");
                    213:        for (i = 1; argv[i] != nil; i++) {
                    214:            printf(" %s", argv[i]);
                    215:        }
                    216:        if (infile != nil) {
                    217:            printf(" < %s", infile);
                    218:        }
                    219:        if (outfile != nil) {
                    220:            printf(" > %s", outfile);
                    221:        }
                    222:        putchar('\n');
                    223:     }
                    224:     unsetout();
                    225:     bpfree();
                    226:     objfree();
                    227:     symbols_init();
                    228:     process_init();
                    229:     enterkeywords();
                    230:     scanner_init();
                    231:     readobj(objname);
                    232:     bpinit();
                    233:     fflush(stdout);
                    234:     setinput(tmpfile);
                    235:     unlink(tmpfile);
                    236:     if (argv != nil) {
                    237:        longjmp(env, 1);
                    238:        /* NOTREACHED */
                    239:     }
                    240: }
                    241: 
                    242: /*
                    243:  * After a non-fatal error we skip the rest of the current input line, and
                    244:  * jump back to command parsing.
                    245:  */
                    246: 
                    247: public erecover()
                    248: {
                    249:     if (initdone) {
                    250:        gobble();
                    251:        longjmp(env, 1);
                    252:     }
                    253: }
                    254: 
                    255: /*
                    256:  * This routine is called when an interrupt occurs.
                    257:  */
                    258: 
                    259: private catchintr()
                    260: {
                    261:     if (isredirected()) {
                    262:        fflush(stdout);
                    263:        unsetout();
                    264:     }
                    265:     putchar('\n');
                    266:     longjmp(env, 1);
                    267: }
                    268: 
                    269: /*
                    270:  * Scan the argument list.
                    271:  */
                    272: 
                    273: private scanargs(argc, argv)
                    274: int argc;
                    275: String argv[];
                    276: {
                    277:     register int i, j;
                    278:     register Boolean foundfile;
                    279:     register File f;
                    280:     char *tmp;
                    281: 
                    282:     runfirst = false;
                    283:     interactive = false;
                    284:     lexdebug = false;
                    285:     tracebpts = false;
                    286:     traceexec = false;
                    287:     tracesyms = false;
                    288:     traceblocks = false;
                    289:     vaddrs = false;
                    290:     foundfile = false;
                    291:     corefile = nil;
                    292:     coredump = true;
                    293:     sourcepath = list_alloc();
                    294:     list_append(list_item("."), nil, sourcepath);
                    295:     i = 1;
                    296:     while (i < argc and (not foundfile or (coredump and corefile == nil))) {
                    297:        if (argv[i][0] == '-') {
                    298:            if (streq(argv[i], "-I")) {
                    299:                ++i;
                    300:                if (i >= argc) {
                    301:                    fatal("missing directory for -I");
                    302:                }
                    303:                list_append(list_item(argv[i]), nil, sourcepath);
                    304:            } else if (streq(argv[i], "-c")) {
                    305:                ++i;
                    306:                if (i >= argc) {
                    307:                    fatal("missing command file name for -c");
                    308:                }
                    309:                initfile = argv[i];
                    310:            } else {
                    311:                for (j = 1; argv[i][j] != '\0'; j++) {
                    312:                    setoption(argv[i][j]);
                    313:                }
                    314:            }
                    315:        } else if (not foundfile) {
                    316:            objname = argv[i];
                    317:            foundfile = true;
                    318:        } else if (coredump and corefile == nil) {
                    319:            corefile = fopen(argv[i], "r");
                    320:            corename = argv[i];
                    321:            if (corefile == nil) {
                    322:                coredump = false;
                    323:            }
                    324:        }
                    325:        ++i;
                    326:     }
                    327:     if (i < argc and not runfirst) {
                    328:        fatal("extraneous argument %s", argv[i]);
                    329:     }
                    330:     firstarg = i;
                    331:     if (not foundfile and isatty(0)) {
                    332:        printf("enter object file name (default is `%s'): ", objname);
                    333:        fflush(stdout);
                    334:        gets(namebuf);
                    335:        if (namebuf[0] != '\0') {
                    336:            objname = namebuf;
                    337:        }
                    338:     }
                    339:     f = fopen(objname, "r");
                    340:     if (f == nil) {
                    341:        fatal("can't read %s", objname);
                    342:     } else {
                    343:        fclose(f);
                    344:     }
                    345:     if (rindex(objname, '/') != nil) {
                    346:        tmp = strdup(objname);
                    347:        *(rindex(tmp, '/')) = '\0';
                    348:        list_append(list_item(tmp), nil, sourcepath);
                    349:     }
                    350:     if (coredump and corefile == nil) {
                    351:        if (vaddrs) {
                    352:            corefile = fopen("/dev/mem", "r");
                    353:            corename = "/dev/mem";
                    354:            if (corefile == nil) {
                    355:                panic("can't open /dev/mem");
                    356:            }
                    357:        } else {
                    358:            corefile = fopen("core", "r");
                    359:            corename = "core";
                    360:            if (corefile == nil) {
                    361:                coredump = false;
                    362:            }
                    363:        }
                    364:     }
                    365: }
                    366: 
                    367: /*
                    368:  * Take appropriate action for recognized command argument.
                    369:  */
                    370: 
                    371: private setoption(c)
                    372: char c;
                    373: {
                    374:     switch (c) {
                    375:        case 'r':   /* run program before accepting commands */
                    376:            runfirst = true;
                    377:            coredump = false;
                    378:            break;
                    379: 
                    380:        case 'i':
                    381:            interactive = true;
                    382:            break;
                    383: 
                    384:        case 'b':
                    385:            tracebpts = true;
                    386:            break;
                    387: 
                    388:        case 'e':
                    389:            traceexec = true;
                    390:            break;
                    391: 
                    392:        case 's':
                    393:            tracesyms = true;
                    394:            break;
                    395: 
                    396:        case 'n':
                    397:            traceblocks = true;
                    398:            break;
                    399: 
                    400:        case 'k':
                    401:            vaddrs = true;
                    402:            break;
                    403: 
                    404:        case 'l':
                    405: #          ifdef LEXDEBUG
                    406:                lexdebug = true;
                    407: #          else
                    408:                fatal("\"-l\" only applicable when compiled with LEXDEBUG");
                    409: #          endif
                    410:            break;
                    411: 
                    412:        default:
                    413:            fatal("unknown option '%c'", c);
                    414:     }
                    415: }
                    416: 
                    417: /*
                    418:  * Save/restore the state of a tty.
                    419:  */
                    420: 
                    421: public savetty(f, t)
                    422: File f;
                    423: Ttyinfo *t;
                    424: {
                    425:     ioctl(fileno(f), TIOCGETP, &(t->sg));
                    426:     ioctl(fileno(f), TIOCGETC, &(t->tc));
                    427:     ioctl(fileno(f), TIOCGLTC, &(t->ltc));
                    428:     ioctl(fileno(f), TIOCGETD, &(t->ldisc));
                    429:     ioctl(fileno(f), TIOCLGET, &(t->local));
                    430:     t->fcflags = fcntl(fileno(f), F_GETFL, 0);
                    431: }
                    432: 
                    433: public restoretty(f, t)
                    434: File f;
                    435: Ttyinfo *t;
                    436: {
                    437:     ioctl(fileno(f), TIOCSETN, &(t->sg));
                    438:     ioctl(fileno(f), TIOCSETC, &(t->tc));
                    439:     ioctl(fileno(f), TIOCSLTC, &(t->ltc));
                    440:     ioctl(fileno(f), TIOCSETD, &(t->ldisc));
                    441:     ioctl(fileno(f), TIOCLSET, &(t->local));
                    442:     (void) fcntl(fileno(f), F_SETFL, t->fcflags);
                    443: }
                    444: 
                    445: /*
                    446:  * Exit gracefully.
                    447:  */
                    448: 
                    449: public quit(r)
                    450: Integer r;
                    451: {
                    452:     pterm(process);
                    453:     exit(r);
                    454: }

unix.superglobalmegacorp.com

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