| /* |
| * |
| * debugger |
| * |
| */ |
| |
| #include "defs.h" |
| #include "fns.h" |
| |
| BKPT *bkpthead; |
| |
| BOOL bpin; |
| |
| int pid; |
| int nnote; |
| int ending; |
| char note[NNOTE][ERRMAX]; |
| |
| /* service routines for sub process control */ |
| |
| int |
| runpcs(int runmode, int keepnote) |
| { |
| int rc; |
| BKPT *bkpt; |
| ADDR x; |
| |
| rc = 0; |
| if (adrflg) |
| rput(correg, mach->pc, dot); |
| if(rget(correg, mach->pc, &dot) < 0) |
| error("%r"); |
| flush(); |
| while (--loopcnt >= 0) { |
| if(loopcnt != 0) |
| printpc(); |
| if (runmode == SINGLE) { |
| bkpt = scanbkpt(dot); |
| if (bkpt) { |
| switch(bkpt->flag){ |
| case BKPTTMP: |
| bkpt->flag = BKPTCLR; |
| break; |
| case BKPTSKIP: |
| bkpt->flag = BKPTSET; |
| break; |
| } |
| } |
| runstep(dot, keepnote); |
| } else { |
| if(rget(correg, mach->pc, &x) < 0) |
| error("%r"); |
| if ((bkpt = scanbkpt(x)) != 0) { |
| execbkpt(bkpt, keepnote); |
| keepnote = 0; |
| } |
| setbp(); |
| runrun(keepnote); |
| } |
| keepnote = 0; |
| delbp(); |
| if(rget(correg, mach->pc, &dot) < 0) |
| error("%r"); |
| /* real note? */ |
| if (nnote > 0) { |
| keepnote = 1; |
| rc = 0; |
| continue; |
| } |
| bkpt = scanbkpt(dot); |
| if(bkpt == 0){ |
| keepnote = 0; |
| rc = 0; |
| continue; |
| } |
| /* breakpoint */ |
| if (bkpt->flag == BKPTTMP) |
| bkpt->flag = BKPTCLR; |
| else if (bkpt->flag == BKPTSKIP) { |
| execbkpt(bkpt, keepnote); |
| keepnote = 0; |
| loopcnt++; /* we didn't really stop */ |
| continue; |
| } |
| else { |
| bkpt->flag = BKPTSKIP; |
| --bkpt->count; |
| if ((bkpt->comm[0] == EOR || command(bkpt->comm, ':') != 0) |
| && bkpt->count != 0) { |
| execbkpt(bkpt, keepnote); |
| keepnote = 0; |
| loopcnt++; |
| continue; |
| } |
| bkpt->count = bkpt->initcnt; |
| } |
| rc = 1; |
| } |
| return(rc); |
| } |
| |
| /* |
| * finish the process off; |
| * kill if still running |
| */ |
| |
| void |
| endpcs(void) |
| { |
| BKPT *bk; |
| |
| if(ending) |
| return; |
| ending = 1; |
| if (pid) { |
| if(pcsactive){ |
| killpcs(); |
| pcsactive = 0; |
| } |
| pid=0; |
| nnote=0; |
| for (bk=bkpthead; bk; bk = bk->nxtbkpt) |
| if (bk->flag == BKPTTMP) |
| bk->flag = BKPTCLR; |
| else if (bk->flag != BKPTCLR) |
| bk->flag = BKPTSET; |
| } |
| bpin = FALSE; |
| ending = 0; |
| } |
| |
| /* |
| * start up the program to be debugged in a child |
| */ |
| |
| void |
| setup(void) |
| { |
| |
| nnote = 0; |
| startpcs(); |
| bpin = FALSE; |
| pcsactive = 1; |
| } |
| |
| /* |
| * skip over a breakpoint: |
| * remove breakpoints, then single step |
| * so we can put it back |
| */ |
| void |
| execbkpt(BKPT *bk, int keepnote) |
| { |
| runstep(bk->loc, keepnote); |
| bk->flag = BKPTSET; |
| } |
| |
| /* |
| * find the breakpoint at adr, if any |
| */ |
| |
| BKPT * |
| scanbkpt(ADDR adr) |
| { |
| BKPT *bk; |
| |
| for (bk = bkpthead; bk; bk = bk->nxtbkpt) |
| if (bk->flag != BKPTCLR && bk->loc == adr) |
| break; |
| return(bk); |
| } |
| |
| /* |
| * remove all breakpoints from the process' address space |
| */ |
| |
| void |
| delbp(void) |
| { |
| BKPT *bk; |
| |
| if (bpin == FALSE || pid == 0) |
| return; |
| for (bk = bkpthead; bk; bk = bk->nxtbkpt) |
| if (bk->flag != BKPTCLR) |
| bkput(bk, 0); |
| bpin = FALSE; |
| } |
| |
| /* |
| * install all the breakpoints |
| */ |
| |
| void |
| setbp(void) |
| { |
| BKPT *bk; |
| |
| if (bpin == TRUE || pid == 0) |
| return; |
| for (bk = bkpthead; bk; bk = bk->nxtbkpt) |
| if (bk->flag != BKPTCLR) |
| bkput(bk, 1); |
| bpin = TRUE; |
| } |