# 2.11BSD#431 - /usr/src/ucb/PORT/pascal/pdx/tree/tracestop.c

##### Functions

    stop              X
    stopinst          X
    stopvar           X
    tcontainer        X
    trace             X
    traceall          X
    traceat           X
    tracedata         X
    traceinst         X

       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.1 (Berkeley) 6/6/85";
       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:     if (exp->op != O_RVAL && exp->op != O_CALL) {
     208:         error("can't trace expressions");
     209:     }
     210:     if (block == NIL) {
     211:         t = tcontainer(exp->left);
     212:     } else if (block->op == O_NAME) {
     213:         t = block->nameval;
     214:     } else {
     215:         trerror("found %t, expected procedure or function", block);
     216:     }
     217:     if (exp->left->op == O_NAME) {
     218:         s = exp->left->nameval;
     219:         if (isblock(s)) {
     220:             addbp(codeloc(t), BLOCK_ON, t, cond, exp->left, 0);
     221:             if (t == program) {
     222:                 addbp(codeloc(s), CALL, s, cond, NIL, 0);
     223:             }
     224:             return;
     225:         }
     226:     }
     227:     addbp(codeloc(t), TERM_ON, t, cond, exp, 0);
     228:     if (curfunc == t) {
     229:         var_tracing++;
     230:         addvar(TRPRINT, exp, cond);
     231:         addbp(return_addr(), TERM_OFF, t, cond, exp, 0);
     232:     }
     233: }
     234:
     235: /*
     236:  * Setting and unsetting of stops.
     237:  */
     238:
     239: stop(cmd, exp, where, cond)
     240: int cmd;
     241: NODE *exp;
     242: NODE *where;
     243: NODE *cond;
     244: {
     245:     SYM *s;
     246:     LINENO n;
     247:
     248:     if (exp != NIL) {
     249:         stopvar(cmd, exp, where, cond);
     250:     } else if (cond != NIL) {
     251:         if (where == NIL) {
     252:             s = program;
     253:         } else if (where->op == O_NAME) {
     254:             s = where->nameval;
     255:         } else {
     256:             error("bad location for stop");
     257:         }
     258:         n = codeloc(s);
     259:         addbp(n, STOP_ON, s, cond, NIL, n);
     260:         addcond(TRSTOP, cond);
     261:         var_tracing++;
     262:     } else if (where->op == O_NAME) {
     263:         s = where->nameval;
     264:         if (!isblock(s)) {
     265:             error("\"%s\" is not a procedure or function", name(s));
     266:         }
     267:         n = codeloc(s);
     268:         addbp(n, STOP_BP, s, cond, NIL, srcline(firstline(s)));
     269:     } else {
     270:         stopinst(cmd, where, cond);
     271:     }
     272:     if (where != NIL) {
     273:         tfree(where);
     274:     }
     275: }
     276:
     277: LOCAL stopinst(cmd, where, cond)
     278: int cmd;
     279: NODE *where;
     280: NODE *cond;
     281: {
     282:     LINENO line;
     283:     ADDRESS addr;
     284:
     285:     if (where->op != O_QLINE) {
     286:         error("expected line number");
     287:     }
     288:     if (cmd == O_STOP) {
     289:         line = (LINENO) where->right->lconval;
     290:         addr = objaddr(line, where->left->sconval);
     291:         if (addr == (ADDRESS) -1) {
     292:             error("can't stop at that line");
     293:         }
     294:     } else {
     295:         line = -1;
     296:         addr = (ADDRESS) where->right->lconval;
     297:     }
     298:     addbp(addr, STOP_BP, NIL, cond, NIL, line);
     299: }
     300:
     301: /*
     302:  * Implement stopping on assignment to a variable by adding it to
     303:  * the variable list.
     304:  */
     305:
     306: LOCAL stopvar(cmd, exp, where, cond)
     307: int cmd;
     308: NODE *exp;
     309: NODE *where;
     310: NODE *cond;
     311: {
     312:     SYM *s;
     313:
     314:     if (exp->op != O_RVAL) {
     315:         trerror("found %t, expected variable", exp);
     316:     }
     317:     if (cmd == O_STOPI) {
     318:         inst_tracing++;
     319:     }
     320:     var_tracing++;
     321:     addvar(TRSTOP, exp, cond);
     322:     if (where == NIL) {
     323:         s = program;
     324:     } else if (where->op == O_NAME) {
     325:         s = where->nameval;
     326:     } else {
     327:         error("bad location for stop");
     328:     }
     329:     addbp(codeloc(s), STOP_ON, s, cond, exp, 0);
     330: }
     331:
     332: /*
     333:  * Figure out the block that contains the symbols
     334:  * in the given variable expression.
     335:  */
     336:
     337: LOCAL SYM *tcontainer(var)
     338: NODE *var;
     339: {
     340:     NODE *p;
     341:
     342:     p = var;
     343:     while (p->op != O_NAME) {
     344:         if (isleaf(p->op)) {
     345:             panic("unexpected op %d in tcontainer", p->op);
     346:             /* NOTREACHED */
     347:         }
     348:         p = p->left;
     349:     }
     350:     return container(p->nameval);
     351: }

#### Defined functions

stop defined in line 239; used 1 times

- in /usr/src/ucb/PORT/pascal/pdx/tree/eval.c line 434

stopinst defined in line 277; used 1 times

- in line 270

stopvar defined in line 306; used 1 times

- in line 249

tcontainer defined in line 337; used 2 times

- in line 26, 211

trace defined in line 33; used 1 times

- in /usr/src/ucb/PORT/pascal/pdx/tree/eval.c line 426

traceall defined in line 67; used 1 times

- in line 40

traceat defined in line 162; used 1 times

- in line 44

tracedata defined in line 199; used 1 times

- in line 46

traceinst defined in line 121; used 1 times

- in line 42

#### Defined variables

sccsid defined in line 8; never used

Last modified: 1985-06-07 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1139 |