mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
205 lines
3 KiB
C
205 lines
3 KiB
C
/*
|
|
*
|
|
* 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;
|
|
}
|