Annotation of 43BSDReno/pgrm/dbx/main.c, revision 1.1

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

unix.superglobalmegacorp.com

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