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

📄 events.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
/*@(#)events.c	4.2	Ultrix	11/9/90*//************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//************************************************************************ *									* *			Modification History				* *									* *  005	- Added support for vectors.							* *		  (L Miller, 18JAN90)									* *									* *	004 - Merged in 4.3 changes.					* *	      (vjh, April 29, 1986)					* *									* *	003 - Fixed *many* bugs/problems in trace (search for 003).	* *	      (vjh, July 23, 1985)					* *									* *	002 - Updated all calls to findlanguage() to call with		* *	      LanguageName constant, rather than with a filename	* *	      suffix.							* *	      (vjh, June 22, 1985)					* *									* *	001 - Added routine delallevents() for use with the		* *	      "delete *" command.					* *	      (Victoria Holt, April 25, 1985)				* *									* ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved.  The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)events.c	5.1 (Berkeley) 5/31/85";#endif not lintstatic char rcsid[] = "$Header: events.c,v 1.5 84/12/26 10:39:26 linton Exp $";/* * Event/breakpoint managment. */#include "defs.h"#include "events.h"#include "languages.h"#include "main.h"#include "symbols.h"#include "tree.h"#include "eval.h"#include "source.h"#include "mappings.h"#include "runtime.h"#include "process.h"#include "machine.h"#include "lists.h"#ifndef publictypedef struct Event *Event;typedef struct Breakpoint *Breakpoint;Boolean inst_tracing;Boolean single_stepping;Boolean isstopped;#include "symbols.h"Symbol linesym;Symbol procsym;Symbol pcsym;Symbol retaddrsym;#define addevent(cond, cmdlist) event_alloc(false, cond, cmdlist)#define event_once(cond, cmdlist) event_alloc(true, cond, cmdlist)#endifstruct Event {    unsigned int id;    Boolean temporary;    Node condition;    Cmdlist actions;};struct Breakpoint {    Event event;    Address bpaddr;	    Lineno bpline;    Cmdlist actions;    Boolean temporary;};typedef List Eventlist;typedef List Bplist;#define eventlist_append(event, el) list_append(list_item(event), nil, el)#define bplist_append(bp, bl) list_append(list_item(bp), nil, bl)private Eventlist eventlist;		/* list of active events */private Bplist bplist;			/* list of active breakpoints */private Event curevent;			/* most recently created event */private integer eventid;		/* id number of current event */private integer trid;			/* id number of current trace */typedef struct Trcmd {    Integer trid;    Event event;    Cmdlist cmdlist;} *Trcmd;private List eachline;		/* commands to execute after each line */private List eachinst;		/* commands to execute after each instruction */private Breakpoint bp_alloc();/* * Initialize breakpoint information. */private Symbol builtinsym(str, class, type)String str;Symclass class;Symbol type;{    Symbol s;    s = insert(identname(str, true));    s->language = findlanguage(ASSEMBLER);    s->class = class;    s->type = type;    return s;}public bpinit(flag)Boolean flag;{    linesym = builtinsym("$line", VAR, t_int);    procsym = builtinsym("$proc", PROC, nil);    pcsym = lookup(identname("$pc", true));    if (pcsym == nil) {	panic("can't find $pc");    }    retaddrsym = builtinsym("$retaddr", VAR, t_int);	if(!flag) {    	eventlist = list_alloc();    	bplist = list_alloc();    	eachline = list_alloc();    	eachinst = list_alloc();	}}/* Allocates a new event.  Adds the event to the eventlist.  Traps the * event (in translate()); when this trap is encountered, the commands * in cmdlist will be executed. * * "curevent" must be assigned the new event before calling translate() * in case translate() calls evalcmdlist() with the new event. * This is part of a fix for the "missing trid" panic.  (003 - vjh) */public Event event_alloc(istmp, econd, cmdlist)boolean istmp;Node econd;Cmdlist cmdlist;{    register Event e;    e = new(Event);    ++eventid;    e->id = eventid;    e->temporary = istmp;    e->condition = econd;    e->actions = cmdlist;    eventlist_append(e, eventlist);    curevent = e;    translate(e);    return e;}/* Routine to indiscriminately remove all break/tracepoints. * Since this routine is invoked by the user (with delete *),  * it only removes user defined eventpoints (ie. leaves temporaries). * Used to remove all of them, which would cause "program unexpecdly * exited" message (breakpoint on _exit() was deleted; see resume() in * process.c).  (003 - vjh) */public boolean delallevents(){    Event e;    Breakpoint bp;    Trcmd t;    foreach (Event, e, eventlist)        if (not e->temporary) {	    foreach (Breakpoint, bp, bplist)	        if (bp->event == e) {		    if (tracebpts) {		        printf("deleting breakpoint at 0x%x\n", bp->bpaddr);		        fflush(stdout);		    }		    list_delete(list_curitem(bplist), bplist);	        }	    endfor	    list_delete(list_curitem(eventlist), eventlist);	}    endfor    foreach (Trcmd, t, eachline)	printrmtr(t);	list_delete(list_curitem(eachline), eachline);    endfor    foreach (Trcmd, t, eachinst)        printrmtr(t);	list_delete(list_curitem(eachinst), eachinst);    endfor    if (list_size(eachinst) == 0) {	inst_tracing = false;	if (list_size(eachline) == 0) {	    single_stepping = false;	}    }}/* * Delete the event with the given id. * Returns whether it's successful or not. */public boolean delevent(id)unsigned int id;{    Event e;    Breakpoint bp;    Trcmd t;    boolean found;    found = false;    foreach (Event, e, eventlist)	if (e->id == id) {	    found = true;	    foreach (Breakpoint, bp, bplist)		if (bp->event == e) {		    if (tracebpts) {			printf("deleting breakpoint at 0x%x\n", bp->bpaddr);			fflush(stdout);		    }		    list_delete(list_curitem(bplist), bplist);		}	    endfor	    list_delete(list_curitem(eventlist), eventlist);	    break;	}    endfor    foreach (Trcmd, t, eachline)	if (t->event->id == id) {	    found = true;	    printrmtr(t);	    list_delete(list_curitem(eachline), eachline);	}    endfor    foreach (Trcmd, t, eachinst)	if (t->event->id == id) {	    found = true;	    printrmtr(t);	    list_delete(list_curitem(eachinst), eachinst);	}    endfor    if (list_size(eachinst) == 0) {	inst_tracing = false;	if (list_size(eachline) == 0) {	    single_stepping = false;	}    }    return found;}/* Translate an event into the appropriate breakpoints and actions. * While we're at it, turn on the breakpoints if the condition is true. * Added a check for presence of a coredump, so that condition doesn't * appear to be true when it really isn't (ie. reading corefile sets * pc to be routine in which the program died; could be Symbol s). * (003 - vjh) */private translate(e)Event e;{    Breakpoint bp;    Symbol s;    Node place;    Lineno line;    Address addr;    checkref(e->condition);    switch (e->condition->op) {	case O_EQ:	    if (e->condition->value.arg[0]->op == O_SYM) {			s = e->condition->value.arg[0]->value.sym;			place = e->condition->value.arg[1];			if (s == linesym) {		    	if (place->op == O_QLINE) {					line = place->value.arg[1]->value.lcon;					addr = objaddr(line, place->value.arg[0]->value.scon);		    	} else {					eval(place);					line = pop(long);					addr = objaddr(line, cursource);		    	}		    	if (addr == NOADDR || addr == ADDRNOEXEC) {					if (not delevent(e->id)) {			    		printf("!! dbx.translate: can't undo event %d?\n",																		e->id);					}					beginerrmsg();					if (addr == NOADDR)		    			fprintf(stderr, "beyond end of file at line ");					else						fprintf(stderr, "no executable code found at line ");					prtree(stderr, place);					enderrmsg();		    	}		    	bp = bp_alloc(e, addr, line, e->actions);			} else if (s == procsym) {		    	eval(place);		    	s = pop(Symbol);		    	bp = bp_alloc(e, codeloc(s), 0, e->actions);		    	if ((not coredump) and isactive(s)  /* (003 - vjh) */		    								and pc != codeloc(program)) {					evalcmdlist(bp->actions);		    	}			} else if (s == pcsym) {		    	eval(place);		    	bp = bp_alloc(e, pop(Address), 0, e->actions);			} else {		    	condbp(e);			}	    } else {			condbp(e);	    }	    break;	/*	 * These should be handled specially.	 * But for now I'm ignoring the problem.	 */	case O_AND:	case O_OR:	default:	    condbp(e);	    break;    }}/* * Create a breakpoint for a condition that cannot be pinpointed * to happening at a particular address, but one for which we * must single step and check the condition after each statement. */private condbp(e)Event e;{    Symbol p;    Breakpoint bp;    Cmdlist actions;    p = tcontainer(e->condition);    if (p == nil) {	p = program;    }    actions = buildcmdlist(build(O_IF, e->condition, e->actions));    actions = buildcmdlist(build(O_TRACEON, false, actions));    bp = bp_alloc(e, codeloc(p), 0, actions);}/* * Determine the deepest nested subprogram that still contains * all elements in the given expression. */public Symbol tcontainer(exp)Node exp;{    Integer i;    Symbol s, t, u, v;    checkref(exp);    s = nil;    if (exp->op == O_SYM) {	s = container(exp->value.sym);    } else if (not isleaf(exp->op)) {	for (i = 0; i < nargs(exp->op); i++) {	    t = tcontainer(exp->value.arg[i]);	    if (t != nil) {		if (s == nil) {		    s = t;		} else {		    u = s;		    v = t;		    while (u != v and u != nil) {			u = container(u);			v = container(v);		    }		    if (u == nil) {			panic("bad ancestry for \"%s\"", symname(s));		    } else {			s = u;		    }		}	    }	}    }    return s;}/* * Determine if the given function can be executed at full speed. * This can only be done if there are no breakpoints within the function. */public Boolean canskip(f)Symbol f;{    Breakpoint p;    Boolean ok;    ok = true;    foreach (Breakpoint, p, bplist)        if (whatblock(p->bpaddr) == f) {	    ok = false;	    break;	}    endfor    return ok;}/* * Print out what's currently being traced by looking at * the currently active events. * * Some convolution here to translate internal representation * of events back into something more palatable. */public status(){    Event e;	if(vectorcapable) {		fprintf(stderr, "machine is currently vector capable\n");	}	else {		fprintf(stderr, "machine is currently NOT vector capable\n");	}	is_vector_capable();    foreach (Event, e, eventlist)	if (not e->temporary) {	    printevent(e);	}    endfor}public printevent(e)Event e;{    Command cmd;    if (not isredirected()) {	printeventid(e->id);    }    cmd = list_element(Command, list_head(e->actions));    if (cmd->op == O_PRINTCALL) {	printf("trace ");	printname(stdout, cmd->value.sym);    } else {	if (list_size(e->actions) > 1) {	    printf("{ ");	}	foreach (Command, cmd, e->actions)	    printcmd(stdout, cmd);	    if (not list_islast()) {		printf("; ");	    }	endfor	if (list_size(e->actions) > 1) {	    printf(" }");	}	printcond(e->condition);    }    printf("\n");}private printeventid (id)integer id;{    printf("[%d] ", id);}/* * Print out a condition. */private printcond(cond)Node cond;{    Symbol s;    Node place;    if (cond->op == O_EQ and cond->value.arg[0]->op == O_SYM) {	s = cond->value.arg[0]->value.sym;	place = cond->value.arg[1];	if (s == procsym) {	    if (place->value.sym != program) {		printf(" in ");		printname(stdout, place->value.sym);	    }	} else if (s == linesym) {	    printf(" at ");	    prtree(stdout, place);	} else if (s == pcsym or s == retaddrsym) {	    printf(" i at ");	    prtree(stdout, place);	} else {	    printf(" when ");	    prtree(stdout, cond);	}    } else {	printf(" when ");	prtree(stdout, cond);    }}/* * Add a breakpoint to the breakpoint list, and return it. */private Breakpoint bp_alloc(e, addr, line, actions)Event e;Address addr;Lineno line;Cmdlist actions;

⌨️ 快捷键说明

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