📄 events.c
字号:
Cmdlist actions;{ register Breakpoint p; p = new(Breakpoint); p->event = e; p->bpaddr = addr; p->bpline = line; p->actions = actions; 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); } } evalcmdlist(p->actions); if (isstopped) { eventId = p->event->id; } } 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; trcmd = new(Trcmd); ++trid; trcmd->trid = trid; trcmd->event = event; 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(event, (Address) ret, 0, actions); } if (tracebpts) { printf("adding trace %d for event %d\n", trcmd->trid, event->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) { panic("missing trid %d", 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;}/* * When tracing variables we keep a copy of their most recent value * and compare it to the current one each time a breakpoint occurs. * MAXTRSIZE is the maximum size variable we allow. */#define MAXTRSIZE 512/* * 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]; 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); mov(buff, sp, n); sp += n; printf("initially (at line %d):\t", curline); 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:\t", prevline); prtree(stdout, p); printf(" = "); printval(p->nodetype); putchar('\n'); } prevline = curline;}/* * 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 + -