Annotation of 42BSD/ucb/pascal/pdx/tree/tracestop.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1982 Regents of the University of California */
                      2: 
                      3: static char sccsid[] = "@(#)tracestop.c 1.1 1/18/82";
                      4: 
                      5: /*
                      6:  * Handle trace and stop commands.
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: #include "breakpoint.h"
                     11: #include "sym.h"
                     12: #include "tree.h"
                     13: #include "runtime.h"
                     14: #include "source.h"
                     15: #include "object.h"
                     16: #include "mappings.h"
                     17: #include "machine.h"
                     18: #include "tree.rep"
                     19: 
                     20: LOCAL SYM *tcontainer();
                     21: 
                     22: /*
                     23:  * Process a trace/untrace command, basically checking arguments
                     24:  * and translate to a call of the appropriate routine.
                     25:  */
                     26: 
                     27: trace(cmd, exp, where, cond)
                     28: int cmd;
                     29: NODE *exp;
                     30: NODE *where;
                     31: NODE *cond;
                     32: {
                     33:        if (exp == NIL) {
                     34:                traceall(cmd, where, cond);
                     35:        } else if (exp->op == O_LCON || exp->op == O_QLINE) {
                     36:                traceinst(cmd, exp, where, cond);
                     37:        } else if (where!=NIL && (where->op==O_QLINE || where->op==O_LCON)) {
                     38:                traceat(cmd, exp, where, cond);
                     39:        } else {
                     40:                tracedata(cmd, exp, where, cond);
                     41:        }
                     42:        if (where != NIL) {
                     43:                tfree(where);
                     44:        }
                     45: }
                     46: 
                     47: /*
                     48:  * Set a breakpoint that will turn on tracing.
                     49:  *
                     50:  * A line number of 0 in the breakpoint information structure
                     51:  * means it's a normal trace.
                     52:  *
                     53:  * A line number of -1 indicates that we want to trace at the instruction
                     54:  * rather than source line level.
                     55:  *
                     56:  * If location is NIL, turn on tracing because if the user
                     57:  * has the program stopped somewhere and says "trace",
                     58:  * he/she wants to see tracing after continuing execution.
                     59:  */
                     60: 
                     61: LOCAL traceall(cmd, where, cond)
                     62: int cmd;
                     63: NODE *where;
                     64: NODE *cond;
                     65: {
                     66:        SYM *s;
                     67:        LINENO line;
                     68: 
                     69:        if (where != NIL && where->op != O_NAME) {
                     70:                error("bad location for trace");
                     71:        }
                     72:        if (cmd == O_TRACE) {
                     73:                line = 0;
                     74:        } else {
                     75:                line = -1;
                     76:        }
                     77:        if (where == NIL) {
                     78:                switch (cmd) {
                     79:                        case O_TRACE:
                     80:                                if (tracing != 0) {
                     81:                                        error("already tracing lines");
                     82:                                }
                     83:                                tracing++;
                     84:                                addcond(TRPRINT, cond);
                     85:                                break;
                     86: 
                     87:                        case O_TRACEI:
                     88:                                if (inst_tracing != 0) {
                     89:                                        error("already tracing instructions");
                     90:                                }
                     91:                                inst_tracing++;
                     92:                                addcond(TRPRINT, cond);
                     93:                                break;
                     94: 
                     95:                        default:
                     96:                                panic("bad cmd in traceall");
                     97:                                break;
                     98:                }
                     99:                s = program;
                    100:        } else if (where->op != O_NAME) {
                    101:                trerror("found %t, expected procedure or function", where);
                    102:        } else {
                    103:                s = where->nameval;
                    104:                if (!isblock(s)) {
                    105:                        error("\"%s\" is not a procedure or function", name(s));
                    106:                }
                    107:        }
                    108:        addbp(codeloc(s), ALL_ON, s, cond, NIL, line);
                    109: }
                    110: 
                    111: /*
                    112:  * Set up the appropriate breakpoint for tracing an instruction.
                    113:  */
                    114: 
                    115: LOCAL traceinst(cmd, exp, where, cond)
                    116: int cmd;
                    117: NODE *exp;
                    118: NODE *where;
                    119: NODE *cond;
                    120: {
                    121:        LINENO line;
                    122:        ADDRESS addr;
                    123: 
                    124:        if (where != NIL) {
                    125:                error("unexpected \"at\" or \"in\"");
                    126:        }
                    127:        if (cmd == O_TRACEI) {
                    128:                if (exp->op == O_QLINE) {
                    129:                        addr = (ADDRESS) exp->right->lconval;
                    130:                } else if (exp->op == O_LCON) {
                    131:                        addr = (ADDRESS) exp->lconval;
                    132:                } else {
                    133:                        trerror("expected integer constant, found %t", exp);
                    134:                }
                    135:                line = -1;
                    136:        } else {
                    137:                if (exp->op == O_QLINE) {
                    138:                        line = (LINENO) exp->right->lconval;
                    139:                        addr = objaddr(line, exp->left->sconval);
                    140:                } else {
                    141:                        line = (LINENO) exp->lconval;
                    142:                        addr = objaddr(line, cursource);
                    143:                }
                    144:                if (addr == (ADDRESS) -1) {
                    145:                        error("can't trace line %d", line);
                    146:                }
                    147:        }
                    148:        tfree(exp);
                    149:        addbp(addr, INST, NIL, cond, NIL, line);
                    150: }
                    151: 
                    152: /*
                    153:  * set a breakpoint to print an expression at a given line or address
                    154:  */
                    155: 
                    156: LOCAL traceat(cmd, exp, where, cond)
                    157: int cmd;
                    158: NODE *exp;
                    159: NODE *where;
                    160: NODE *cond;
                    161: {
                    162:        LINENO line;
                    163:        ADDRESS addr;
                    164: 
                    165:        if (cmd == O_TRACEI) {
                    166:                if (where->op != O_LCON) {
                    167:                        trerror("expected integer constant, found %t", where);
                    168:                }
                    169:                line = -1;
                    170:                addr = (ADDRESS) where->lconval;
                    171:        } else {
                    172:                line = (LINENO) where->right->lconval;
                    173:                addr = objaddr(line, where->left->sconval);
                    174:                if (addr == (ADDRESS) -1) {
                    175:                        error("can't trace at line %d", line);
                    176:                }
                    177:        }
                    178:        addbp(addr, AT_BP, NIL, cond, exp, line);
                    179: }
                    180: 
                    181: /*
                    182:  * Set up breakpoint for tracing data.
                    183:  *
                    184:  * The tracing of blocks lies somewhere between instruction and data;
                    185:  * it's here since a block cannot be distinguished from other terms.
                    186:  *
                    187:  * As in "traceall", if the "block" is the main program then the
                    188:  * user didn't actually specify a block.  This means we want to
                    189:  * turn tracing on ourselves because if the program is stopped
                    190:  * we want to be on regardless of whether they say "cont" or "run".
                    191:  */
                    192: 
                    193: LOCAL tracedata(cmd, exp, block, cond)
                    194: int cmd;
                    195: NODE *exp;
                    196: NODE *block;
                    197: NODE *cond;
                    198: {
                    199:        SYM *s, *t;
                    200: 
                    201:        if (exp->op != O_RVAL && exp->op != O_CALL) {
                    202:                error("can't trace expressions");
                    203:        }
                    204:        if (block == NIL) {
                    205:                t = tcontainer(exp->left);
                    206:        } else if (block->op == O_NAME) {
                    207:                t = block->nameval;
                    208:        } else {
                    209:                trerror("found %t, expected procedure or function", block);
                    210:        }
                    211:        if (exp->left->op == O_NAME) {
                    212:                s = exp->left->nameval;
                    213:                if (isblock(s)) {
                    214:                        addbp(codeloc(t), BLOCK_ON, t, cond, exp->left, 0);
                    215:                        if (t == program) {
                    216:                                addbp(codeloc(s), CALL, s, cond, NIL, 0);
                    217:                        }
                    218:                        return;
                    219:                }
                    220:        }
                    221:        addbp(codeloc(t), TERM_ON, t, cond, exp, 0);
                    222:        if (curfunc == t) {
                    223:                var_tracing++;
                    224:                addvar(TRPRINT, exp, cond);
                    225:                addbp(return_addr(), TERM_OFF, t, cond, exp, 0);
                    226:        }
                    227: }
                    228: 
                    229: /*
                    230:  * Setting and unsetting of stops.
                    231:  */
                    232: 
                    233: stop(cmd, exp, where, cond)
                    234: int cmd;
                    235: NODE *exp;
                    236: NODE *where;
                    237: NODE *cond;
                    238: {
                    239:        SYM *s;
                    240:        LINENO n;
                    241: 
                    242:        if (exp != NIL) {
                    243:                stopvar(cmd, exp, where, cond);
                    244:        } else if (cond != NIL) {
                    245:                if (where == NIL) {
                    246:                        s = program;
                    247:                } else if (where->op == O_NAME) {
                    248:                        s = where->nameval;
                    249:                } else {
                    250:                        error("bad location for stop");
                    251:                }
                    252:                n = codeloc(s);
                    253:                addbp(n, STOP_ON, s, cond, NIL, n);
                    254:                addcond(TRSTOP, cond);
                    255:                var_tracing++;
                    256:        } else if (where->op == O_NAME) {
                    257:                s = where->nameval;
                    258:                if (!isblock(s)) {
                    259:                        error("\"%s\" is not a procedure or function", name(s));
                    260:                }
                    261:                n = codeloc(s);
                    262:                addbp(n, STOP_BP, s, cond, NIL, srcline(firstline(s)));
                    263:        } else {
                    264:                stopinst(cmd, where, cond);
                    265:        }
                    266:        if (where != NIL) {
                    267:                tfree(where);
                    268:        }
                    269: }
                    270: 
                    271: LOCAL stopinst(cmd, where, cond)
                    272: int cmd;
                    273: NODE *where;
                    274: NODE *cond;
                    275: {
                    276:        LINENO line;
                    277:        ADDRESS addr;
                    278: 
                    279:        if (where->op != O_QLINE) {
                    280:                error("expected line number");
                    281:        }
                    282:        if (cmd == O_STOP) {
                    283:                line = (LINENO) where->right->lconval;
                    284:                addr = objaddr(line, where->left->sconval);
                    285:                if (addr == (ADDRESS) -1) {
                    286:                        error("can't stop at that line");
                    287:                }
                    288:        } else {
                    289:                line = -1;
                    290:                addr = (ADDRESS) where->right->lconval;
                    291:        }
                    292:        addbp(addr, STOP_BP, NIL, cond, NIL, line);
                    293: }
                    294: 
                    295: /*
                    296:  * Implement stopping on assignment to a variable by adding it to
                    297:  * the variable list.
                    298:  */
                    299: 
                    300: LOCAL stopvar(cmd, exp, where, cond)
                    301: int cmd;
                    302: NODE *exp;
                    303: NODE *where;
                    304: NODE *cond;
                    305: {
                    306:        SYM *s;
                    307: 
                    308:        if (exp->op != O_RVAL) {
                    309:                trerror("found %t, expected variable", exp);
                    310:        }
                    311:        if (cmd == O_STOPI) {
                    312:                inst_tracing++;
                    313:        }
                    314:        var_tracing++;
                    315:        addvar(TRSTOP, exp, cond);
                    316:        if (where == NIL) {
                    317:                s = program;
                    318:        } else if (where->op == O_NAME) {
                    319:                s = where->nameval;
                    320:        } else {
                    321:                error("bad location for stop");
                    322:        }
                    323:        addbp(codeloc(s), STOP_ON, s, cond, exp, 0);
                    324: }
                    325: 
                    326: /*
                    327:  * Figure out the block that contains the symbols
                    328:  * in the given variable expression.
                    329:  */
                    330: 
                    331: LOCAL SYM *tcontainer(var)
                    332: NODE *var;
                    333: {
                    334:        NODE *p;
                    335: 
                    336:        p = var;
                    337:        while (p->op != O_NAME) {
                    338:                if (isleaf(p->op)) {
                    339:                        panic("unexpected op %d in tcontainer", p->op);
                    340:                        /* NOTREACHED */
                    341:                }
                    342:                p = p->left;
                    343:        }
                    344:        return container(p->nameval);
                    345: }

unix.superglobalmegacorp.com

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