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