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