* Copyright (c) 1980 The Regents of the University of California.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)bpact.c 5.2 (Berkeley) %G%";
* Routines for doing the right thing when a breakpoint is reached.
typedef enum { SAVE
, NOSAVE
} SAVEBP
;
* A "delayed" breakpoint is one that has an action involving execution
* of code, e.g. at a CALL we want to step from the beginning of the
* procedure to the first line before printing parameters.
* Take action at a breakpoint; if it's not a breakpoint return FALSE.
* As we go through the list of breakpoints, we have to remember
* the previous one so that "handlebp" can delete breakpoints on
* If the breakpoint is a STOP_BP, handlebp will set "isstopped". After
* going through the loop, bpact checks if "isstopped" is set and calls
* printstatus if it is. This is so multiple breakpoints at the same
* address, one of which is a STOP_BP, still work.
#define isswitch(bptype) ( \
bptype == ALL_ON || bptype == ALL_OFF || \
bptype == TERM_ON || bptype == TERM_OFF || \
bptype == BLOCK_ON || bptype == BLOCK_OFF || \
bptype == STOP_ON || bptype == STOP_OFF \
for (p
= bphead
; p
!= NIL
; p
= next
) {
if (p
->bpcond
== NIL
|| isswitch(p
->bptype
) || cond(p
->bpcond
)) {
if (handlebp(p
) == NOSAVE
) {
if ((delayed
&DELAY_CALL
) == DELAY_CALL
) {
t
= whatblock(return_addr());
panic("can't find block for caller addr %d", caller_addr());
addbp(return_addr(), RETURN
, s
, NIL
, NIL
, 0);
* Handle an expected breakpoint appropriately, return whether
* or not to save the breakpoint.
addcond(TRPRINT
, p
->bpcond
);
addbp(return_addr(), ALL_OFF
, curfunc
, p
->bpcond
, NIL
, 0);
delcond(TRPRINT
, p
->bpcond
);
addvar(TRSTOP
, p
->bpnode
, p
->bpcond
);
} else if (p
->bpcond
!= NIL
) {
addcond(TRSTOP
, p
->bpcond
);
addbp(return_addr(), STOP_OFF
, curfunc
, p
->bpcond
, p
->bpnode
, 0);
delcond(TRSTOP
, p
->bpcond
);
printlines(curline
, curline
);
nbp
= newbp(codeloc(t
), CALL
, t
, p
->bpcond
, NIL
, 0);
addbp(return_addr(), BLOCK_OFF
, (SYM
*) nbp
, NIL
, NIL
, 0);
oldbp
= (BPINFO
*) p
->bpblock
;
addvar(TRPRINT
, p
->bpnode
, p
->bpcond
);
addbp(addr
, TERM_OFF
, curfunc
, p
->bpcond
, p
->bpnode
, 0);
delvar(TRPRINT
, p
->bpnode
, p
->bpcond
);
printf("at line %d: ", p
->bpline
);
printval(p
->bpnode
->nodetype
);
* Returning from a called procedure.
* Further breakpoint processing is not done, since if
* there were any it wouldn't be associated with the call.
panic("unknown bptype %d in cont", p
->bptype
);
* Internal trace routines.
LOCAL
char *prbptype
[] ={
"ALL_ON", "ALL_OFF", "INST", "CALL", "RETURN", "BLOCK_ON", "BLOCK_OFF",
"TERM_ON", "TERM_OFF", "AT_BP", "STOP_BP", "CALLPROC", "END_BP",
printf("%s breakpoint found at pc %d, line %d -- ",
prbptype
[(int) p
->bptype
], p
->bpaddr
, p
->bpline
);