Annotation of 43BSD/ucb/dbx/main.c, revision 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.