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

unix.superglobalmegacorp.com

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