mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
178 lines
2.8 KiB
C
178 lines
2.8 KiB
C
|
/*
|
||
|
*
|
||
|
* debugger
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "defs.h"
|
||
|
#include "fns.h"
|
||
|
|
||
|
char NOPCS[] = "no process";
|
||
|
|
||
|
/* sub process control */
|
||
|
|
||
|
void
|
||
|
subpcs(int modif)
|
||
|
{
|
||
|
int check;
|
||
|
int runmode;
|
||
|
int keepnote;
|
||
|
int n, r;
|
||
|
ulong line, curr;
|
||
|
BKPT *bk;
|
||
|
char *comptr;
|
||
|
|
||
|
runmode=SINGLE;
|
||
|
r = 0;
|
||
|
keepnote=0;
|
||
|
loopcnt=cntval;
|
||
|
switch (modif) {
|
||
|
|
||
|
/* delete breakpoint */
|
||
|
case 'd':
|
||
|
case 'D':
|
||
|
if ((bk=scanbkpt(dot)) == 0)
|
||
|
error("no breakpoint set");
|
||
|
bk->flag=BKPTCLR;
|
||
|
return;
|
||
|
|
||
|
/* set breakpoint */
|
||
|
case 'b':
|
||
|
case 'B':
|
||
|
if (bk=scanbkpt(dot))
|
||
|
bk->flag=BKPTCLR;
|
||
|
for (bk=bkpthead; bk; bk=bk->nxtbkpt)
|
||
|
if (bk->flag == BKPTCLR)
|
||
|
break;
|
||
|
if (bk==0) {
|
||
|
bk = (BKPT *)malloc(sizeof(*bk));
|
||
|
if (bk == 0)
|
||
|
error("too many breakpoints");
|
||
|
bk->nxtbkpt=bkpthead;
|
||
|
bkpthead=bk;
|
||
|
}
|
||
|
bk->loc = dot;
|
||
|
bk->initcnt = bk->count = cntval;
|
||
|
bk->flag = modif == 'b' ? BKPTSET : BKPTTMP;
|
||
|
check=MAXCOM-1;
|
||
|
comptr=bk->comm;
|
||
|
rdc();
|
||
|
reread();
|
||
|
do {
|
||
|
*comptr++ = readchar();
|
||
|
} while (check-- && lastc!=EOR);
|
||
|
*comptr=0;
|
||
|
if(bk->comm[0] != EOR && cntflg == FALSE)
|
||
|
bk->initcnt = bk->count = HUGEINT;
|
||
|
reread();
|
||
|
if (check)
|
||
|
return;
|
||
|
error("bkpt command too long");
|
||
|
|
||
|
/* exit */
|
||
|
case 'k' :
|
||
|
case 'K':
|
||
|
if (pid == 0)
|
||
|
error(NOPCS);
|
||
|
dprint("%d: killed", pid);
|
||
|
pcsactive = 1; /* force 'kill' ctl */
|
||
|
endpcs();
|
||
|
return;
|
||
|
|
||
|
/* run program */
|
||
|
case 'r':
|
||
|
case 'R':
|
||
|
endpcs();
|
||
|
setup();
|
||
|
runmode = CONTIN;
|
||
|
break;
|
||
|
|
||
|
/* single step */
|
||
|
case 's':
|
||
|
if (pid == 0) {
|
||
|
setup();
|
||
|
loopcnt--;
|
||
|
}
|
||
|
runmode=SINGLE;
|
||
|
keepnote=defval(1);
|
||
|
break;
|
||
|
case 'S':
|
||
|
if (pid == 0) {
|
||
|
setup();
|
||
|
loopcnt--;
|
||
|
}
|
||
|
keepnote=defval(1);
|
||
|
if(pc2line(dbrget(cormap, mach->pc), &line) < 0)
|
||
|
error("%r");
|
||
|
n = loopcnt;
|
||
|
dprint("%s: running\n", symfil);
|
||
|
flush();
|
||
|
for (loopcnt = 1; n > 0; loopcnt = 1) {
|
||
|
r = runpcs(SINGLE, keepnote);
|
||
|
if(pc2line(dot, &curr) < 0)
|
||
|
error("%r");
|
||
|
if (line != curr) { /* on a new line of c */
|
||
|
line = curr;
|
||
|
n--;
|
||
|
}
|
||
|
}
|
||
|
loopcnt = 0;
|
||
|
break;
|
||
|
/* continue with optional note */
|
||
|
case 'c':
|
||
|
case 'C':
|
||
|
if (pid==0)
|
||
|
error(NOPCS);
|
||
|
runmode=CONTIN;
|
||
|
keepnote=defval(1);
|
||
|
break;
|
||
|
|
||
|
case 'n': /* deal with notes */
|
||
|
if (pid==0)
|
||
|
error(NOPCS);
|
||
|
n=defval(-1);
|
||
|
if(n>=0 && n<nnote){
|
||
|
nnote--;
|
||
|
memmove(note[n], note[n+1], (nnote-n)*sizeof(note[0]));
|
||
|
}
|
||
|
notes();
|
||
|
return;
|
||
|
|
||
|
case 'h': /* halt the current process */
|
||
|
if (adrflg && adrval == 0) {
|
||
|
if (pid == 0)
|
||
|
error(NOPCS);
|
||
|
ungrab();
|
||
|
}
|
||
|
else {
|
||
|
grab();
|
||
|
dprint("stopped at%16t");
|
||
|
goto Return;
|
||
|
}
|
||
|
return;
|
||
|
|
||
|
case 'x': /* continue executing the current process */
|
||
|
if (pid == 0)
|
||
|
error(NOPCS);
|
||
|
ungrab();
|
||
|
return;
|
||
|
|
||
|
default:
|
||
|
error("bad `:' command");
|
||
|
}
|
||
|
|
||
|
if (loopcnt>0) {
|
||
|
dprint("%s: running\n", symfil);
|
||
|
flush();
|
||
|
r = runpcs(runmode,keepnote);
|
||
|
}
|
||
|
if (r)
|
||
|
dprint("breakpoint%16t");
|
||
|
else
|
||
|
dprint("stopped at%16t");
|
||
|
Return:
|
||
|
delbp();
|
||
|
printpc();
|
||
|
notes();
|
||
|
}
|