xref: /plan9-contrib/sys/src/cmd/db/runpcs.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  *
3  *	debugger
4  *
5  */
6 
7 #include "defs.h"
8 #include "fns.h"
9 
10 BKPT *bkpthead;
11 
12 BOOL bpin;
13 
14 int pid;
15 int nnote;
16 int ending;
17 char note[NNOTE][ERRLEN];
18 
19 /* service routines for sub process control */
20 
21 runpcs(int runmode, int keepnote)
22 {
23 	int rc;
24 	BKPT *bkpt;
25 
26 	rc = 0;
27 	if (adrflg)
28 		rput(cormap, mach->pc, dot);
29 	dot = rget(cormap, mach->pc);
30 	flush();
31 	while (--loopcnt >= 0) {
32 		if (runmode == SINGLE) {
33 			bkpt = scanbkpt(dot);
34 			if (bkpt) {
35 				switch(bkpt->flag){
36 				case BKPTTMP:
37 					bkpt->flag = BKPTCLR;
38 					break;
39 				case BKPTSKIP:
40 					bkpt->flag = BKPTSET;
41 					break;
42 				}
43 			}
44 			runstep(dot, keepnote);
45 		} else {
46 			if ((bkpt = scanbkpt(rget(cormap, mach->pc))) != 0) {
47 				execbkpt(bkpt, keepnote);
48 				keepnote = 0;
49 			}
50 			setbp();
51 			runrun(keepnote);
52 		}
53 		keepnote = 0;
54 		delbp();
55 		dot = rget(cormap, mach->pc);
56 		/* real note? */
57 		if (nnote > 0) {
58 			keepnote = 1;
59 			rc = 0;
60 			continue;
61 		}
62 		bkpt = scanbkpt(dot);
63 		if(bkpt == 0){
64 			keepnote = 0;
65 			rc = 0;
66 			continue;
67 		}
68 		/* breakpoint */
69 		if (bkpt->flag == BKPTTMP)
70 			bkpt->flag = BKPTCLR;
71 		else if (bkpt->flag == BKPTSKIP) {
72 			execbkpt(bkpt, keepnote);
73 			keepnote = 0;
74 			loopcnt++;	/* we didn't really stop */
75 			continue;
76 		}
77 		else {
78 			bkpt->flag = BKPTSKIP;
79 			--bkpt->count;
80 			if ((bkpt->comm[0] == EOR || command(bkpt->comm, ':') != 0)
81 			&&  bkpt->count != 0) {
82 				execbkpt(bkpt, keepnote);
83 				keepnote = 0;
84 				loopcnt++;
85 				continue;
86 			}
87 			bkpt->count = bkpt->initcnt;
88 		}
89 		rc = 1;
90 	}
91 	return(rc);
92 }
93 
94 /*
95  * finish the process off;
96  * kill if still running
97  */
98 
99 void
100 endpcs(void)
101 {
102 	BKPT *bk;
103 
104 	if(ending)
105 		return;
106 	ending = 1;
107 	if (pid) {
108 		if(pcsactive){
109 			killpcs();
110 			pcsactive = 0;
111 		}
112 		pid=0;
113 		nnote=0;
114 		for (bk=bkpthead; bk; bk = bk->nxtbkpt)
115 			if (bk->flag == BKPTTMP)
116 				bk->flag = BKPTCLR;
117 			else if (bk->flag != BKPTCLR)
118 				bk->flag = BKPTSET;
119 	}
120 	bpin = FALSE;
121 	ending = 0;
122 }
123 
124 /*
125  * start up the program to be debugged in a child
126  */
127 
128 void
129 setup(void)
130 {
131 
132 	nnote = 0;
133 	startpcs();
134 	bpin = FALSE;
135 	pcsactive = 1;
136 }
137 
138 /*
139  * skip over a breakpoint:
140  * remove breakpoints, then single step
141  * so we can put it back
142  */
143 void
144 execbkpt(BKPT *bk, int keepnote)
145 {
146 	runstep(bk->loc, keepnote);
147 	bk->flag = BKPTSET;
148 }
149 
150 /*
151  * find the breakpoint at adr, if any
152  */
153 
154 BKPT *
155 scanbkpt(ADDR adr)
156 {
157 	BKPT *bk;
158 
159 	for (bk = bkpthead; bk; bk = bk->nxtbkpt)
160 		if (bk->flag != BKPTCLR && bk->loc == adr)
161 			break;
162 	return(bk);
163 }
164 
165 /*
166  * remove all breakpoints from the process' address space
167  */
168 
169 void
170 delbp(void)
171 {
172 	BKPT *bk;
173 
174 	if (bpin == FALSE || pid == 0)
175 		return;
176 	for (bk = bkpthead; bk; bk = bk->nxtbkpt)
177 		if (bk->flag != BKPTCLR)
178 			bkput(bk, 0);
179 	bpin = FALSE;
180 }
181 
182 /*
183  * install all the breakpoints
184  */
185 
186 void
187 setbp(void)
188 {
189 	BKPT *bk;
190 
191 	if (bpin == TRUE || pid == 0)
192 		return;
193 	for (bk = bkpthead; bk; bk = bk->nxtbkpt)
194 		if (bk->flag != BKPTCLR)
195 			bkput(bk, 1);
196 	bpin = TRUE;
197 }
198