Annotation of coherent/d/bin/db/trace2.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * A debugger.
                      3:  * Runtime support.
                      4:  */
                      5: #include <stdio.h>
                      6: #include <ctype.h>
                      7: #include <errno.h>
                      8: #include "trace.h"
                      9: #if NOUT
                     10: #include <n.out.h>
                     11: #else
                     12: #include <l.out.h>
                     13: #endif
                     14: #include <sys/uproc.h>
                     15: #include <signal.h>
                     16: 
                     17: /*
                     18:  * Talk to the user and try to solve his problems.
                     19:  */
                     20: process()
                     21: {
                     22:        register BPT *bp;
                     23:        register int n;
                     24:        register int nibflag;
                     25:        register int bptflag;
                     26:        register vaddr_t pc;
                     27:        register vaddr_t fp;
                     28:        register int f;
                     29: 
                     30:        /*
                     31:         * Let the user speak.
                     32:         */
                     33: top:
                     34:        bptflag = 0;
                     35:        execute(":x\n");
                     36:        for (;;) {
                     37:                /*
                     38:                 * Initialise flags.
                     39:                 */
                     40:                bitflag = 0;
                     41:                nibflag = 0;
                     42:        
                     43:                /*
                     44:                 * If in single step mode, set up for single step.
                     45:                 */
                     46:                if (sinmode!=SNULL && sinmode!=SWAIT) {
                     47:                        bitflag = 1;
                     48:                        if (sinmode == SCONT)
                     49:                                setcont();
                     50:                }
                     51:        
                     52:                /*
                     53:                 * Place all breakpoints.
                     54:                 */
                     55:                pc = getpc();
                     56:                for (n=NBPT, bp=&bpt[0]; n--; bp++) {
                     57:                        if (bp->b_flag == 0)
                     58:                                continue;
                     59:                        add = bp->b_badd;
                     60:                        if (getb(1, bp->b_bins, sizeof(BIN)) == 0) {
                     61:                                fprintf( stderr, "cannot read\n");
                     62:                                printb(bp->b_badd);
                     63:                                goto err;
                     64:                        }
                     65:                        if (bptflag!=0 && bp->b_badd==pc) {
                     66:                                bitflag = 1;
                     67:                                continue;
                     68:                        }
                     69:                        add = bp->b_badd;
                     70:                        if (putb(1, bin, sizeof(BIN)) == 0) {
                     71:                                fprintf( stderr, "cannot install\n");
                     72:                                printb(bp->b_badd);
                     73:                                goto err;
                     74:                        }
                     75:                }
                     76:                bptflag = 0;
                     77: 
                     78:                /*
                     79:                 * Set flags and call machine dependent restore routine.
                     80:                 */
                     81:                if (testbpt(pc) != 0)
                     82:                        nibflag = 1;
                     83:                if (restret() == 0)
                     84:                        goto err;
                     85:        
                     86:                /*
                     87:                 * Start up the child.
                     88:                 */
                     89:                errno = 0;
                     90:                ptrace(bitflag?9:7, pid, (int *)1, 0);
                     91:                if (errno) {
                     92:                        printr("Ptrace error (%d)", errno);
                     93:                        goto err;
                     94:                }
                     95:                if (waitc() == 0)
                     96:                        goto err;
                     97:        
                     98:                /*
                     99:                 * Get registers and call machine dependent trap routine.
                    100:                 */
                    101:                if (trapint() == 0)
                    102:                        goto err;
                    103:                if (setregs() == 0)
                    104:                        goto err;
                    105:                if ((f=settrap()) == 0)
                    106:                        goto err;
                    107:                /*
                    108:                 * Replace breakpoints with instructions.
                    109:                 */
                    110:                for (n=NBPT, bp=&bpt[0]; n--; bp++) {
                    111:                        if (bp->b_flag == 0)
                    112:                                continue;
                    113:                        add = bp->b_badd;
                    114:                        if (putb(1, bp->b_bins, sizeof(BIN)) == 0) {
                    115:                                fprintf( stderr, "cannot replace instr\n");
                    116:                                printb(bp->b_badd);
                    117:                                goto err;
                    118:                        }
                    119:                }
                    120:        
                    121:                /*
                    122:                 * If trap was not a breakpoint, tell the user, accept input.
                    123:                 */
                    124:                if (f != SIGTRAP) {
                    125:                        execute(":f\n:x\n");
                    126:                        continue;
                    127:                }
                    128: 
                    129:                /*
                    130:                 * Find the breakpoint we are at.
                    131:                 */
                    132:                pc = getpc() - sizeof(BIN);
                    133:                if (bitflag==0 || nibflag!=0) {
                    134:                        for (n=NBPT, bp=&bpt[0]; n--; bp++) {
                    135:                                if (bp->b_flag == 0)
                    136:                                        continue;
                    137:                                if (bp->b_badd != pc)
                    138:                                        continue;
                    139:                                setpc((vaddr_t)pc);
                    140:                                bptflag = 1;
                    141:                                break;
                    142:                        }
                    143:                }
                    144: 
                    145:                /*
                    146:                 * If in single step mode, execute command.
                    147:                 */
                    148:                switch (sinmode) {
                    149:                case SSTEP:
                    150:                case SCONT:
                    151:                        execute(sinp);
                    152:                        if (--sindecr == 0)
                    153:                                execute(":x\n");
                    154:                        continue;
                    155:                case SCSET:
                    156:                        for (n=0, bp=&bpt[0]; n<NBPT; n++, bp++)
                    157:                                bp->b_flag &= ~BSIN;
                    158:                        sinmode = SWAIT;
                    159:                        intcont();
                    160:                        break;
                    161:                }
                    162: 
                    163:                /*
                    164:                 * If we got an unexpected trace trap or unknown
                    165:                 * breakpoint, we handle it here.
                    166:                 */
                    167:                if (bp == NULL) {
                    168:                        if (bitflag==0 || nibflag!=0)
                    169:                                execute(":f\n:x\n");
                    170:                        continue;
                    171:                }
                    172: 
                    173:                /*
                    174:                 * Single step breakpoints have highest priority.
                    175:                 */
                    176:                fp = getfp();
                    177:                if ((bp->b_flag&BSIN) != 0) {
                    178:                        if (bp->b_sfpt==0 || bp->b_sfpt==fp) {
                    179:                                bp->b_flag &= ~BSIN;
                    180:                                if (sinmode == SWAIT) {
                    181:                                        sinmode = SCONT;
                    182:                                        execute(sinp);
                    183:                                        if (--sindecr == 0)
                    184:                                               execute(":x\n");
                    185:                                        continue;
                    186:                                }
                    187:                        }
                    188:                }
                    189: 
                    190:                /*
                    191:                 * Return breakpoints are next.
                    192:                 */
                    193:                if ((bp->b_flag&BRET) != 0) {
                    194:                        if (fp == bp->b_rfpt) {
                    195:                                bp->b_flag &= ~BRET;
                    196:                                execute(bp->b_rcom);
                    197:                                continue;
                    198:                        }
                    199:                }
                    200: 
                    201:                /*
                    202:                 * Your conventional everyday ordinary breakpoint.
                    203:                 */
                    204:                if ((bp->b_flag&BBPT) != 0) {
                    205:                        execute(bp->b_bcom);
                    206:                        continue;
                    207:                }
                    208:        }
                    209: 
                    210:        /*
                    211:         * Something is terribly wrong.  Kill off our child,
                    212:         * and generally reset everything to the start.
                    213:         */
                    214: err:
                    215:        killc();
                    216:        reslout();
                    217:        bptinit();
                    218:        goto top;
                    219: 
                    220:        /*
                    221:         * They say psychiatry is one of the hardest occupations.
                    222:         * I think I agree.
                    223:         */
                    224: }
                    225: 
                    226: /*
                    227:  * Reset segmentation for an l.out.
                    228:  */
                    229: reslout()
                    230: {
                    231:        struct ldheader ldh;
                    232: 
                    233:        clramap();
                    234:        objflag = 0;
                    235:        fseek(lfp, (long)0, 0);
                    236:        if (fread(&ldh, sizeof(ldh), 1, lfp) != 1) {
                    237:                printr("Can't read object file");
                    238:                return (0);
                    239:        }
                    240:        canlout(&ldh);
                    241:        if (ldh.l_magic != L_MAGIC) {
                    242:                printr("not an object file");
                    243:                return (0);
                    244:        }
                    245:        objflag = 1;
                    246:        setaseg(&ldh);
                    247:        return (1);
                    248: }
                    249: 
                    250: /*
                    251:  * Given a command line in `miscbuf', parse the command line, kill the
                    252:  * current child and start up a new one.  0 is returned on success, 1
                    253:  * on failure.
                    254:  */
                    255: runfile()
                    256: {
                    257:        register char *bp, *cp;
                    258:        register int c;
                    259:        char *ifn, *ofn, *argl[ARGSIZE];
                    260:        int qflag, aflag, n;
                    261: 
                    262:        killc();
                    263:        if (objflag == 0) {
                    264:                printe("No l.out");
                    265:                return (1);
                    266:        }
                    267:        ifn = NULL;
                    268:        ofn = NULL;
                    269:        qflag = 0;
                    270:        aflag = 0;
                    271:        n = 0;
                    272:        bp = miscbuf;
                    273:        cp = miscbuf;
                    274:        c = *bp++;
                    275:        while (c != '\n') {
                    276:                switch (c) {
                    277:                case '<':
                    278:                        ifn = cp;
                    279:                        c = *bp++;
                    280:                        break;
                    281:                case '>':
                    282:                        ofn = cp;
                    283:                        if ((c=*bp++) == '>') {
                    284:                                aflag = 1;
                    285:                                c = *bp++;
                    286:                        }
                    287:                        break;
                    288:                default:
                    289:                        if (n >= ARGSIZE-1) {
                    290:                                printe("Too many arguments");
                    291:                                return (1);
                    292:                        }
                    293:                        argl[n++] = cp;
                    294:                }
                    295:                while (qflag || !isascii(c) || !isspace(c)) {
                    296:                        if (c == '\n')
                    297:                                break;
                    298:                        if (c == '"') {
                    299:                                qflag ^= 1;
                    300:                                c = *bp++;
                    301:                                continue;
                    302:                        }
                    303:                        if (c == '\\') {
                    304:                                if ((c=*bp++) == '\n') {
                    305:                                        printe("Syntax error");
                    306:                                        return (1);
                    307:                                }
                    308:                        }
                    309:                        *cp++ = c;
                    310:                        c = *bp++;
                    311:                }
                    312:                if (qflag) {
                    313:                        printe("Missing \"");
                    314:                        return (1);
                    315:                }
                    316:                *cp++ = '\0';
                    317:                if (c == '\n')
                    318:                        break;
                    319:                while (isascii(c) && isspace(c))
                    320:                        c = *bp++;
                    321:        }
                    322:        if (n == 0)
                    323:                argl[n++] = lfn;
                    324:        argl[n] = NULL;
                    325:        if (startup(argl, ifn, ofn, aflag) == 0)
                    326:                return (1);
                    327:        return (0);
                    328: }
                    329: 
                    330: /*
                    331:  * Start execution of the child.  `argv' is the argument list, `ifnp' is
                    332:  * the name of the input file, `ofnp' is the name of the output file and
                    333:  * `appf' tells us whether the output file is opened for append or write.
                    334:  */
                    335: startup(argv, ifnp, ofnp, appf)
                    336: char **argv;
                    337: char *ifnp;
                    338: char *ofnp;
                    339: {
                    340:        register int n;
                    341: 
                    342:        if ((pid=fork()) < 0) {
                    343:                printr("Cannot fork");
                    344:                return (0);
                    345:        }
                    346:        if (pid == 0) {
                    347:                if (ifnp != NULL) {
                    348:                        if ((n=open(ifnp, 0)) < 0)
                    349:                                panic("Cannot open %s", ifnp);
                    350:                        dup2(n, 0);
                    351:                        close(n);
                    352:                }
                    353:                if (ofnp != NULL) {
                    354:                        n = -1;
                    355:                        if (appf) {
                    356:                                if ((n=open(ofnp, 1)) >= 0)
                    357:                                        lseek(n, 0L, 2);
                    358:                        }
                    359:                        if (n < 0) {
                    360:                                if ((n=creat(ofnp, 0644)) < 0)
                    361:                                        panic("%s: cannot create", ofnp);
                    362:                        }
                    363:                        dup2(n, 1);
                    364:                        close(n);
                    365:                }
                    366:                ptrace(0, 0, NULL, 0);
                    367:                execv(lfn, argv);
                    368:                exit(1);
                    369:        }
                    370:        if (waitc() == 0)
                    371:                return (0);
                    372:        clramap();
                    373:        DSPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
                    374:                        getp, putp, 1);
                    375:        ISPACE = setsmap(NULL, (fsize_t)0, (fsize_t)LI, (fsize_t)0,
                    376:                        getp, putp, 0);
                    377:        USPACE = setsmap(NULL, (fsize_t)0, (fsize_t)UPASIZE, (fsize_t)0,
                    378:                        getp, putp, 2);
                    379:        excflag = 1;
                    380:        regflag = 1;
                    381:        return (1);
                    382: }
                    383: 
                    384: /*
                    385:  * Given a newly started child, find out necessary information.
                    386:  */
                    387: shiftup()
                    388: {
                    389:        if (trapint() == 0)
                    390:                return (0);
                    391:        if (setregs() == 0)
                    392:                return (0);
                    393:        return (settrap());
                    394: }
                    395: 
                    396: /*
                    397:  * Kill off our child.
                    398:  */
                    399: killc()
                    400: {
                    401:        if (excflag) {
                    402:                ptrace(8, pid, 0, 0);
                    403:                waitc();
                    404:        }
                    405:        excflag = 0;
                    406:        regflag = 0;
                    407:        trapstr = NULL;
                    408: }
                    409: 
                    410: /*
                    411:  * Wait for the traced process to stop.
                    412:  */
                    413: waitc()
                    414: {
                    415:        register int p;
                    416:        int s;
                    417: 
                    418:        while ((p=wait(&s)) != pid) {
                    419:                if (p >= 0) {
                    420:                        printr("Adopted a child %d", p);
                    421:                        continue;
                    422:                }
                    423:                if (intflag == 0) {
                    424:                        excflag = 0;
                    425:                        printr("Nonexistant child");
                    426:                        return (0);
                    427:                }
                    428:                intflag = 0;
                    429:        }
                    430:        if ((s&0377) != 0177) {
                    431:                excflag = 0;
                    432:                printr("Child process terminated (%d)", (s>>8)&0377);
                    433:                return (0);
                    434:        }
                    435:        return (1);
                    436: }

unix.superglobalmegacorp.com

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