xref: /plan9-contrib/sys/src/cmd/db/pcs.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  *
3  *	debugger
4  *
5  */
6 
7 #include "defs.h"
8 #include "fns.h"
9 
10 char	NOPCS[] = "no process";
11 
12 extern	char	lastc;
13 
14 /* sub process control */
15 
16 void
17 subpcs(int modif)
18 {
19 	int	check;
20 	int	runmode;
21 	int	keepnote;
22 	int	n, r;
23 	long line, curr;
24 	BKPT *bk;
25 	char *comptr;
26 
27 	runmode=SINGLE;
28 	r = 0;
29 	keepnote=0;
30 	loopcnt=cntval;
31 	switch (modif) {
32 
33 		/* delete breakpoint */
34 	case 'd':
35 	case 'D':
36 		if ((bk=scanbkpt(dot)) == 0)
37 			error("no breakpoint set");
38 		bk->flag=BKPTCLR;
39 		return;
40 
41 		/* set breakpoint */
42 	case 'b':
43 	case 'B':
44 		if (bk=scanbkpt(dot))
45 			bk->flag=BKPTCLR;
46 		for (bk=bkpthead; bk; bk=bk->nxtbkpt)
47 			if (bk->flag == BKPTCLR)
48 				break;
49 		if (bk==0) {
50 			bk = (BKPT *)malloc(sizeof(*bk));
51 			if (bk == 0)
52 				error("too many breakpoints");
53 			bk->nxtbkpt=bkpthead;
54 			bkpthead=bk;
55 		}
56 		bk->loc = dot;
57 		bk->initcnt = bk->count = cntval;
58 		bk->flag = modif == 'b' ? BKPTSET : BKPTTMP;
59 		check=MAXCOM-1;
60 		comptr=bk->comm;
61 		rdc();
62 		reread();
63 		do {
64 			*comptr++ = readchar();
65 		} while (check-- && lastc!=EOR);
66 		*comptr=0;
67 		if(bk->comm[0] != EOR && cntflg == FALSE)
68 			bk->initcnt = bk->count = HUGEINT;
69 		reread();
70 		if (check)
71 			return;
72 		error("bkpt command too long");
73 
74 		/* exit */
75 	case 'k' :
76 	case 'K':
77 		if (pid == 0)
78 			error(NOPCS);
79 		dprint("%d: killed", pid);
80 		pcsactive = 1;	/* force 'kill' ctl */
81 		endpcs();
82 		return;
83 
84 		/* run program */
85 	case 'r':
86 	case 'R':
87 		endpcs();
88 		setup();
89 		runmode = CONTIN;
90 		break;
91 
92 		/* single step */
93 	case 's':
94 		if (pid == 0) {
95 			setup();
96 			loopcnt--;
97 		}
98 		runmode=SINGLE;
99 		keepnote=defval(1);
100 		break;
101 	case 'S':
102 		if (pid == 0) {
103 			setup();
104 			loopcnt--;
105 		}
106 		keepnote=defval(1);
107 		line = pc2line(rget(cormap, mach->pc));
108 		n = loopcnt;
109 		dprint("%s: running\n", symfil);
110 		flush();
111 		for (loopcnt = 1; n > 0; loopcnt = 1) {
112 			r = runpcs(SINGLE, keepnote);
113 			curr = pc2line(dot);
114 			if (line != curr) {	/* on a new line of c */
115 				line = curr;
116 				n--;
117 			}
118 		}
119 		loopcnt = 0;
120 		break;
121 		/* continue with optional note */
122 	case 'c':
123 	case 'C':
124 		if (pid==0)
125 			error(NOPCS);
126 		runmode=CONTIN;
127 		keepnote=defval(1);
128 		break;
129 
130 	case 'n':	/* deal with notes */
131 		if (pid==0)
132 			error(NOPCS);
133 		n=defval(-1);
134 		if(n>=0 && n<nnote){
135 			nnote--;
136 			memmove(note[n], note[n+1], (nnote-n)*sizeof(note[0]));
137 		}
138 		notes();
139 		return;
140 
141 	case 'h':	/* halt the current process */
142 		if (adrflg && adrval == 0) {
143 			if (pid == 0)
144 				error(NOPCS);
145 			ungrab();
146 		}
147 		else {
148 			grab();
149 			dprint("stopped at%16t");
150 			goto Return;
151 		}
152 		return;
153 
154 	case 'x':	/* continue executing the current process */
155 		if (pid == 0)
156 			error(NOPCS);
157 		ungrab();
158 		return;
159 
160 	default:
161 		error("bad `:' command");
162 	}
163 
164 	if (loopcnt>0) {
165 		dprint("%s: running\n", symfil);
166 		flush();
167 		r = runpcs(runmode,keepnote);
168 	}
169 	if (r)
170 		dprint("breakpoint%16t");
171 	else
172 		dprint("stopped at%16t");
173     Return:
174 	delbp();
175 	printpc();
176 	notes();
177 }
178