xref: /plan9-contrib/sys/src/cmd/db/trcrun.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 /*
2  * functions for running the debugged process
3  */
4 
5 #include "defs.h"
6 #include "fns.h"
7 
8 extern char lastc, peekc;
9 
10 int child;
11 int msgfd = -1;
12 int notefd = -1;
13 int pcspid = -1;
14 int pcsactive = 0;
15 
16 void
17 setpcs(void)
18 {
19 	char buf[128];
20 
21 	if(pid && pid != pcspid){
22 		if(msgfd >= 0){
23 			close(msgfd);
24 			msgfd = -1;
25 		}
26 		if(notefd >= 0){
27 			close(notefd);
28 			notefd = -1;
29 		}
30 		pcspid = -1;
31 		sprint(buf, "/proc/%d/ctl", pid);
32 		msgfd = open(buf, OWRITE);
33 		if(msgfd < 0)
34 			error("can't open control file");
35 		sprint(buf, "/proc/%d/note", pid);
36 		notefd = open(buf, ORDWR);
37 		if(notefd < 0)
38 			error("can't open note file");
39 		pcspid = pid;
40 	}
41 }
42 
43 void
44 msgpcs(char *msg)
45 {
46 	char err[ERRLEN];
47 
48 	setpcs();
49 	if(write(msgfd, msg, strlen(msg)) < 0 && !ending){
50 		errstr(err);
51 		if(strcmp(err, "interrupted") != 0)
52 			endpcs();
53 		errors("can't write control file", err);
54 	}
55 }
56 
57 /*
58  * empty the note buffer and toss pending breakpoint notes
59  */
60 void
61 unloadnote(void)
62 {
63 	char err[ERRLEN];
64 
65 	setpcs();
66 	for(; nnote<NNOTE; nnote++){
67 		switch(read(notefd, note[nnote], ERRLEN)){
68 		case -1:
69 			errstr(err);
70 			if(strcmp(err, "interrupted") != 0)
71 				endpcs();
72 			errors("can't read note file", err);
73 		case 0:
74 			return;
75 		}
76 		note[nnote][ERRLEN-1] = 0;
77 		if(strncmp(note[nnote], "sys: breakpoint", 15) == 0)
78 			--nnote;
79 	}
80 }
81 
82 /*
83  * reload the note buffer
84  */
85 void
86 loadnote(void)
87 {
88 	int i;
89 	char err[ERRLEN];
90 
91 	setpcs();
92 	for(i=0; i<nnote; i++){
93 		if(write(notefd, note[i], strlen(note[i])) < 0){
94 			errstr(err);
95 			if(strcmp(err, "interrupted") != 0)
96 				endpcs();
97 			errors("can't write note file", err);
98 		}
99 	}
100 	nnote = 0;
101 }
102 
103 void
104 notes(void)
105 {
106 	int n;
107 
108 	if(nnote == 0)
109 		return;
110 	dprint("notes:\n");
111 	for(n=0; n<nnote; n++)
112 		dprint("%d:\t%s\n", n, note[n]);
113 }
114 
115 void
116 killpcs(void)
117 {
118 	msgpcs("kill");
119 }
120 
121 void
122 grab(void)
123 {
124 	flush();
125 	msgpcs("stop");
126 	bpwait();
127 }
128 
129 void
130 ungrab(void)
131 {
132 	msgpcs("start");
133 }
134 
135 void
136 doexec(void)
137 {
138 	char *argl[MAXARG];
139 	char args[LINSIZ];
140 	char *p;
141 	char **ap;
142 	char *thisarg;
143 
144 	ap = argl;
145 	p = args;
146 	*ap++ = symfil;
147 	for (rdc(); lastc != EOR;) {
148 		thisarg = p;
149 		if (lastc == '<' || lastc == '>') {
150 			*p++ = lastc;
151 			rdc();
152 		}
153 		while (lastc != EOR && lastc != SPC && lastc != TB) {
154 			*p++ = lastc;
155 			readchar();
156 		}
157 		if (lastc == SPC || lastc == TB)
158 			rdc();
159 		*p++ = 0;
160 		if (*thisarg == '<') {
161 			close(0);
162 			if (open(&thisarg[1], OREAD) < 0) {
163 				print("%s: cannot open\n", &thisarg[1]);
164 				_exits(0);
165 			}
166 		}
167 		else if (*thisarg == '>') {
168 			close(1);
169 			if (create(&thisarg[1], OWRITE, 0666) < 0) {
170 				print("%s: cannot create\n", &thisarg[1]);
171 				_exits(0);
172 			}
173 		}
174 		else
175 			*ap++ = thisarg;
176 	}
177 	*ap = 0;
178 	exec(symfil, argl);
179 	perror(symfil);
180 }
181 
182 char	procname[100];
183 
184 void
185 startpcs(void)
186 {
187 	if ((pid = fork()) == 0) {
188 		pid = getpid();
189 		msgpcs("hang");
190 		doexec();
191 		exits(0);
192 	}
193 
194 	if (pid == -1)
195 		error("can't fork");
196 	child++;
197 	sprint(procname, "/proc/%d/mem", pid);
198 	corfil = procname;
199 	msgpcs("waitstop");
200 	bpwait();
201 	if (adrflg)
202 		rput(cormap, mach->pc, adrval);
203 	while (rdc() != EOR)
204 		;
205 	reread();
206 }
207 
208 void
209 runstep(ulong loc, int keepnote)
210 {
211 	int nfoll;
212 	ulong foll[3];
213 	BKPT bkpt[3];
214 	int i;
215 
216 	if(machdata->foll == 0){
217 		dprint("stepping unimplemented; assuming not a branch\n");
218 		nfoll = 1;
219 		foll[0] = loc+mach->pcquant;
220 	}else {
221 		nfoll = machdata->foll(cormap, loc, rget, foll);
222 		if (nfoll < 0)
223 			error("%r");
224 	}
225 	memset(bkpt, 0, sizeof bkpt);
226 	for(i=0; i<nfoll; i++){
227 		if(foll[i] == loc)
228 			error("can't single step: next instruction is dot");
229 		bkpt[i].loc = foll[i];
230 		bkput(&bkpt[i], 1);
231 	}
232 	runrun(keepnote);
233 	for(i=0; i<nfoll; i++)
234 		bkput(&bkpt[i], 0);
235 }
236 
237 void
238 bpwait(void)
239 {
240 	setcor();
241 	unloadnote();
242 }
243 
244 void
245 runrun(int keepnote)
246 {
247 	int on;
248 
249 	on = nnote;
250 	unloadnote();
251 	if(on != nnote){
252 		notes();
253 		error("not running: new notes pending");
254 	}
255 	if(keepnote)
256 		loadnote();
257 	else
258 		nnote = 0;
259 	flush();
260 	msgpcs("startstop");
261 	bpwait();
262 }
263 
264 void
265 bkput(BKPT *bp, int install)
266 {
267 	char buf[256];
268 	ulong loc;
269 	int ret;
270 
271 	errstr(buf);
272 	if(machdata->bpfix)
273 		loc = (*machdata->bpfix)(bp->loc);
274 	else
275 		loc = bp->loc;
276 	if(install){
277 		ret = get1(cormap, loc, bp->save, machdata->bpsize);
278 		if (ret > 0)
279 			ret = put1(cormap, loc, machdata->bpinst, machdata->bpsize);
280 	}else
281 		ret = put1(cormap, loc, bp->save, machdata->bpsize);
282 	if(ret < 0){
283 		sprint(buf, "can't set breakpoint at %lux: %r", bp->loc);
284 		print(buf);
285 		read(0, buf, 100);
286 	}
287 }
288