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[] = "@(#)bpact.c	5.1 (Berkeley) 6/5/85";
   9: #endif not lint
  10: /*
  11:  * Routines for doing the right thing when a breakpoint is reached.
  12:  */
  13: 
  14: #include "defs.h"
  15: #include "breakpoint.h"
  16: #include "sym.h"
  17: #include "tree.h"
  18: #include "source.h"
  19: #include "mappings.h"
  20: #include "runtime.h"
  21: #include "process.h"
  22: #include "machine.h"
  23: #include "main.h"
  24: #include "bp.rep"
  25: #include "tree/tree.rep"
  26: 
  27: typedef enum { SAVE, NOSAVE } SAVEBP;
  28: 
  29: LOCAL SAVEBP handlebp();
  30: 
  31: /*
  32:  * A "delayed" breakpoint is one that has an action involving execution
  33:  * of code, e.g. at a CALL we want to step from the beginning of the
  34:  * procedure to the first line before printing parameters.
  35:  */
  36: 
  37: LOCAL short delayed;
  38: 
  39: #define NONE 0
  40: #define DELAY_CALL 1
  41: #define DELAY_STOP 2
  42: 
  43: /*
  44:  * Take action at a breakpoint; if it's not a breakpoint return FALSE.
  45:  *
  46:  * As we go through the list of breakpoints, we have to remember
  47:  * the previous one so that "handlebp" can delete breakpoints on
  48:  * the fly if necessary.
  49:  *
  50:  * If the breakpoint is a STOP_BP, handlebp will set "isstopped".  After
  51:  * going through the loop, bpact checks if "isstopped" is set and calls
  52:  * printstatus if it is.  This is so multiple breakpoints at the same
  53:  * address, one of which is a STOP_BP, still work.
  54:  */
  55: 
  56: #define isswitch(bptype) ( \
  57:     bptype == ALL_ON || bptype == ALL_OFF || \
  58:     bptype == TERM_ON || bptype == TERM_OFF || \
  59:     bptype == BLOCK_ON || bptype == BLOCK_OFF || \
  60:     bptype == STOP_ON || bptype == STOP_OFF \
  61: )
  62: 
  63: BOOLEAN bpact()
  64: {
  65:     register BPINFO *p;
  66:     BPINFO *prev, *next;
  67:     BOOLEAN found;
  68:     ADDRESS oldpc;
  69: 
  70:     delayed = NONE;
  71:     found = FALSE;
  72:     prev = NIL;
  73:     for (p = bphead; p != NIL; p = next) {
  74:         next = p->bpnext;
  75:         if (p->bpaddr == pc) {
  76:             prbpfound(p);
  77:             found = TRUE;
  78:             if (p->bpcond == NIL || isswitch(p->bptype) || cond(p->bpcond)) {
  79:                 prbphandled();
  80:                 if (handlebp(p) == NOSAVE) {
  81:                     prbpnosave();
  82:                     if (prev == NIL) {
  83:                         bphead = next;
  84:                     } else {
  85:                         prev->bpnext = next;
  86:                     }
  87:                     dispose(p);
  88:                 } else {
  89:                     prbpsave();
  90:                     prev = p;
  91:                 }
  92:             } else {
  93:                 prev = p;
  94:             }
  95:         } else {
  96:             prev = p;
  97:         }
  98:     }
  99:     if (delayed != NONE) {
 100:         oldpc = pc;
 101:         runtofirst();
 102:         if ((delayed&DELAY_CALL) == DELAY_CALL) {
 103:             SYM *s, *t;
 104: 
 105:             s = curfunc;
 106:             t = whatblock(return_addr());
 107:             if (t == NIL) {
 108:                 panic("can't find block for caller addr %d", caller_addr());
 109:             }
 110:             printcall(s, t);
 111:             addbp(return_addr(), RETURN, s, NIL, NIL, 0);
 112:         }
 113:         if (pc != oldpc) {
 114:             bpact();
 115:         }
 116:         if (isstopped) {
 117:             printstatus();
 118:         }
 119:     } else {
 120:         if (isstopped) {
 121:             printstatus();
 122:         }
 123:     }
 124:     fflush(stdout);
 125:     return(found);
 126: }
 127: 
 128: /*
 129:  * Handle an expected breakpoint appropriately, return whether
 130:  * or not to save the breakpoint.
 131:  */
 132: 
 133: LOCAL SAVEBP handlebp(p)
 134: BPINFO *p;
 135: {
 136:     register SYM *s, *t;
 137:     SAVEBP r;
 138: 
 139:     r = SAVE;
 140:     switch(p->bptype) {
 141:         case ALL_ON:
 142:             curfunc = p->bpblock;
 143:             addcond(TRPRINT, p->bpcond);
 144:             if (p->bpline >= 0) {
 145:                 tracing++;
 146:             } else {
 147:                 inst_tracing++;
 148:             }
 149:             addbp(return_addr(), ALL_OFF, curfunc, p->bpcond, NIL, 0);
 150:             break;
 151: 
 152:         case ALL_OFF:
 153:             r = NOSAVE;
 154:             if (p->bpline >= 0) {
 155:                 tracing--;
 156:             } else {
 157:                 inst_tracing--;
 158:             }
 159:             delcond(TRPRINT, p->bpcond);
 160:             curfunc = p->bpblock;
 161:             break;
 162: 
 163:         case STOP_ON:
 164:             var_tracing++;
 165:             curfunc = p->bpblock;
 166:             if (p->bpnode != NIL) {
 167:                 addvar(TRSTOP, p->bpnode, p->bpcond);
 168:             } else if (p->bpcond != NIL) {
 169:                 addcond(TRSTOP, p->bpcond);
 170:             }
 171:             addbp(return_addr(), STOP_OFF, curfunc, p->bpcond, p->bpnode, 0);
 172:             break;
 173: 
 174:         case STOP_OFF:
 175:             r = NOSAVE;
 176:             delcond(TRSTOP, p->bpcond);
 177:             var_tracing--;
 178:             curfunc = p->bpblock;
 179:             break;
 180: 
 181:         case INST:
 182:             curline = p->bpline;
 183:             if (curline > 0) {
 184:                 printf("trace:  ");
 185:                 printlines(curline, curline);
 186:             } else {
 187:                 printf("inst trace:	");
 188:                 printinst(pc, pc);
 189:             }
 190:             break;
 191: 
 192:         case STOP_BP:
 193:             if (p->bpblock != NIL) {
 194:                 delayed |= DELAY_STOP;
 195:                 curfunc = p->bpblock;
 196:             }
 197:             curline = p->bpline;
 198:             isstopped = TRUE;
 199:             break;
 200: 
 201:         case BLOCK_ON: {
 202:             BPINFO *nbp;
 203: 
 204:             s = p->bpblock;
 205:             t = p->bpnode->nameval;
 206:             nbp = newbp(codeloc(t), CALL, t, p->bpcond, NIL, 0);
 207:             addbp(return_addr(), BLOCK_OFF, (SYM *) nbp, NIL, NIL, 0);
 208:             break;
 209:         }
 210: 
 211:         case BLOCK_OFF: {
 212:             BPINFO *oldbp;
 213: 
 214:             r = NOSAVE;
 215:             oldbp = (BPINFO *) p->bpblock;
 216:             delbp(oldbp->bpid);
 217:             break;
 218:         }
 219: 
 220:         case CALL:
 221:             delayed |= DELAY_CALL;
 222:             curfunc = p->bpblock;
 223:             break;
 224: 
 225:         case RETURN:
 226:             r = NOSAVE;
 227:             s = p->bpblock;
 228:             printrtn(s);
 229:             break;
 230: 
 231:         case TERM_ON: {
 232:             ADDRESS addr;
 233: 
 234:             curfunc = p->bpblock;
 235:             addvar(TRPRINT, p->bpnode, p->bpcond);
 236:             addr = return_addr();
 237:             addbp(addr, TERM_OFF, curfunc, p->bpcond, p->bpnode, 0);
 238:             var_tracing++;
 239:             break;
 240:         }
 241: 
 242:         case TERM_OFF:
 243:             r = NOSAVE;
 244:             var_tracing--;
 245:             delvar(TRPRINT, p->bpnode, p->bpcond);
 246:             curfunc = p->bpblock;
 247:             break;
 248: 
 249:         case AT_BP:
 250:             printf("at line %d: ", p->bpline);
 251:             eval(p->bpnode);
 252:             prtree(p->bpnode);
 253:             printf(" = ");
 254:             printval(p->bpnode->nodetype);
 255:             putchar('\n');
 256:             break;
 257: 
 258:         /*
 259: 		 * Returning from a called procedure.
 260: 		 * Further breakpoint processing is not done, since if
 261: 		 * there were any it wouldn't be associated with the call.
 262: 		 */
 263:         case CALLPROC:
 264:             procreturn(p->bpblock);
 265:             delbp(p->bpid);
 266:             erecover();
 267:             /* NOTREACHED */
 268: 
 269:         case END_BP:
 270:             r = NOSAVE;
 271:             endprogram();
 272: 
 273:         default:
 274:             panic("unknown bptype %d in cont", p->bptype);
 275:             /* NOTREACHED */
 276:     }
 277:     return(r);
 278: }
 279: 
 280: /*
 281:  * Internal trace routines.
 282:  */
 283: 
 284: LOCAL char *prbptype[] ={
 285:     "ALL_ON", "ALL_OFF", "INST", "CALL", "RETURN", "BLOCK_ON", "BLOCK_OFF",
 286:     "TERM_ON", "TERM_OFF", "AT_BP", "STOP_BP", "CALLPROC", "END_BP",
 287:     "STOP_ON", "STOP_OFF",
 288: };
 289: 
 290: LOCAL prbpfound(p)
 291: BPINFO *p;
 292: {
 293:     if (option('b')) {
 294:         printf("%s breakpoint found at pc %d, line %d -- ",
 295:             prbptype[(int) p->bptype], p->bpaddr, p->bpline);
 296:     }
 297: }
 298: 
 299: LOCAL prbphandled()
 300: {
 301:     if (option('b')) {
 302:         printf("handled, ");
 303:     }
 304: }
 305: 
 306: LOCAL prbpnosave()
 307: {
 308:     if (option('b')) {
 309:         printf("not saved\n");
 310:         fflush(stdout);
 311:     }
 312: }
 313: 
 314: LOCAL prbpsave()
 315: {
 316:     if (option('b')) {
 317:         printf("saved\n");
 318:         fflush(stdout);
 319:     }
 320: }

Defined functions

bpact defined in line 63; used 2 times
handlebp defined in line 133; used 2 times
prbpfound defined in line 290; used 1 times
  • in line 76
prbphandled defined in line 299; used 1 times
  • in line 79
prbpnosave defined in line 306; used 1 times
  • in line 81
prbpsave defined in line 314; used 1 times
  • in line 89

Defined variables

delayed defined in line 37; used 5 times
prbptype defined in line 284; used 1 times
sccsid defined in line 8; never used

Defined macros

DELAY_CALL defined in line 40; used 3 times
DELAY_STOP defined in line 41; used 1 times
NONE defined in line 39; used 2 times
isswitch defined in line 56; used 1 times
  • in line 78
Last modified: 1985-06-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1700
Valid CSS Valid XHTML 1.0 Strict