Annotation of 42BSD/ucb/pascal/pdx/tree/tracestop.c, revision 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.