diff options
author | rsc <devnull@localhost> | 2004-04-19 19:30:50 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2004-04-19 19:30:50 +0000 |
commit | 84114f06650ba3db950532b1d0cd1d7e18b4b6be (patch) | |
tree | 4a5aa4819d01f1798bf86c3420db542c74092a6f /src/cmd/db/trcrun.c | |
parent | a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 (diff) | |
download | plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.tar.gz plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.tar.bz2 plan9port-84114f06650ba3db950532b1d0cd1d7e18b4b6be.zip |
debugger
Diffstat (limited to 'src/cmd/db/trcrun.c')
-rw-r--r-- | src/cmd/db/trcrun.c | 288 |
1 files changed, 288 insertions, 0 deletions
diff --git a/src/cmd/db/trcrun.c b/src/cmd/db/trcrun.c new file mode 100644 index 00000000..807f902e --- /dev/null +++ b/src/cmd/db/trcrun.c @@ -0,0 +1,288 @@ +/* + * 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(correg, mach->pc, adrval); + while (rdc() != EOR) + ; + reread(); +} + +void +runstep(ulong loc, int keepnote) +{ + int nfoll; + ulong foll[3]; + BKPT bkpt[3]; + int i; + + if(mach->foll == 0){ + dprint("stepping unimplemented; assuming not a branch\n"); + nfoll = 1; + foll[0] = loc+mach->pcquant; + }else { + nfoll = mach->foll(cormap, correg, loc, 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]; + ulong loc; + int ret; + + errstr(buf, sizeof buf); +/* + if(mach->bpfix) + loc = (*mach->bpfix)(bp->loc); + else +*/ + loc = bp->loc; + if(install){ + ret = get1(cormap, loc, bp->save, mach->bpsize); + if (ret > 0) + ret = put1(cormap, loc, mach->bpinst, mach->bpsize); + }else + ret = put1(cormap, loc, bp->save, mach->bpsize); + if(ret < 0){ + sprint(buf, "can't set breakpoint at %#llux: %r", bp->loc); + print(buf); + read(0, buf, 100); + } +} |