|
|
1.1 root 1: /*
2: * OS-specific functions for running the debugged process
3: * particular to v8 (assumes /proc)
4: */
5:
6: #include "defs.h"
7: #include "regs.h"
8: #include <sys/pioctl.h>
9: #include <sys/user.h>
10: #include <sys/proc.h>
11: #include <signal.h>
12: #include <errno.h>
13: #include "base.h"
14:
15: char lastc, peekc;
16: ADDR txtsize;
17:
18: static int child;
19: static long tsigs = -1;
20:
21: /*
22: * kill process
23: */
24:
25: killpcs()
26: {
27: long sig = SIGKILL;
28:
29: ioctl(fcor, PIOCCSIG, 0);
30: ioctl(fcor, PIOCKILL, &sig);
31: ioctl(fcor, PIOCRUN, 0);
32: }
33:
34: /*
35: * grab the process already opened (but not traced);
36: * stop it so we can look at it
37: */
38:
39: grab()
40: {
41: struct proc p;
42: int f;
43:
44: if ((f = open(corfil, 2)) < 0)
45: error("no write access");
46: close(fcor);
47: fcor = f;
48: if (ioctl(fcor, PIOCGETPR, &p) < 0)
49: error("not a process");
50: pid = p.p_pid;
51: child = 0;
52: ioctl(fcor, PIOCSMASK, &tsigs);
53: if (p.p_stat != SSTOP)
54: ioctl(fcor, PIOCSTOP, 0);
55: bpwait();
56: }
57:
58: /*
59: * turn off tracing & let it go
60: */
61:
62: ungrab()
63: {
64: long zero = 0;
65:
66: if (signo == 0)
67: ioctl(fcor, PIOCCSIG, 0);
68: ioctl(fcor, PIOCSMASK, &zero);
69: ioctl(fcor, PIOCRUN, 0);
70: pid = 0;
71: }
72:
73: /*
74: * get the program to be debugged ready to run
75: * program is left stopped at the beginning (so we can poke in breakpoints)
76: */
77:
78: startpcs()
79: {
80: int fd;
81: char *procname();
82: extern int (*sigint)(), (*sigqit)();
83:
84: fd = procopen(getpid());
85: if (ioctl(fd, PIOCSEXEC, 0) < 0) {
86: close(fd);
87: error("no process ioctl");
88: }
89: if ((pid = fork()) == 0) {
90: close(fd);
91: close(fsym);
92: close(fcor);
93: signal(SIGINT, sigint);
94: signal(SIGQUIT, sigqit);
95: doexec();
96: exit(0);
97: }
98: ioctl(fd, PIOCREXEC, 0);
99: close(fd);
100: if (pid == -1)
101: error("can't fork");
102: child++;
103: fcor = procopen(pid);
104: corfil = procname(pid);
105: ioctl(fcor, PIOCSMASK, &tsigs);
106: bpwait();
107: ioctl(fcor, PIOCREXEC, 0);
108: if (adrflg)
109: rput(PC, wtoa(adrval));
110: while (rdc() != EOR)
111: ;
112: reread();
113: }
114:
115: int
116: procopen(pid)
117: int pid;
118: {
119: char *pn;
120: int fd;
121: char *procname();
122:
123: pn = procname(pid);
124: if ((fd = open(pn, 2)) < 0) {
125: printf("%s: cannot open\n", pn);
126: error(0);
127: }
128: return (fd);
129: }
130:
131: char *
132: procname(pid)
133: int pid;
134: {
135: static char name[20];
136:
137: sprintf(name, "/proc/%d", pid);
138: return (name);
139: }
140:
141: /*
142: * set process running, single-stepped
143: */
144:
145: runstep(keepsig)
146: int keepsig;
147: {
148:
149: delbp();
150: setstep();
151: rrest();
152: if (keepsig == 0)
153: ioctl(fcor, PIOCCSIG, 0);
154: ioctl(fcor, PIOCRUN, 0);
155: }
156:
157: /*
158: * set process running
159: */
160:
161: runrun(keepsig)
162: int keepsig;
163: {
164:
165: if (keepsig == 0)
166: ioctl(fcor, PIOCCSIG, 0);
167: ioctl(fcor, PIOCRUN, 0);
168: }
169:
170: /*
171: * exec the program to be debugged
172: * opening standard input and output as requested
173: */
174:
175: doexec()
176: {
177: char *argl[MAXARG];
178: char args[LINSIZ];
179: register char *p;
180: register char **ap;
181: register char *thisarg;
182: extern char **environ;
183:
184: ap = argl;
185: p = args;
186: *ap++ = symfil;
187: for (rdc(); lastc != EOR;) {
188: thisarg = p;
189: if (lastc == '<' || lastc == '>') {
190: *p++ = lastc;
191: rdc();
192: }
193: while (lastc != EOR && lastc != SPC && lastc != TB) {
194: *p++ = lastc;
195: readchar();
196: }
197: if (lastc == SPC || lastc == TB)
198: rdc();
199: *p++ = 0;
200: if (*thisarg == '<') {
201: close(0);
202: if (open(&thisarg[1], 0) < 0) {
203: printf("%s: cannot open\n", &thisarg[1]);
204: _exit(0);
205: }
206: }
207: else if (*thisarg == '>') {
208: close(1);
209: if (creat(&thisarg[1], 0666) < 0) {
210: printf("%s: cannot create\n", &thisarg[1]);
211: _exit(0);
212: }
213: }
214: else
215: *ap++ = thisarg;
216: }
217: *ap = NULL;
218: execve(symfil, argl, environ);
219: perror(symfil);
220: }
221:
222: /*
223: * wait for the process to stop;
224: * pick up status and registers when it does
225: */
226:
227: #define WSLEEP 10
228:
229: bpwait()
230: {
231: register int w;
232: int stat;
233: int (*isig)();
234: int nulsig();
235: extern int errno;
236:
237: isig = signal(SIGINT, SIG_IGN);
238: /*
239: * alarm stuff is just in case
240: */
241: for (;;) {
242: signal(SIGALRM, nulsig);
243: alarm(WSLEEP);
244: if (ioctl(fcor, PIOCWSTOP, 0) >= 0)
245: errno = 0;
246: alarm(0);
247: if (errno == 0) {
248: signal(SIGINT, isig);
249: mapimage();
250: if (signo == SIGTRAP || signo == SIGSTOP)
251: signo = 0;
252: else {
253: sigprint();
254: newline();
255: }
256: return; /* should set stuff? */
257: }
258: if (errno == ENOENT)
259: break;
260: /* still there, still running. try again. */
261: }
262: if (child == 0) {
263: close(fcor);
264: pid = 0;
265: corfil = NULL;
266: errflg = "process terminated";
267: return;
268: }
269: /*
270: * process has died; wait and report status
271: * should check if it's really our child
272: */
273: signal(SIGALRM, nulsig);
274: alarm(WSLEEP);
275: while ((w = wait(&stat)) != -1 && w != pid)
276: ;
277: alarm(0);
278: pid = 0;
279: signal(SIGINT, isig);
280: close(fcor);
281: pid = 0;
282: corfil = NULL;
283: errflg = "process terminated";
284: if (w == -1)
285: errflg = "wait failed";
286: else {
287: if ((stat & 0177) == 0177)
288: printf("trace status? 0%o\n", stat);
289: else {
290: sigcode = 0;
291: if ((signo = stat & 0177) != 0)
292: sigprint();
293: if (stat & 0200) {
294: prints(" - core dumped");
295: corfil = "core";
296: setcor();
297: }
298: }
299: }
300: }
301:
302: static
303: nulsig()
304: {
305: }
306:
307: /*
308: * is the right-hand file a process image?
309: */
310:
311: static struct proc p;
312: static struct user u;
313:
314: trcimage()
315: {
316:
317: if (ioctl(fcor, PIOCGETPR, &p) < 0)
318: return (0);
319: lseek(fcor, (off_t)UBASE, 0);
320: if (read(fcor, (char *)&u, sizeof(u)) != sizeof(u))
321: return (0);
322: if (p.p_stat != SSTOP)
323: signo = 0;
324: else
325: signo = p.p_cursig;
326: return (1);
327: }
328:
329: /*
330: * get bits of u-area before maps are set
331: */
332:
333: int
334: trcunab(off)
335: int off;
336: {
337:
338: return (*(int *)((char *)&u + off));
339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.