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

📄 events.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
{    register Breakpoint p;    p = new(Breakpoint);    p->event = e;    p->bpaddr = addr;    p->bpline = line;    p->actions = actions;    p->temporary = false;    if (tracebpts) {	if (e == nil) {	    printf("new bp at 0x%x for event ??\n", addr, e->id);	} else {	printf("new bp at 0x%x for event %d\n", addr, e->id);	}	fflush(stdout);    }    bplist_append(p, bplist);    return p;}/* * Free all storage in the event and breakpoint tables. */public bpfree(){    register Event e;    fixbps();    foreach (Event, e, eventlist)	if (not delevent(e->id)) {	    printf("!! dbx.bpfree: can't delete event %d\n", e->id);	}	list_delete(list_curitem(eventlist), eventlist);    endfor}/* * Determine if the program stopped at a known breakpoint * and if so do the associated commands. */public boolean bpact(){    register Breakpoint p;    Boolean found;    integer eventId;    found = false;    foreach (Breakpoint, p, bplist)	if (p->bpaddr == pc) {	    if (tracebpts) {		printf("breakpoint for event %d found at location 0x%x\n",		    p->event->id, pc);	    }	    found = true;	    if (p->event->temporary) {		if (not delevent(p->event->id)) {		    printf("!! dbx.bpact: can't find event %d\n",			p->event->id);		}	    }	    /* See if this breakpoint is associated with a trace event	     * that has just completed (eg. see traceoff() ).  If so,	     * delete the associated breakpoint.  (Didn't do this before -	     * main source of "missing trid" panic:  breakpoint would be	     * encountered again, but the trcmd associated with it had	     * been deleted in traceoff() ).	     */	    if (p->temporary) {		list_delete(list_curitem(bplist), bplist);		} else {	    evalcmdlist(p->actions);	    if (isstopped) {		eventId = p->event->id;	    }		}	}    endfor    if (isstopped) {	if (found) {	    printeventid(eventId);	}	printstatus();    }    fflush(stdout);    return found;}/* Sets up a single step context (ie.  global single_stepping = true). * As long as this is true, dbx will step by source line * (instruction if first arg. is true) until traceoff() is called. * If tracing by source line, the commands that are to be executed * after each line are appended to eachline.  Otherwise, they are * appended to eachinst list.  After stepping each line, printnews() is * called, and the commands in eachline (eachinst) are executed. * * A breakpoint is set at the end of the current procedure to  * automatically turn off the given tracing with traceoff(). */public traceon(inst, event, cmdlist)Boolean inst;Event event;Cmdlist cmdlist;{    register Trcmd trcmd;    Breakpoint bp;    Cmdlist actions;    Address ret;    Event e;    if (event == nil) {	e = curevent;    } else {	e = event;    }    trcmd = new(Trcmd);    ++trid;    trcmd->trid = trid;    trcmd->event = e;    trcmd->cmdlist = cmdlist;    single_stepping = true;    if (inst) {	inst_tracing = true;	list_append(list_item(trcmd), nil, eachinst);    } else {	list_append(list_item(trcmd), nil, eachline);    }    ret = return_addr();    if (ret != 0) {  /* ret is 0 if tracing entire program. */	actions = buildcmdlist(build(O_TRACEOFF, trcmd->trid));	bp = bp_alloc(e, (Address) ret, 0, actions);	bp->temporary = true;    }    if (tracebpts) {	printf("adding trace %d for event %d\n", trcmd->trid, e->id);    }}/* Turn off some kind of tracing. * Strictly an internal command, this cannot be invoked by the user. * First search for and remove the commands listed in eachline (or * eachinst) that are associated with this trid.  If trid not found, * panic. *	  >>> Next, REMOVE THE BREAKPOINT ASSOCIATED WITH THE  * 	  >>> EVENT:  This is now done in bpact(). * Finally, reset inst_tracing and single_stepping flags when there is * no more inst/line tracing in effect. * * Note - this does not delete the event itself, only the trace * associated with the event.  In this way, if the user says "run" * again, the trace corresponding to this event will be reconstructed. */public traceoff(id)Integer id;{    register Trcmd t;    register Boolean found;    register Event e;    register Breakpoint bp;    found = false;    foreach (Trcmd, t, eachline)	if (t->trid == id) {	    printrmtr(t);	    list_delete(list_curitem(eachline), eachline);	    found = true;	    break;	}    endfor    if (not found) {	foreach (Trcmd, t, eachinst)	    if (t->trid == id) {		printrmtr(t);		list_delete(list_curitem(eachinst), eachinst);		found = true;		break;	    }	endfor	if (not found) {	    beginerrmsg();	    fprintf(stderr, "[internal error: trace id %d not found]\n", id);	}    }    /* Delete associated breakpoints.  This is now done in bpact(),     * by making use of the "temporary" field in the Breakpoint struct.     *    foreach (Event, e, eventlist)        if (t->event->id == e->id) {	    foreach (Breakpoint, bp, bplist)	        if (bp->event == e and bp->bpaddr == pc) {		    if (tracebpts) {		        printf("deleting breakpoint at 0x%x", bp->bpaddr);			printf(" associated with event %d\n", e->id);			fflush(stdout);		    }		    list_delete(list_curitem(bplist), bplist);		}	    endfor	}    endfor    */    /* Reset flags if no more inst/line tracing in effect. */    if (list_size(eachinst) == 0) {	inst_tracing = false;	if (list_size(eachline) == 0) {	    single_stepping = false;	}    }}/* * If breakpoints are being traced, note that a Trcmd is being deleted. */private printrmtr(t)Trcmd t;{    if (tracebpts) {	printf("removing trace %d", t->trid);	if (t->event != nil) {	    printf(" for event %d", t->event->id);    }	printf("\n");    }}/* Print out news during single step tracing. * This routine has a pretty bad hack in it.  Because each trace is * stored and maintained independently from any other, one trace cannot * be aware of what another is doing.  This is expecially evident in * recursive routines.  Traceon() is called repeatedly each time the * start address of the routine is encountered (where there is a bkpt * associated with the event).  Traceon() will add the same command(s) * to the eachline list at each invocation of the routine (eg.  * O_PRINTSRCPOS).  The case statement in this routine prevents a * source line from being displayed as many times as the routine has * called itself.  (003 - vjh) */public printnews(){    register Trcmd t;    register Command cmd;    register Boolean noprint;    noprint = true;    foreach (Trcmd, t, eachline)        foreach(Command, cmd, t->cmdlist)	    /* This case statement checks to see if we have already	     * displayed a source line or a return.  It prevents printing	     * the same line/return over & over in a recursively called	     * routine.  (003 - vjh)	     */	    switch (cmd->op) {	        case O_PRINTSRCPOS:		    if (noprint) {		        evalcmd(cmd);			noprint = false;		    }		    break;		default:		    evalcmd(cmd);		    break;	    }	endfor    endfor    noprint = true;    foreach (Trcmd, t, eachinst)        foreach(Command, cmd, t->cmdlist)	    switch (cmd->op) {	        case O_PRINTSRCPOS:		    if (noprint) {		        evalcmd(cmd);			noprint = false;		    }		    break;		default:		    evalcmd(cmd);		    break;	    }	endfor    endfor    bpact();}/* * A procedure call/return has occurred while single-stepping, * note it if we're tracing lines. */private Boolean chklist();public callnews(iscall)Boolean iscall;{    if (not chklist(eachline, iscall)) {	chklist(eachinst, iscall);    }}private Boolean chklist(list, iscall)List list;Boolean iscall;{    register Trcmd t;    register Command cmd;    setcurfunc(whatblock(pc));    foreach (Trcmd, t, list)	foreach (Command, cmd, t->cmdlist)	    if (cmd->op == O_PRINTSRCPOS and	      (cmd->value.arg[0] == nil or cmd->value.arg[0]->op == O_QLINE)) {		if (iscall) {		    printentry(curfunc);		} else {		    printexit(curfunc);		}		return true;	    }	endfor    endfor    return false;}/* * When tracing variables we keep a copy of their most recent value * and compare it to the current one each time a breakpoint occurs. */#define TRBUFFSIZE 512  /* Used to be MAXTRSIZE - now no max (vjh) *//* * List of variables being watched. */typedef struct Trinfo *Trinfo;struct Trinfo {    Node variable;    Address traddr;    Symbol trblock;    char *trvalue;};private List trinfolist;/* * Find the trace information record associated with the given record. * If there isn't one then create it and add it to the list. * Made this work in recursive routines:  checks tp->traddr == addr * as well.  (003 - vjh) */private Trinfo findtrinfo(p)Node p;{    register Trinfo tp;    Boolean isnew;    Address addr;    isnew = true;    addr = lval(p);    if (trinfolist == nil) {	trinfolist = list_alloc();    } else {	foreach (Trinfo, tp, trinfolist)	    if (tp->variable == p and tp->traddr == addr) {		isnew = false;		break;	    }	endfor    }    if (isnew) {	if (tracebpts) {	    printf("adding trinfo for \"");	    prtree(stdout, p);	    printf("\"\n");	}	tp = new(Trinfo);	tp->variable = p;	tp->traddr = addr;	tp->trvalue = nil;	list_append(list_item(tp), nil, trinfolist);    }    return tp;}/* * Print out the value of a variable if it has changed since the * last time we checked. * Took away size limitations.  Now, if data is > TRBUFFSIZE, malloc() * a large enough buffer.  (003 - vjh) */public printifchanged(p)Node p;{    register Trinfo tp;    register int n;    char sbuff[TRBUFFSIZE];    char *buff;    Filename curfile;    static Lineno prevline;    static Filename prevfile;    tp = findtrinfo(p);    n = size(p->nodetype);    if (n > TRBUFFSIZE) {        buff = newarr(char, n);    } else {        buff = sbuff;    }    dread(buff, tp->traddr, n);    curfile = srcfilename(pc);    if (tp->trvalue == nil) {	tp->trvalue = newarr(char, n);	mov(buff, tp->trvalue, n);	mov(buff, sp, n);	sp += n;	printf("initially (at line %d in \"%s\"):\t", curline, curfile);	prtree(stdout, p);	printf(" = ");	printval(p->nodetype);	putchar('\n');    } else if (cmp(tp->trvalue, buff, n) != 0) {	mov(buff, tp->trvalue, n);	mov(buff, sp, n);	sp += n;	printf("after line %d in \"%s\":\t", prevline, prevfile);	prtree(stdout, p);	printf(" = ");	printval(p->nodetype);	putchar('\n');    }    prevline = curline;    prevfile = curfile;    if (buff != sbuff) {        dispose(buff);    }}/* * Stop if the value of the given expression has changed. * Took away size limitations.  Now, if data is > TRBUFFSIZE, malloc() * a large enough buffer.  (003 - vjh) */public stopifchanged(p)Node p;{    register Trinfo tp;    register int n;    char sbuff[TRBUFFSIZE];    char *buff;    static Lineno prevline;    tp = findtrinfo(p);    n = size(p->nodetype);    if (n > TRBUFFSIZE) {        buff = newarr(char, n);    } else {        buff = sbuff;    }    dread(buff, tp->traddr, n);    if (tp->trvalue == nil) {	tp->trvalue = newarr(char, n);	mov(buff, tp->trvalue, n);	isstopped = true;    } else if (cmp(tp->trvalue, buff, n) != 0) {	mov(buff, tp->trvalue, n);	mov(buff, sp, n);	sp += n;	printf("after line %d:\t", prevline);	prtree(stdout, p);	printf(" = ");	printval(p->nodetype);	putchar('\n');	isstopped = true;    }    prevline = curline;    if (buff != sbuff) {        dispose(buff);    }}/* * Free the tracing table. */public trfree(){    register Trinfo tp;    foreach (Trinfo, tp, trinfolist)	dispose(tp->trvalue);	dispose(tp);	list_delete(list_curitem(trinfolist), trinfolist);    endfor}/* * Fix up breakpoint information before continuing execution. * * It's necessary to destroy events and breakpoints that were created * temporarily and still exist because the program terminated abnormally. */public fixbps(){    register Event e;    register Trcmd t;    single_stepping = false;    inst_tracing = false;    trfree();    foreach (Event, e, eventlist)	if (e->temporary) {	    if (not delevent(e->id)) {		printf("!! dbx.fixbps: can't find event %d\n", e->id);	    }	}    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	trid = 0;}/* * Set all breakpoints in object code. */public setallbps(){    register Breakpoint p;    foreach (Breakpoint, p, bplist)	setbp(p->bpaddr);    endfor}/* * Undo damage done by "setallbps". */public unsetallbps(){    register Breakpoint p;    foreach (Breakpoint, p, bplist)	unsetbp(p->bpaddr);    endfor}

⌨️ 快捷键说明

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