ref: 4308f6e7e6586e3a27aa46c4d54c434b8533b16d
dir: /sys/src/cmd/db/trcrun.c/
/* * functions for running the debugged process */ #include "defs.h" #include "fns.h" int child; int msgfd = -1; int notefd = -1; int pcspid = -1; int pcsactive = 0; void setpcs(void) { char buf[128]; if(pid && pid != pcspid){ if(msgfd >= 0){ close(msgfd); msgfd = -1; } if(notefd >= 0){ close(notefd); notefd = -1; } pcspid = -1; sprint(buf, "/proc/%d/ctl", pid); msgfd = open(buf, OWRITE); if(msgfd < 0) error("can't open control file"); sprint(buf, "/proc/%d/note", pid); notefd = open(buf, ORDWR); if(notefd < 0) error("can't open note file"); pcspid = pid; } } void msgpcs(char *msg) { char err[ERRMAX]; setpcs(); if(write(msgfd, msg, strlen(msg)) < 0 && !ending){ errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't write control file", err); } } /* * empty the note buffer and toss pending breakpoint notes */ void unloadnote(void) { char err[ERRMAX]; setpcs(); for(; nnote<NNOTE; nnote++){ switch(read(notefd, note[nnote], sizeof note[nnote])){ case -1: errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't read note file", err); case 0: return; } note[nnote][ERRMAX-1] = '\0'; if(strncmp(note[nnote], "sys: breakpoint", 15) == 0) --nnote; } } /* * reload the note buffer */ void loadnote(void) { int i; char err[ERRMAX]; setpcs(); for(i=0; i<nnote; i++){ if(write(notefd, note[i], strlen(note[i])) < 0){ errstr(err, sizeof err); if(strcmp(err, "interrupted") != 0) endpcs(); errors("can't write note file", err); } } nnote = 0; } void notes(void) { int n; if(nnote == 0) return; dprint("notes:\n"); for(n=0; n<nnote; n++) dprint("%d:\t%s\n", n, note[n]); } void killpcs(void) { msgpcs("kill"); } void grab(void) { flush(); msgpcs("stop"); bpwait(); } void ungrab(void) { msgpcs("start"); } void doexec(void) { char *argl[MAXARG]; char args[LINSIZ]; char *p; char **ap; char *thisarg; ap = argl; p = args; *ap++ = symfil; for (rdc(); lastc != EOR;) { thisarg = p; if (lastc == '<' || lastc == '>') { *p++ = lastc; rdc(); } while (lastc != EOR && lastc != SPC && lastc != TB) { *p++ = lastc; readchar(); } if (lastc == SPC || lastc == TB) rdc(); *p++ = 0; if (*thisarg == '<') { close(0); if (open(&thisarg[1], OREAD) < 0) { print("%s: cannot open\n", &thisarg[1]); _exits(0); } } else if (*thisarg == '>') { close(1); if (create(&thisarg[1], OWRITE, 0666) < 0) { print("%s: cannot create\n", &thisarg[1]); _exits(0); } } else *ap++ = thisarg; } *ap = 0; exec(symfil, argl); perror(symfil); } char procname[100]; void startpcs(void) { if ((pid = fork()) == 0) { pid = getpid(); msgpcs("hang"); doexec(); exits(0); } if (pid == -1) error("can't fork"); child++; sprint(procname, "/proc/%d/mem", pid); corfil = procname; msgpcs("waitstop"); bpwait(); if (adrflg) rput(cormap, mach->pc, adrval); while (rdc() != EOR) ; reread(); } void runstep(uvlong loc, int keepnote) { int nfoll; uvlong foll[3]; BKPT bkpt[3]; int i; if(machdata->foll == 0){ dprint("stepping unimplemented; assuming not a branch\n"); nfoll = 1; foll[0] = loc+mach->pcquant; }else { nfoll = machdata->foll(cormap, loc, rget, foll); if (nfoll < 0) error("%r"); } memset(bkpt, 0, sizeof bkpt); for(i=0; i<nfoll; i++){ if(foll[i] == loc) error("can't single step: next instruction is dot"); bkpt[i].loc = foll[i]; bkput(&bkpt[i], 1); } runrun(keepnote); for(i=0; i<nfoll; i++) bkput(&bkpt[i], 0); } void bpwait(void) { setcor(); unloadnote(); } void runrun(int keepnote) { int on; on = nnote; unloadnote(); if(on != nnote){ notes(); error("not running: new notes pending"); } if(keepnote) loadnote(); else nnote = 0; flush(); msgpcs("startstop"); bpwait(); } void bkput(BKPT *bp, int install) { char buf[256]; ADDR loc; int ret; errstr(buf, sizeof buf); if(machdata->bpfix) loc = (*machdata->bpfix)(bp->loc); else loc = bp->loc; if(install){ ret = get1(cormap, loc, bp->save, machdata->bpsize); if (ret > 0) ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize); }else ret = put1(cormap, loc, bp->save, machdata->bpsize); if(ret < 0){ sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc); print(buf); read(0, buf, 100); } }