⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpact.c

📁 早期freebsd实现
💻 C
字号:
/*- * Copyright (c) 1980, 1993 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char sccsid[] = "@(#)bpact.c	8.1 (Berkeley) 6/6/93";#endif /* not lint *//* * Routines for doing the right thing when a breakpoint is reached. */#include "defs.h"#include "breakpoint.h"#include "sym.h"#include "tree.h"#include "source.h"#include "mappings.h"#include "runtime.h"#include "process.h"#include "machine.h"#include "main.h"#include "bp.rep"#include "tree/tree.rep"typedef enum { SAVE, NOSAVE } SAVEBP;LOCAL SAVEBP handlebp();/* * 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. */LOCAL short delayed;#define NONE 0#define DELAY_CALL 1#define DELAY_STOP 2/* * 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 * the fly if necessary. * * 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 \)BOOLEAN bpact(){	register BPINFO *p;	BPINFO *prev, *next;	BOOLEAN found;	ADDRESS oldpc;	delayed = NONE;	found = FALSE;	prev = NIL;	for (p = bphead; p != NIL; p = next) {		next = p->bpnext;		if (p->bpaddr == pc) {			prbpfound(p);			found = TRUE;			if (p->bpcond == NIL || isswitch(p->bptype) || cond(p->bpcond)) {				prbphandled();				if (handlebp(p) == NOSAVE) {					prbpnosave();					if (prev == NIL) {						bphead = next;					} else {						prev->bpnext = next;					}					dispose(p);				} else {					prbpsave();					prev = p;				}			} else {				prev = p;			}		} else {			prev = p;		}	}	if (delayed != NONE) {		oldpc = pc;		runtofirst();		if ((delayed&DELAY_CALL) == DELAY_CALL) {			SYM *s, *t;			s = curfunc;			t = whatblock(return_addr());			if (t == NIL) {				panic("can't find block for caller addr %d", caller_addr());			}			printcall(s, t);			addbp(return_addr(), RETURN, s, NIL, NIL, 0);		}		if (pc != oldpc) {			bpact();		}		if (isstopped) {			printstatus();		}	} else {		if (isstopped) {			printstatus();		}	}	fflush(stdout);	return(found);}/* * Handle an expected breakpoint appropriately, return whether * or not to save the breakpoint. */LOCAL SAVEBP handlebp(p)BPINFO *p;{	register SYM *s, *t;	SAVEBP r;	r = SAVE;	switch(p->bptype) {		case ALL_ON:			curfunc = p->bpblock;			addcond(TRPRINT, p->bpcond);			if (p->bpline >= 0) {				tracing++;			} else {				inst_tracing++;			}			addbp(return_addr(), ALL_OFF, curfunc, p->bpcond, NIL, 0);			break;		case ALL_OFF:			r = NOSAVE;			if (p->bpline >= 0) {				tracing--;			} else {				inst_tracing--;			}			delcond(TRPRINT, p->bpcond);			curfunc = p->bpblock;			break;		case STOP_ON:			var_tracing++;			curfunc = p->bpblock;			if (p->bpnode != NIL) {				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);			break;		case STOP_OFF:			r = NOSAVE;			delcond(TRSTOP, p->bpcond);			var_tracing--;			curfunc = p->bpblock;			break;		case INST:			curline = p->bpline;			if (curline > 0) {				printf("trace:  ");				printlines(curline, curline);			} else {				printf("inst trace:	");				printinst(pc, pc);			}			break;		case STOP_BP:			if (p->bpblock != NIL) {				delayed |= DELAY_STOP;				curfunc = p->bpblock;			}			curline = p->bpline;			isstopped = TRUE;			break;		case BLOCK_ON: {			BPINFO *nbp;			s = p->bpblock;			t = p->bpnode->nameval;			nbp = newbp(codeloc(t), CALL, t, p->bpcond, NIL, 0);			addbp(return_addr(), BLOCK_OFF, (SYM *) nbp, NIL, NIL, 0);			break;		}		case BLOCK_OFF: {			BPINFO *oldbp;			r = NOSAVE;			oldbp = (BPINFO *) p->bpblock;			delbp(oldbp->bpid);			break;		}		case CALL:			delayed |= DELAY_CALL;			curfunc = p->bpblock;			break;		case RETURN:			r = NOSAVE;			s = p->bpblock;			printrtn(s);			break;		case TERM_ON: {			ADDRESS addr;			curfunc = p->bpblock;			addvar(TRPRINT, p->bpnode, p->bpcond);			addr = return_addr();			addbp(addr, TERM_OFF, curfunc, p->bpcond, p->bpnode, 0);			var_tracing++;			break;		}		case TERM_OFF:			r = NOSAVE;			var_tracing--;			delvar(TRPRINT, p->bpnode, p->bpcond);			curfunc = p->bpblock;			break;		case AT_BP:			printf("at line %d: ", p->bpline);			eval(p->bpnode);			prtree(p->bpnode);			printf(" = ");			printval(p->bpnode->nodetype);			putchar('\n');			break;		/*		 * Returning from a called procedure.		 * Further breakpoint processing is not done, since if		 * there were any it wouldn't be associated with the call.		 */		case CALLPROC:			procreturn(p->bpblock);			delbp(p->bpid);			erecover();			/* NOTREACHED */		case END_BP:			r = NOSAVE;			endprogram();		default:			panic("unknown bptype %d in cont", p->bptype);			/* NOTREACHED */	}	return(r);}/* * 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",	"STOP_ON", "STOP_OFF",};LOCAL prbpfound(p)BPINFO *p;{	if (option('b')) {		printf("%s breakpoint found at pc %d, line %d -- ",			prbptype[(int) p->bptype], p->bpaddr, p->bpline);	}}LOCAL prbphandled(){	if (option('b')) {		printf("handled, ");	}}LOCAL prbpnosave(){	if (option('b')) {		printf("not saved\n");		fflush(stdout);	}}LOCAL prbpsave(){	if (option('b')) {		printf("saved\n");		fflush(stdout);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -