|  | /* | 
|  | * | 
|  | *	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(); | 
|  | } |