Annotation of 43BSDReno/pgrm/pascal/pdx/tree/tracestop.c, revision 1.1

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

unix.superglobalmegacorp.com

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