📄 events.c
字号:
printf(" when "); prtree(stdout, cond); } } else { printf(" when "); prtree(stdout, cond); }}/* * Add a breakpoint to the list and return it. */private Breakpoint bp_alloc(e, addr, line, actions)Event e;Address addr;Lineno line;Cmdlist actions;{ 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); } 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); } } evalcmdlist(p->actions); if (isstopped) { eventId = p->event->id; } if (p->temporary) { list_delete(list_curitem(bplist), bplist); } } endfor if (isstopped) { if (found) { printeventid(eventId); } printstatus(); } fflush(stdout); return found;}/* * Begin single stepping and executing the given commands after each step. * If the first argument is true step by instructions, otherwise * step by source lines. * * We automatically set a breakpoint at the end of the current procedure * to turn off the given tracing. */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) { 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. */public traceoff(id)Integer id;{ register Trcmd t; register boolean found; 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->event->id == 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); } } 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. */public printnews(){ register Trcmd t; foreach (Trcmd, t, eachline) evalcmdlist(t->cmdlist); endfor foreach (Trcmd, t, eachinst) evalcmdlist(t->cmdlist); 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;}/* * 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. */private Trinfo findtrinfo(p)Node p;{ register Trinfo tp; boolean isnew; isnew = true; if (trinfolist == nil) { trinfolist = list_alloc(); } else { foreach (Trinfo, tp, trinfolist) if (tp->variable == p) { 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 = lval(p); 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. */public printifchanged(p)Node p;{ register Trinfo tp; register int n; char buff[MAXTRSIZE]; Filename curfile; static Lineno prevline; static Filename prevfile; tp = findtrinfo(p); n = size(p->nodetype); 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;}/* * Stop if the value of the given expression has changed. */public stopifchanged(p)Node p;{ register Trinfo tp; register int n; char buff[MAXTRSIZE]; static Lineno prevline; tp = findtrinfo(p); n = size(p->nodetype); 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;}/* * 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}/* * 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 + -