Annotation of 43BSDReno/bin/adb/common_source/pcs.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)pcs.c      5.5 (Berkeley) 4/9/89";
                      3: #endif
                      4: 
                      5: /*
                      6:  * adb - subprocess control
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: #include "bkpt.h"
                     11: #include <machine/reg.h>       /* for getpc() *//* XXX */
                     12: #include <sys/file.h>
                     13: #include <sys/ptrace.h>
                     14: #include <sys/wait.h>
                     15: 
                     16: extern char NOBKPT[];
                     17: extern char SZBKPT[];
                     18: extern char EXBKPT[];
                     19: extern char NOPCS[];
                     20: extern char BADMOD[];
                     21: extern char NOFORK[];
                     22: extern char ENDPCS[];
                     23: extern char BADWAIT[];
                     24: 
                     25: struct bkpt *bkpthead;         /* head of breakpoint list */
                     26: 
                     27: static long runcount;          /* number of times to loop past breakpoints */
                     28: 
                     29: /* bpstate remembers whether we have installed the breakpoints */
                     30: static enum { BPOUT, BPIN } bpstate;
                     31: 
                     32: char   *malloc();
                     33: 
                     34: /* run modes */
                     35: #define        CONTINUOUS      0
                     36: #define        SINGLESTEP      1
                     37: 
                     38: /* sub process control */
                     39: 
                     40: subpcs(modif)
                     41:        int modif;
                     42: {
                     43:        register int check;
                     44:        register struct bkpt *bp;
                     45:        int execsig, runmode;
                     46:        char *comptr;
                     47: 
                     48:        switch (modif) {
                     49: 
                     50:        case 'd':
                     51:                /* delete breakpoint */
                     52:                if ((bp = scanbkpt(dot)) == NULL)
                     53:                        error(NOBKPT);
                     54:                bp->state = BKPT_FREE;
                     55:                return;
                     56: 
                     57:        case 'D':
                     58:                /* delete all breapoints */
                     59:                for (bp = bkpthead; bp != NULL; bp = bp->next)
                     60:                        bp->state = BKPT_FREE;
                     61:                return;
                     62: 
                     63:        case 'b':
                     64:        case 'B':
                     65:                /* set breakpoint */
                     66:                if ((bp = scanbkpt(dot)) == NULL) {
                     67:                        /* find a free one, or make one */
                     68:                        for (bp = bkpthead; bp != NULL; bp = bp->next)
                     69:                                if (bp->state == BKPT_FREE)
                     70:                                        break;
                     71:                        if (bp == NULL) {
                     72:                                bp = (struct bkpt *)malloc(sizeof *bp);
                     73:                                if (bp == NULL)
                     74:                                        error(EXBKPT);
                     75:                                bp->next = bkpthead;
                     76:                                bkpthead = bp;
                     77:                        }
                     78:                }
                     79:                bp->loc = dot;
                     80:                bp->initcnt = bp->count = ecount;
                     81:                bp->state = BKPT_SET;
                     82:                check = MAX_BKPTCOM - 1;
                     83:                comptr = bp->comm;
                     84:                (void) rdc();
                     85:                unreadc();
                     86:                do {
                     87:                        *comptr++ = readchar();
                     88:                } while (check-- && lastc != '\n');
                     89:                *comptr = 0;
                     90:                unreadc();
                     91:                if (check == 0)
                     92:                        error(SZBKPT);
                     93:                return;
                     94: 
                     95:        case 'k':
                     96:        case 'K':
                     97:                /* kill process */
                     98:                if (pid == 0)
                     99:                        error(NOPCS);
                    100:                adbprintf("%d: killed", pid);
                    101:                endpcs();
                    102:                return;
                    103: 
                    104:        case 'r':
                    105:        case 'R':
                    106:                /* run program */
                    107:                endpcs();
                    108:                setup();
                    109:                runcount = ecount;
                    110:                runmode = CONTINUOUS;
                    111:                execsig = 0;
                    112:                /* if starting at a breakpoint, run over it */
                    113:                if (scanbkpt(gavedot ? dot : entrypc()) != NULL)
                    114:                        runcount++;
                    115:                break;
                    116: 
                    117:        case 's':
                    118:        case 'S':
                    119:                /* single step, with optional signal */
                    120:                runcount = ecount;
                    121:                if (pid) {
                    122:                        runmode = SINGLESTEP;
                    123:                        execsig = oexpr() ? expv : signo;
                    124:                } else {
                    125:                        setup();
                    126:                        runmode = SINGLESTEP;
                    127:                        execsig = 0;
                    128:                        runcount--;
                    129:                }
                    130:                break;
                    131: 
                    132:        case 'c':
                    133:        case 'C':
                    134:        case 0:
                    135:                /* continue with optional signal */
                    136:                runcount = ecount;
                    137:                if (pid == 0)
                    138:                        error(NOPCS);
                    139:                runmode = CONTINUOUS;
                    140:                execsig = oexpr() ? expv : signo;
                    141:                break;
                    142: 
                    143:        default:
                    144:                error(BADMOD);
                    145:                /* NOTREACHED */
                    146:        }
                    147: 
                    148:        if (runcount > 0 && runpcs(runmode, execsig))
                    149:                adbprintf("breakpoint%16t");
                    150:        else
                    151:                adbprintf("stopped at%16t");
                    152:        delbp();
                    153:        printpc();
                    154: }
                    155: 
                    156: /*
                    157:  * Print all breakpoints.
                    158:  */
                    159: printbkpts()
                    160: {
                    161:        register struct bkpt *b;
                    162: 
                    163:        adbprintf("breakpoints\ncount%8tbkpt%24tcommand\n");
                    164:        for (b = bkpthead; b != NULL; b = b->next) {
                    165:                if (b->state != BKPT_FREE) {
                    166:                        adbprintf("%-8.8D", b->count);
                    167:                        psymoff("%R", b->loc, SP_INSTR, maxoff, "%24t");
                    168:                        prints(b->comm);
                    169:                }
                    170:        }
                    171: }
                    172: 
                    173: /*
                    174:  * Remove (restore to original instruction(s)) all breakpoints.
                    175:  */
                    176: delbp()
                    177: {
                    178:        register struct bkpt *b;
                    179: 
                    180:        if (bpstate != BPOUT) {
                    181:                for (b = bkpthead; b != NULL; b = b->next)
                    182:                        if (b->state != BKPT_FREE && clr_bpt(b))
                    183:                                bperr(b, "clear");
                    184:                bpstate = BPOUT;
                    185:        }
                    186: }
                    187: 
                    188: /*
                    189:  * Insert all breakpoints.
                    190:  */
                    191: setbp()
                    192: {
                    193:        register struct bkpt *b;
                    194: 
                    195:        if (bpstate != BPIN) {
                    196:                for (b = bkpthead; b != NULL; b = b->next)
                    197:                        if (b->state != BKPT_FREE && set_bpt(b))
                    198:                                bperr(b, "set");
                    199:                bpstate = BPIN;
                    200:        }
                    201: }
                    202: 
                    203: static
                    204: bperr(b, how)
                    205:        struct bkpt *b;
                    206:        char *how;
                    207: {
                    208: 
                    209:        adbprintf("cannot %s breakpoint: ", how);
                    210:        psymoff("%R", b->loc, SP_INSTR, maxoff, "\n");
                    211: }
                    212: 
                    213: /*
                    214:  * Run subprocess for a while.
                    215:  * Return true iff stopped due to breakpoint.
                    216:  */
                    217: int
                    218: runpcs(runmode, execsig)
                    219:        int runmode, execsig;
                    220: {
                    221:        register struct bkpt *bkpt;
                    222:        int rc;
                    223: 
                    224:        /* always set pc, so that expr>pc works too */
                    225:        setpc(gavedot ? dot : getpc());
                    226:        adbprintf("%s: running\n", symfile.name);
                    227:        while (--runcount >= 0) {
                    228:                /* BEGIN XXX (machine dependent?, delete ptrace, etc) */
                    229:                if (runmode == SINGLESTEP)
                    230:                        delbp();        /* hardware handles single-stepping */
                    231:                else {  /* continuing from a breakpoint is hard */
                    232:                        if ((bkpt = scanbkpt(getpc())) != NULL) {
                    233:                                execbkpt(bkpt, execsig);
                    234:                                execsig = 0;
                    235:                        }
                    236:                        setbp();
                    237:                }
                    238:                (void) ptrace(runmode == CONTINUOUS ? PT_CONTINUE : PT_STEP,
                    239:                        pid, (int *)getpc(), execsig);
                    240:                /* END XXX */
                    241: 
                    242:                /* paranoia, SP_DATA usually sufficient, but this is easy */
                    243:                cacheinval(SP_INSTR | SP_DATA);
                    244: 
                    245:                bpwait();
                    246:                checkerr();
                    247:                execsig = 0;
                    248:                delbp();
                    249:                readregs();
                    250: 
                    251:                if (signo != 0 || (bkpt = scanbkpt(getpc())) == NULL) {
                    252:                        execsig = signo;
                    253:                        rc = 0;
                    254:                        continue;
                    255:                }
                    256:                /* stopped by BPT instruction */
                    257: #ifdef DEBUG
                    258:                adbprintf("\n BPT code: comm=%s%8tstate=%d",
                    259:                    bkpt->comm, bkpt->state);
                    260: #endif
                    261:                dot = bkpt->loc;
                    262:                switch (bkpt->state) {
                    263:                        char *p;
                    264: 
                    265:                case BKPT_SET:
                    266:                        bkpt->state = BKPT_TRIPPED;
                    267:                        if (*bkpt->comm == '\n')
                    268:                                break;
                    269:                        p = lp;
                    270:                        command(bkpt->comm, ':');
                    271:                        lp = p;
                    272:                        if (gavedot && edot == 0) /* maybe dot==0 ??? */
                    273:                                break;
                    274:                        if (--bkpt->count == 0)
                    275:                                break;
                    276:                        /* FALLTHROUGH */
                    277: 
                    278:                case BKPT_TRIPPED:
                    279:                        execbkpt(bkpt, execsig);
                    280:                        execsig = 0;
                    281:                        runcount++;
                    282:                        continue;
                    283: 
                    284:                default:
                    285:                        panic("runpcs");
                    286:                        /* NOTREACHED */
                    287:                }
                    288:                bkpt->count = bkpt->initcnt;
                    289:                rc = 1;
                    290:        }
                    291:        return (rc);
                    292: }
                    293: 
                    294: endpcs()
                    295: {
                    296:        register struct bkpt *bp;
                    297: 
                    298:        if (pid) {
                    299:                (void) ptrace(PT_KILL, pid, (int *)0, 0);       /* XXX */
                    300:                pid = 0;
                    301:                for (bp = bkpthead; bp != NULL; bp = bp->next)
                    302:                        if (bp->state != BKPT_FREE)
                    303:                                bp->state = BKPT_SET;
                    304:        }
                    305:        bpstate = BPOUT;
                    306: }
                    307: 
                    308: #ifdef VFORK
                    309: nullsig()
                    310: {
                    311: 
                    312: }
                    313: #endif
                    314: 
                    315: setup()
                    316: {
                    317: 
                    318:        cacheinval(SP_INSTR | SP_DATA); /* paranoia */
                    319:        (void) close(symfile.fd);
                    320:        symfile.fd = -1;
                    321: #ifndef VFORK
                    322: #define vfork fork
                    323: #endif
                    324:        if ((pid = vfork()) == 0) {
                    325:                (void) ptrace(PT_TRACE_ME, 0, (int *)0, 0);     /* XXX */
                    326: #ifdef VFORK
                    327:                (void) signal(SIGTRAP, nullsig);
                    328: #endif
                    329:                (void) signal(SIGINT, sigint);
                    330:                (void) signal(SIGQUIT, sigquit);
                    331:                doexec();
                    332:                exit(0);
                    333:        } else if (pid == -1) {
                    334:                pid = 0;
                    335:                error(NOFORK);
                    336:        } else {
                    337:                bpwait();
                    338:                readregs();
                    339:                symfile.fd = open(symfile.name, wtflag);
                    340:                if (errflag) {
                    341:                        adbprintf("%s: cannot execute\n", symfile.name);
                    342:                        endpcs();
                    343:                        error((char *)0);
                    344:                }
                    345:        }
                    346:        bpstate = BPOUT;
                    347: }
                    348: 
                    349: /*
                    350:  * Single step over a location containing a breakpoint.
                    351:  */
                    352: execbkpt(bp, execsig)
                    353:        struct bkpt *bp;
                    354:        int execsig;
                    355: {
                    356: 
                    357: #ifdef DEBUG
                    358:        adbprintf("exbkpt: %d\n", bp->count);
                    359: #endif
                    360:        delbp();
                    361:        (void) ptrace(PT_STEP, pid, (int *)bp->loc, execsig);   /* XXX */
                    362:        bp->state = BKPT_SET;
                    363:        bpwait();
                    364:        checkerr();
                    365:        readregs();
                    366: }
                    367: 
                    368: static char separators[] = "<> \t\n";
                    369: 
                    370: doexec()
                    371: {
                    372:        register char *p, **ap;
                    373:        register int c;
                    374:        char *argl[LINELEN / 2 + 1];
                    375:        char args[LINELEN];
                    376:        extern char **environ;
                    377:        char *index();
                    378: 
                    379:        ap = argl;
                    380:        p = args;
                    381:        *ap++ = symfile.name;
                    382:        do {
                    383:                switch (c = rdc()) {
                    384: 
                    385:                case '\n':
                    386:                        break;
                    387: 
                    388:                case '<':
                    389:                        setfile(0, O_RDONLY, 0, p, "open");
                    390:                        break;
                    391: 
                    392:                case '>':
                    393:                        setfile(1, O_CREAT|O_WRONLY, 0666, p, "create");
                    394:                        break;
                    395: 
                    396:                default:
                    397:                        *ap = p;
                    398:                        while (index(separators, c) == NULL) {
                    399:                                *p++ = c;
                    400:                                c = readchar();
                    401:                        }
                    402:                        *p++ = '\0';
                    403:                        ap++;
                    404:                }
                    405:        } while (c != '\n');
                    406:        unreadc();
                    407:        *ap++ = 0;
                    408:        execve(symfile.name, argl, environ);
                    409:        perror(symfile.name);
                    410: }
                    411: 
                    412: static int
                    413: setfile(fd, flags, mode, namebuf, err)
                    414:        int fd, flags, mode;
                    415:        char *namebuf, *err;
                    416: {
                    417:        register char *p = namebuf;
                    418:        register int c = rdc();
                    419: 
                    420:        while (index(separators, c) == NULL) {
                    421:                *p++ = c;
                    422:                c = readchar();
                    423:        }
                    424:        *p = 0;
                    425:        (void) close(fd);
                    426:        if (open(namebuf, flags, mode) < 0) {
                    427:                adbprintf("%s: cannot %s\n", namebuf, err);
                    428:                _exit(0);
                    429:                /* NOTREACHED */
                    430:        }
                    431: }
                    432: 
                    433: struct bkpt *
                    434: scanbkpt(a)
                    435:        register addr_t a;
                    436: {
                    437:        register struct bkpt *bp;
                    438: 
                    439:        for (bp = bkpthead; bp != NULL; bp = bp->next)
                    440:                if (bp->state != BKPT_FREE && bp->loc == a)
                    441:                        break;
                    442:        return (bp);
                    443: }
                    444: 
                    445: bpwait()
                    446: {
                    447:        register int w;
                    448:        union wait status;
                    449: 
                    450:        (void) signal(SIGINT, SIG_IGN);
                    451:        while ((w = wait(&status)) != pid && w != -1)
                    452:                 /* void */ ;
                    453:        (void) signal(SIGINT, intcatch);
                    454:        if (w == -1) {
                    455:                pid = 0;
                    456:                errflag = BADWAIT;
                    457:        } else if (!WIFSTOPPED(status)) {
                    458:                sigcode = 0;
                    459:                if ((signo = status.w_termsig) != 0)
                    460:                        sigprint();
                    461:                if (status.w_coredump) {
                    462:                        prints(" - core dumped");
                    463:                        (void) close(corefile.fd);
                    464:                        setcore();
                    465:                }
                    466:                pid = 0;
                    467:                bpstate = BPOUT;
                    468:                errflag = ENDPCS;
                    469:        } else {
                    470:                signo = status.w_stopsig;
                    471:                sigcode = ptrace(PT_READ_U, pid,
                    472:                                 &((struct user *)0)->u_code, 0); /* XXX */
                    473:                if (signo != SIGTRAP)
                    474:                        sigprint();
                    475:                else
                    476:                        signo = 0;
                    477:                flushbuf();
                    478:        }
                    479: }

unix.superglobalmegacorp.com

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