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