1 /*
2 * Copyright (c) 1983 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)process.c 5.6 (Berkeley) 06/01/90";
10 #endif /* not lint */
11
12 /*
13 * Process management.
14 *
15 * This module contains the routines to manage the execution and
16 * tracing of the debuggee process.
17 */
18
19 #include "defs.h"
20 #include "process.h"
21 #include "machine.h"
22 #include "events.h"
23 #include "tree.h"
24 #include "eval.h"
25 #include "operators.h"
26 #include "source.h"
27 #include "object.h"
28 #include "mappings.h"
29 #include "main.h"
30 #include "coredump.h"
31 #include <signal.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34
35 #ifndef public
36
37 typedef struct Process *Process;
38
39 Process process;
40
41 #define DEFSIG -1
42
43 #include "machine.h"
44
45 #endif
46
47 #define NOTSTARTED 1
48 #define STOPPED 0177
49 #define FINISHED 0
50
51 /*
52 * A cache of the instruction segment is kept to reduce the number
53 * of system calls. Might be better just to read the entire
54 * code space into memory.
55 */
56
57 #define CACHESIZE 1003
58
59 typedef struct {
60 Word addr;
61 Word val;
62 } CacheWord;
63
64 /*
65 * This structure holds the information we need from the user structure.
66 */
67
68 struct Process {
69 int pid; /* process being traced */
70 int mask; /* process status word */
71 Word reg[NREG]; /* process' registers */
72 Word oreg[NREG]; /* registers when process last stopped */
73 short status; /* either STOPPED or FINISHED */
74 short signo; /* signal that stopped process */
75 short sigcode; /* extra signal information */
76 int exitval; /* return value from exit() */
77 long sigset; /* bit array of traced signals */
78 CacheWord word[CACHESIZE]; /* text segment cache */
79 Ttyinfo ttyinfo; /* process' terminal characteristics */
80 Address sigstatus; /* process' handler for current signal */
81 };
82
83 /*
84 * These definitions are for the arguments to "pio".
85 */
86
87 typedef enum { PREAD, PWRITE } PioOp;
88 typedef enum { TEXTSEG, DATASEG } PioSeg;
89
90 private struct Process pbuf;
91
92 #define MAXNCMDARGS 1000 /* maximum number of arguments to RUN */
93
94 extern int errno;
95
96 private Boolean just_started;
97 private int argc;
98 private String argv[MAXNCMDARGS];
99 private String infile, outfile;
100
101 /*
102 * Initialize process information.
103 */
104
process_init()105 public process_init()
106 {
107 register integer i;
108 char buf[10];
109
110 process = &pbuf;
111 process->status = (coredump) ? STOPPED : NOTSTARTED;
112 setsigtrace();
113 # if vax || tahoe
114 for (i = 0; i < NREG; i++) {
115 sprintf(buf, "$r%d", i);
116 defregname(identname(buf, false), i);
117 }
118 # ifdef vax
119 defregname(identname("$ap", true), ARGP);
120 # endif
121 # else
122 # ifdef mc68000
123 for (i = 0; i < 8; i++) {
124 sprintf(buf, "$d%d", i);
125 defregname(identname(buf, false), i);
126 sprintf(buf, "$a%d", i);
127 defregname(identname(buf, false), i + 8);
128 }
129 # endif
130 # endif
131 defregname(identname("$fp", true), FRP);
132 defregname(identname("$sp", true), STKP);
133 defregname(identname("$pc", true), PROGCTR);
134 if (coredump) {
135 coredump_readin(process->mask, process->reg, process->signo);
136 pc = process->reg[PROGCTR];
137 }
138 arginit();
139 }
140
141 /*
142 * Routines to get at process information from outside this module.
143 */
144
reg(n)145 public Word reg(n)
146 Integer n;
147 {
148 register Word w;
149
150 if (n == NREG) {
151 w = process->mask;
152 } else {
153 w = process->reg[n];
154 }
155 return w;
156 }
157
setreg(n,w)158 public setreg(n, w)
159 Integer n;
160 Word w;
161 {
162 process->reg[n] = w;
163 }
164
165 /*
166 * Begin execution.
167 *
168 * We set a breakpoint at the end of the code so that the
169 * process data doesn't disappear after the program terminates.
170 */
171
172 private Boolean remade();
173
start(argv,infile,outfile)174 public start(argv, infile, outfile)
175 String argv[];
176 String infile, outfile;
177 {
178 String pargv[4];
179 Node cond;
180
181 if (coredump) {
182 coredump = false;
183 fclose(corefile);
184 coredump_close();
185 }
186 if (argv == nil) {
187 argv = pargv;
188 pargv[0] = objname;
189 pargv[1] = nil;
190 } else {
191 argv[argc] = nil;
192 }
193 pstart(process, argv, infile, outfile);
194 if (remade(objname)) {
195 reinit(argv, infile, outfile);
196 }
197 if (process->status == STOPPED) {
198 pc = CODESTART;
199 setcurfunc(program);
200 if (objsize != 0) {
201 cond = build(O_EQ, build(O_SYM, pcsym), build(O_LCON, lastaddr()));
202 event_once(cond, buildcmdlist(build(O_ENDX)));
203 }
204 }
205 }
206
207 /*
208 * Check to see if the object file has changed since the symbolic
209 * information last was read.
210 */
211
212 private time_t modtime;
213
remade(filename)214 private Boolean remade(filename)
215 String filename;
216 {
217 struct stat s;
218 Boolean b;
219
220 stat(filename, &s);
221 b = (Boolean) (modtime != 0 and modtime < s.st_mtime);
222 modtime = s.st_mtime;
223 return b;
224 }
225
226 /*
227 * Set up what signals we want to trace.
228 */
229
setsigtrace()230 private setsigtrace()
231 {
232 register Integer i;
233 register Process p;
234
235 p = process;
236 for (i = 1; i <= NSIG; i++) {
237 psigtrace(p, i, true);
238 }
239 psigtrace(p, SIGHUP, false);
240 psigtrace(p, SIGKILL, false);
241 psigtrace(p, SIGALRM, false);
242 # ifdef SIGTSTP
243 psigtrace(p, SIGTSTP, false);
244 psigtrace(p, SIGCONT, false);
245 # endif
246 psigtrace(p, SIGCHLD, false);
247 psigtrace(p, SIGWINCH, false);
248 }
249
250 /*
251 * Initialize the argument list.
252 */
253
arginit()254 public arginit()
255 {
256 infile = nil;
257 outfile = nil;
258 argv[0] = objname;
259 argc = 1;
260 }
261
262 /*
263 * Add an argument to the list for the debuggee.
264 */
265
newarg(arg)266 public newarg(arg)
267 String arg;
268 {
269 if (argc >= MAXNCMDARGS) {
270 error("too many arguments");
271 }
272 argv[argc++] = arg;
273 }
274
275 /*
276 * Set the standard input for the debuggee.
277 */
278
inarg(filename)279 public inarg(filename)
280 String filename;
281 {
282 if (infile != nil) {
283 error("multiple input redirects");
284 }
285 infile = filename;
286 }
287
288 /*
289 * Set the standard output for the debuggee.
290 * Probably should check to avoid overwriting an existing file.
291 */
292
outarg(filename)293 public outarg(filename)
294 String filename;
295 {
296 if (outfile != nil) {
297 error("multiple output redirect");
298 }
299 outfile = filename;
300 }
301
302 /*
303 * Start debuggee executing.
304 */
305
run()306 public run()
307 {
308 process->status = STOPPED;
309 fixbps();
310 curline = 0;
311 start(argv, infile, outfile);
312 just_started = true;
313 isstopped = false;
314 cont(0);
315 }
316
317 /*
318 * Continue execution wherever we left off.
319 *
320 * Note that this routine never returns. Eventually bpact() will fail
321 * and we'll call printstatus or step will call it.
322 */
323
324 typedef int Intfunc();
325
326 private sig_t dbintr;
327 private void intr();
328
cont(signo)329 public cont(signo)
330 integer signo;
331 {
332 integer s;
333
334 dbintr = signal(SIGINT, intr);
335 if (just_started) {
336 just_started = false;
337 } else {
338 if (not isstopped) {
339 error("can't continue execution");
340 }
341 isstopped = false;
342 stepover();
343 }
344 s = signo;
345 for (;;) {
346 if (single_stepping) {
347 printnews();
348 } else {
349 setallbps();
350 resume(s);
351 unsetallbps();
352 s = DEFSIG;
353 if (not isbperr() or not bpact()) {
354 printstatus();
355 }
356 }
357 stepover();
358 }
359 /* NOTREACHED */
360 }
361
362 /*
363 * This routine is called if we get an interrupt while "running"
364 * but actually in the debugger. Could happen, for example, while
365 * processing breakpoints.
366 *
367 * We basically just want to keep going; the assumption is
368 * that when the process resumes it will get the interrupt,
369 * which will then be handled.
370 */
371
intr()372 private void intr()
373 {
374 signal(SIGINT, intr);
375 }
376
fixintr()377 public fixintr()
378 {
379 signal(SIGINT, dbintr);
380 }
381
382 /*
383 * Resume execution.
384 */
385
resume(signo)386 public resume(signo)
387 int signo;
388 {
389 register Process p;
390
391 p = process;
392 pcont(p, signo);
393 pc = process->reg[PROGCTR];
394 if (p->status != STOPPED) {
395 if (p->signo != 0) {
396 error("program terminated by signal %d", p->signo);
397 } else if (not runfirst) {
398 if (p->exitval == 0) {
399 error("program exited");
400 } else {
401 error("program exited with code %d", p->exitval);
402 }
403 }
404 }
405 }
406
407 /*
408 * Continue execution up to the next source line.
409 *
410 * There are two ways to define the next source line depending on what
411 * is desired when a procedure or function call is encountered. Step
412 * stops at the beginning of the procedure or call; next skips over it.
413 */
414
415 /*
416 * Stepc is what is called when the step command is given.
417 * It has to play with the "isstopped" information.
418 */
419
stepc()420 public stepc()
421 {
422 if (not isstopped) {
423 error("can't continue execution");
424 }
425 isstopped = false;
426 dostep(false);
427 isstopped = true;
428 }
429
next()430 public next()
431 {
432 Address oldfrp, newfrp;
433
434 if (not isstopped) {
435 error("can't continue execution");
436 }
437 isstopped = false;
438 oldfrp = reg(FRP);
439 do {
440 dostep(true);
441 pc = reg(PROGCTR);
442 newfrp = reg(FRP);
443 } while (newfrp < oldfrp and newfrp != 0);
444 isstopped = true;
445 }
446
447 /*
448 * Continue execution until the current function returns, or,
449 * if the given argument is non-nil, until execution returns to
450 * somewhere within the given function.
451 */
452
rtnfunc(f)453 public rtnfunc (f)
454 Symbol f;
455 {
456 Address addr;
457 Symbol t;
458
459 if (not isstopped) {
460 error("can't continue execution");
461 } else if (f != nil and not isactive(f)) {
462 error("%s is not active", symname(f));
463 } else {
464 addr = return_addr();
465 if (addr == nil) {
466 error("no place to return to");
467 } else {
468 isstopped = false;
469 contto(addr);
470 if (f != nil) {
471 for (;;) {
472 t = whatblock(pc);
473 addr = return_addr();
474 if (t == f or addr == nil) break;
475 contto(addr);
476 }
477 }
478 if (not bpact()) {
479 isstopped = true;
480 printstatus();
481 }
482 }
483 }
484 }
485
486 /*
487 * Single-step over the current machine instruction.
488 *
489 * If we're single-stepping by source line we want to step to the
490 * next source line. Otherwise we're going to continue so there's
491 * no reason to do all the work necessary to single-step to the next
492 * source line.
493 */
494
stepover()495 public stepover()
496 {
497 Boolean b;
498
499 if (traceexec) {
500 printf("!! stepping over 0x%x\n", process->reg[PROGCTR]);
501 }
502 if (single_stepping) {
503 dostep(false);
504 } else {
505 b = inst_tracing;
506 inst_tracing = true;
507 dostep(false);
508 inst_tracing = b;
509 }
510 if (traceexec) {
511 printf("!! stepped over to 0x%x\n", process->reg[PROGCTR]);
512 }
513 }
514
515 /*
516 * Resume execution up to the given address. We can either ignore
517 * breakpoints (stepto) or catch them (contto).
518 */
519
stepto(addr)520 public stepto(addr)
521 Address addr;
522 {
523 xto(addr, false);
524 }
525
contto(addr)526 private contto (addr)
527 Address addr;
528 {
529 xto(addr, true);
530 }
531
xto(addr,catchbps)532 private xto (addr, catchbps)
533 Address addr;
534 boolean catchbps;
535 {
536 Address curpc;
537
538 if (catchbps) {
539 stepover();
540 }
541 curpc = process->reg[PROGCTR];
542 if (addr != curpc) {
543 if (traceexec) {
544 printf("!! stepping from 0x%x to 0x%x\n", curpc, addr);
545 }
546 if (catchbps) {
547 setallbps();
548 }
549 setbp(addr);
550 resume(DEFSIG);
551 unsetbp(addr);
552 if (catchbps) {
553 unsetallbps();
554 }
555 if (not isbperr()) {
556 printstatus();
557 }
558 }
559 }
560
561 /*
562 * Print the status of the process.
563 * This routine does not return.
564 */
565
printstatus()566 public printstatus ()
567 {
568 int status;
569
570 if (process->status == FINISHED) {
571 exit(0);
572 } else {
573 if (runfirst) {
574 fprintf(stderr, "\nEntering debugger ...\n");
575 printheading();
576 init();
577 }
578 setcurfunc(whatblock(pc));
579 getsrcpos();
580 if (process->signo == SIGINT) {
581 isstopped = true;
582 printerror();
583 } else if (isbperr() and isstopped) {
584 printf("stopped ");
585 printloc();
586 putchar('\n');
587 if (curline > 0) {
588 printlines(curline, curline);
589 } else {
590 printinst(pc, pc);
591 }
592 erecover();
593 } else {
594 fixintr();
595 isstopped = true;
596 printerror();
597 }
598 }
599 }
600
601 /*
602 * Print out the current location in the debuggee.
603 */
604
printloc()605 public printloc()
606 {
607 printf("in ");
608 printname(stdout, curfunc);
609 putchar(' ');
610 if (curline > 0 and not useInstLoc) {
611 printsrcpos();
612 } else {
613 useInstLoc = false;
614 curline = 0;
615 printf("at 0x%x", pc);
616 }
617 }
618
619 /*
620 * Some functions for testing the state of the process.
621 */
622
notstarted(p)623 public Boolean notstarted(p)
624 Process p;
625 {
626 return (Boolean) (p->status == NOTSTARTED);
627 }
628
isfinished(p)629 public Boolean isfinished(p)
630 Process p;
631 {
632 return (Boolean) (p->status == FINISHED);
633 }
634
635 /*
636 * Predicate to test if the reason the process stopped was because
637 * of a breakpoint. If so, as a side effect clear the local copy of
638 * signal handler associated with process. We must do this so as to
639 * not confuse future stepping or continuing by possibly concluding
640 * the process should continue with a SIGTRAP handler.
641 */
642
isbperr()643 public boolean isbperr()
644 {
645 Process p;
646 boolean b;
647
648 p = process;
649 if (p->status == STOPPED and p->signo == SIGTRAP) {
650 b = true;
651 p->sigstatus = 0;
652 } else {
653 b = false;
654 }
655 return b;
656 }
657
658 /*
659 * Return the signal number that stopped the process.
660 */
661
errnum(p)662 public integer errnum (p)
663 Process p;
664 {
665 return p->signo;
666 }
667
668 /*
669 * Return the signal code associated with the signal.
670 */
671
errcode(p)672 public integer errcode (p)
673 Process p;
674 {
675 return p->sigcode;
676 }
677
678 /*
679 * Return the termination code of the process.
680 */
681
exitcode(p)682 public integer exitcode (p)
683 Process p;
684 {
685 return p->exitval;
686 }
687
688 /*
689 * These routines are used to access the debuggee process from
690 * outside this module.
691 *
692 * They invoke "pio" which eventually leads to a call to "ptrace".
693 * The system generates an I/O error when a ptrace fails. During reads
694 * these are ignored, during writes they are reported as an error, and
695 * for anything else they cause a fatal error.
696 */
697
698 extern Intfunc *onsyserr();
699
700 private badaddr;
701 private read_err(), write_err();
702
703 /*
704 * Read from the process' instruction area.
705 */
706
iread(buff,addr,nbytes)707 public iread(buff, addr, nbytes)
708 char *buff;
709 Address addr;
710 int nbytes;
711 {
712 Intfunc *f;
713
714 f = onsyserr(EIO, read_err);
715 badaddr = addr;
716 if (coredump) {
717 coredump_readtext(buff, addr, nbytes);
718 } else {
719 pio(process, PREAD, TEXTSEG, buff, addr, nbytes);
720 }
721 onsyserr(EIO, f);
722 }
723
724 /*
725 * Write to the process' instruction area, usually in order to set
726 * or unset a breakpoint.
727 */
728
iwrite(buff,addr,nbytes)729 public iwrite(buff, addr, nbytes)
730 char *buff;
731 Address addr;
732 int nbytes;
733 {
734 Intfunc *f;
735
736 if (coredump) {
737 error("no process to write to");
738 }
739 f = onsyserr(EIO, write_err);
740 badaddr = addr;
741 pio(process, PWRITE, TEXTSEG, buff, addr, nbytes);
742 onsyserr(EIO, f);
743 }
744
745 /*
746 * Read for the process' data area.
747 */
748
dread(buff,addr,nbytes)749 public dread(buff, addr, nbytes)
750 char *buff;
751 Address addr;
752 int nbytes;
753 {
754 Intfunc *f;
755
756 badaddr = addr;
757 if (coredump) {
758 f = onsyserr(EFAULT, read_err);
759 coredump_readdata(buff, addr, nbytes);
760 onsyserr(EFAULT, f);
761 } else {
762 f = onsyserr(EIO, read_err);
763 pio(process, PREAD, DATASEG, buff, addr, nbytes);
764 onsyserr(EIO, f);
765 }
766 }
767
768 /*
769 * Write to the process' data area.
770 */
771
dwrite(buff,addr,nbytes)772 public dwrite(buff, addr, nbytes)
773 char *buff;
774 Address addr;
775 int nbytes;
776 {
777 Intfunc *f;
778
779 if (coredump) {
780 error("no process to write to");
781 }
782 f = onsyserr(EIO, write_err);
783 badaddr = addr;
784 pio(process, PWRITE, DATASEG, buff, addr, nbytes);
785 onsyserr(EIO, f);
786 }
787
788 /*
789 * Trap for errors in reading or writing to a process.
790 * The current approach is to "ignore" read errors and complain
791 * bitterly about write errors.
792 */
793
read_err()794 private read_err()
795 {
796 /*
797 * Ignore.
798 */
799 }
800
write_err()801 private write_err()
802 {
803 error("can't write to process (address 0x%x)", badaddr);
804 }
805
806 /*
807 * Ptrace interface.
808 */
809
810 #define WMASK (~(sizeof(Word) - 1))
811 #define cachehash(addr) ((unsigned) ((addr >> 2) % CACHESIZE))
812
813 #define FIRSTSIG SIGINT
814 #define LASTSIG SIGQUIT
815 #define ischild(pid) ((pid) == 0)
816 #define traceme() ptrace(0, 0, 0, 0)
817 #define setrep(n) (1 << ((n)-1))
818 #define istraced(p) (p->sigset&setrep(p->signo))
819
820 /*
821 * Ptrace options (specified in first argument).
822 */
823
824 #define UREAD 3 /* read from process's user structure */
825 #define UWRITE 6 /* write to process's user structure */
826 #define IREAD 1 /* read from process's instruction space */
827 #define IWRITE 4 /* write to process's instruction space */
828 #define DREAD 2 /* read from process's data space */
829 #define DWRITE 5 /* write to process's data space */
830 #define CONT 7 /* continue stopped process */
831 #define SSTEP 9 /* continue for approximately one instruction */
832 #define PKILL 8 /* terminate the process */
833
834 #ifdef IRIS
835 # define readreg(p, r) ptrace(10, p->pid, r, 0)
836 # define writereg(p, r, v) ptrace(11, p->pid, r, v)
837 #else
838 # define readreg(p, r) ptrace(UREAD, p->pid, regloc(r), 0);
839 # define writereg(p, r, v) ptrace(UWRITE, p->pid, regloc(r), v);
840 #endif
841
842 /*
843 * Start up a new process by forking and exec-ing the
844 * given argument list, returning when the process is loaded
845 * and ready to execute. The PROCESS information (pointed to
846 * by the first argument) is appropriately filled.
847 *
848 * If the given PROCESS structure is associated with an already running
849 * process, we terminate it.
850 */
851
852 /* VARARGS2 */
pstart(p,argv,infile,outfile)853 private pstart(p, argv, infile, outfile)
854 Process p;
855 String argv[];
856 String infile;
857 String outfile;
858 {
859 int status;
860
861 if (p->pid != 0) {
862 pterm(p);
863 cacheflush(p);
864 }
865 fflush(stdout);
866 psigtrace(p, SIGTRAP, true);
867 # ifdef IRIS
868 p->pid = fork();
869 # else
870 p->pid = vfork();
871 # endif
872 if (p->pid == -1) {
873 panic("can't fork");
874 }
875 if (ischild(p->pid)) {
876 nocatcherrs();
877 traceme();
878 if (infile != nil) {
879 infrom(infile);
880 }
881 if (outfile != nil) {
882 outto(outfile);
883 }
884 execv(argv[0], argv);
885 _exit(1);
886 }
887 pwait(p->pid, &status);
888 getinfo(p, status);
889 if (p->status != STOPPED) {
890 beginerrmsg();
891 fprintf(stderr, "warning: cannot execute %s\n", argv[0]);
892 } else {
893 ptraced(p->pid);
894 }
895 }
896
897 /*
898 * Terminate a ptrace'd process.
899 */
900
pterm(p)901 public pterm (p)
902 Process p;
903 {
904 integer status;
905
906 if (p != nil and p->pid != 0) {
907 ptrace(PKILL, p->pid, 0, 0);
908 pwait(p->pid, &status);
909 unptraced(p->pid);
910 }
911 }
912
913 /*
914 * Continue a stopped process. The first argument points to a Process
915 * structure. Before the process is restarted it's user area is modified
916 * according to the values in the structure. When this routine finishes,
917 * the structure has the new values from the process's user area.
918 *
919 * Pcont terminates when the process stops with a signal pending that
920 * is being traced (via psigtrace), or when the process terminates.
921 */
922
pcont(p,signo)923 private pcont(p, signo)
924 Process p;
925 int signo;
926 {
927 int s, status;
928
929 if (p->pid == 0) {
930 error("program is not active");
931 }
932 s = signo;
933 do {
934 setinfo(p, s);
935 if (traceexec) {
936 printf("!! pcont from 0x%x with signal %d (%d)\n",
937 p->reg[PROGCTR], s, p->signo);
938 fflush(stdout);
939 }
940 sigs_off();
941 if (ptrace(CONT, p->pid, p->reg[PROGCTR], p->signo) < 0) {
942 panic("error %d trying to continue process", errno);
943 }
944 pwait(p->pid, &status);
945 sigs_on();
946 getinfo(p, status);
947 if (p->status == STOPPED and traceexec and not istraced(p)) {
948 printf("!! ignored signal %d at 0x%x\n",
949 p->signo, p->reg[PROGCTR]);
950 fflush(stdout);
951 }
952 s = p->signo;
953 } while (p->status == STOPPED and not istraced(p));
954 if (traceexec) {
955 printf("!! pcont to 0x%x on signal %d\n", p->reg[PROGCTR], p->signo);
956 fflush(stdout);
957 }
958 }
959
960 /*
961 * Single step as best ptrace can.
962 */
963
pstep(p,signo)964 public pstep(p, signo)
965 Process p;
966 integer signo;
967 {
968 int s, status;
969
970 s = signo;
971 do {
972 setinfo(p, s);
973 if (traceexec) {
974 printf("!! pstep from 0x%x with signal %d (%d)\n",
975 p->reg[PROGCTR], s, p->signo);
976 fflush(stdout);
977 }
978 sigs_off();
979 if (ptrace(SSTEP, p->pid, p->reg[PROGCTR], p->signo) < 0) {
980 panic("error %d trying to step process", errno);
981 }
982 pwait(p->pid, &status);
983 sigs_on();
984 getinfo(p, status);
985 # if mc68000 || m68000
986 if (p->status == STOPPED and p->signo == SIGTRAP) {
987 p->reg[PROGCTR] += 2;
988 }
989 # endif
990 if (p->status == STOPPED and traceexec and not istraced(p)) {
991 printf("!! pstep ignored signal %d at 0x%x\n",
992 p->signo, p->reg[PROGCTR]);
993 fflush(stdout);
994 }
995 s = p->signo;
996 } while (p->status == STOPPED and not istraced(p));
997 if (traceexec) {
998 printf("!! pstep to 0x%x on signal %d\n",
999 p->reg[PROGCTR], p->signo);
1000 fflush(stdout);
1001 }
1002 if (p->status != STOPPED) {
1003 if (p->exitval == 0) {
1004 error("program exited\n");
1005 } else {
1006 error("program exited with code %d\n", p->exitval);
1007 }
1008 }
1009 }
1010
1011 /*
1012 * Return from execution when the given signal is pending.
1013 */
1014
psigtrace(p,sig,sw)1015 public psigtrace(p, sig, sw)
1016 Process p;
1017 int sig;
1018 Boolean sw;
1019 {
1020 if (sw) {
1021 p->sigset |= setrep(sig);
1022 } else {
1023 p->sigset &= ~setrep(sig);
1024 }
1025 }
1026
1027 /*
1028 * Don't catch any signals.
1029 * Particularly useful when letting a process finish uninhibited.
1030 */
1031
unsetsigtraces(p)1032 public unsetsigtraces(p)
1033 Process p;
1034 {
1035 p->sigset = 0;
1036 }
1037
1038 /*
1039 * Turn off attention to signals not being caught.
1040 */
1041
1042 private sig_t sigfunc[NSIG];
1043
sigs_off()1044 private sigs_off()
1045 {
1046 register int i;
1047
1048 for (i = FIRSTSIG; i < LASTSIG; i++) {
1049 if (i != SIGKILL) {
1050 sigfunc[i] = signal(i, SIG_IGN);
1051 }
1052 }
1053 }
1054
1055 /*
1056 * Turn back on attention to signals.
1057 */
1058
sigs_on()1059 private sigs_on()
1060 {
1061 register int i;
1062
1063 for (i = FIRSTSIG; i < LASTSIG; i++) {
1064 if (i != SIGKILL) {
1065 signal(i, sigfunc[i]);
1066 }
1067 }
1068 }
1069
1070 /*
1071 * Get process information from user area.
1072 */
1073
getinfo(p,status)1074 private getinfo (p, status)
1075 register Process p;
1076 register int status;
1077 {
1078 register int i;
1079 Address addr;
1080
1081 p->signo = (status&0177);
1082 p->exitval = ((status >> 8)&0377);
1083 if (p->signo != STOPPED) {
1084 p->status = FINISHED;
1085 p->pid = 0;
1086 p->reg[PROGCTR] = 0;
1087 } else {
1088 p->status = p->signo;
1089 p->signo = p->exitval;
1090 p->exitval = 0;
1091 # ifdef IRIS
1092 p->mask = readreg(p, RPS);
1093 # else
1094 p->sigcode = ptrace(UREAD, p->pid, &((struct user *)0)->u_code, 0);
1095 p->mask = readreg(p, PS);
1096 # endif
1097 for (i = 0; i < NREG; i++) {
1098 p->reg[i] = readreg(p, rloc[i]);
1099 p->oreg[i] = p->reg[i];
1100 }
1101 # ifdef mc68000
1102 if (p->status == STOPPED and p->signo == SIGTRAP and
1103 p->reg[PROGCTR] > CODESTART
1104 ) {
1105 p->reg[PROGCTR] -= 2;
1106 }
1107 # endif
1108 savetty(stdout, &(p->ttyinfo));
1109 addr = (Address) &(((struct user *) 0)->u_signal[p->signo]);
1110 p->sigstatus = (Address) ptrace(UREAD, p->pid, addr, 0);
1111 }
1112 }
1113
1114 /*
1115 * Set process's user area information from given process structure.
1116 */
1117
setinfo(p,signo)1118 private setinfo (p, signo)
1119 register Process p;
1120 int signo;
1121 {
1122 register int i;
1123 register int r;
1124
1125 if (signo == DEFSIG) {
1126 if (istraced(p) and (p->sigstatus == 0 or p->sigstatus == 1)) {
1127 p->signo = 0;
1128 }
1129 } else {
1130 p->signo = signo;
1131 }
1132 for (i = 0; i < NREG; i++) {
1133 if ((r = p->reg[i]) != p->oreg[i]) {
1134 writereg(p, rloc[i], r);
1135 }
1136 }
1137 restoretty(stdout, &(p->ttyinfo));
1138 }
1139
1140 /*
1141 * Return the address associated with the current signal.
1142 * (Plus two since the address points to the beginning of a procedure).
1143 */
1144
usignal(p)1145 public Address usignal (p)
1146 Process p;
1147 {
1148 Address r;
1149
1150 r = p->sigstatus;
1151 if (r != 0 and r != 1) {
1152 r += FUNCOFFSET;
1153 }
1154 return r;
1155 }
1156
1157 /*
1158 * Structure for reading and writing by words, but dealing with bytes.
1159 */
1160
1161 typedef union {
1162 Word pword;
1163 Byte pbyte[sizeof(Word)];
1164 } Pword;
1165
1166 /*
1167 * Read (write) from (to) the process' address space.
1168 * We must deal with ptrace's inability to look anywhere other
1169 * than at a word boundary.
1170 */
1171
1172 private Word fetch();
1173 private store();
1174
pio(p,op,seg,buff,addr,nbytes)1175 private pio(p, op, seg, buff, addr, nbytes)
1176 Process p;
1177 PioOp op;
1178 PioSeg seg;
1179 char *buff;
1180 Address addr;
1181 int nbytes;
1182 {
1183 register int i;
1184 register Address newaddr;
1185 register char *cp;
1186 char *bufend;
1187 Pword w;
1188 Address wordaddr;
1189 int byteoff;
1190
1191 if (p->status != STOPPED) {
1192 error("program is not active");
1193 }
1194 cp = buff;
1195 newaddr = addr;
1196 wordaddr = (newaddr&WMASK);
1197 if (wordaddr != newaddr) {
1198 w.pword = fetch(p, seg, wordaddr);
1199 for (i = newaddr - wordaddr; i < sizeof(Word) and nbytes > 0; i++) {
1200 if (op == PREAD) {
1201 *cp++ = w.pbyte[i];
1202 } else {
1203 w.pbyte[i] = *cp++;
1204 }
1205 nbytes--;
1206 }
1207 if (op == PWRITE) {
1208 store(p, seg, wordaddr, w.pword);
1209 }
1210 newaddr = wordaddr + sizeof(Word);
1211 }
1212 byteoff = (nbytes&(~WMASK));
1213 nbytes -= byteoff;
1214 bufend = cp + nbytes;
1215 #ifdef tahoe
1216 if (((int)cp)&WMASK) {
1217 /*
1218 * Must copy a byte at a time, buffer not word addressable.
1219 */
1220 while (cp < bufend) {
1221 if (op == PREAD) {
1222 w.pword = fetch(p, seg, newaddr);
1223 for (i = 0; i < sizeof(Word); i++)
1224 *cp++ = w.pbyte[i];
1225 } else {
1226 for (i = 0; i < sizeof(Word); i++)
1227 w.pbyte[i] = *cp++;
1228 store(p, seg, newaddr, w.pword);
1229 }
1230 newaddr += sizeof(Word);
1231 }
1232 } else {
1233 /*
1234 * Buffer, word aligned, act normally...
1235 */
1236 #endif
1237 while (cp < bufend) {
1238 if (op == PREAD) {
1239 *((Word *) cp) = fetch(p, seg, newaddr);
1240 } else {
1241 store(p, seg, newaddr, *((Word *) cp));
1242 }
1243 cp += sizeof(Word);
1244 newaddr += sizeof(Word);
1245 }
1246 #ifdef tahoe
1247 }
1248 #endif
1249 if (byteoff > 0) {
1250 w.pword = fetch(p, seg, newaddr);
1251 for (i = 0; i < byteoff; i++) {
1252 if (op == PREAD) {
1253 *cp++ = w.pbyte[i];
1254 } else {
1255 w.pbyte[i] = *cp++;
1256 }
1257 }
1258 if (op == PWRITE) {
1259 store(p, seg, newaddr, w.pword);
1260 }
1261 }
1262 }
1263
1264 /*
1265 * Get a word from a process at the given address.
1266 * The address is assumed to be on a word boundary.
1267 *
1268 * A simple cache scheme is used to avoid redundant ptrace calls
1269 * to the instruction space since it is assumed to be pure.
1270 *
1271 * It is necessary to use a write-through scheme so that
1272 * breakpoints right next to each other don't interfere.
1273 */
1274
1275 private Integer nfetchs, nreads, nwrites;
1276
fetch(p,seg,addr)1277 private Word fetch(p, seg, addr)
1278 Process p;
1279 PioSeg seg;
1280 register int addr;
1281 {
1282 register CacheWord *wp;
1283 register Word w;
1284
1285 switch (seg) {
1286 case TEXTSEG:
1287 ++nfetchs;
1288 wp = &p->word[cachehash(addr)];
1289 if (addr == 0 or wp->addr != addr) {
1290 ++nreads;
1291 w = ptrace(IREAD, p->pid, addr, 0);
1292 wp->addr = addr;
1293 wp->val = w;
1294 } else {
1295 w = wp->val;
1296 }
1297 break;
1298
1299 case DATASEG:
1300 w = ptrace(DREAD, p->pid, addr, 0);
1301 break;
1302
1303 default:
1304 panic("fetch: bad seg %d", seg);
1305 /* NOTREACHED */
1306 }
1307 return w;
1308 }
1309
1310 /*
1311 * Put a word into the process' address space at the given address.
1312 * The address is assumed to be on a word boundary.
1313 */
1314
store(p,seg,addr,data)1315 private store(p, seg, addr, data)
1316 Process p;
1317 PioSeg seg;
1318 int addr;
1319 Word data;
1320 {
1321 register CacheWord *wp;
1322
1323 switch (seg) {
1324 case TEXTSEG:
1325 ++nwrites;
1326 wp = &p->word[cachehash(addr)];
1327 wp->addr = addr;
1328 wp->val = data;
1329 ptrace(IWRITE, p->pid, addr, data);
1330 break;
1331
1332 case DATASEG:
1333 ptrace(DWRITE, p->pid, addr, data);
1334 break;
1335
1336 default:
1337 panic("store: bad seg %d", seg);
1338 /* NOTREACHED */
1339 }
1340 }
1341
1342 /*
1343 * Flush the instruction cache associated with a process.
1344 */
1345
cacheflush(p)1346 private cacheflush (p)
1347 Process p;
1348 {
1349 bzero(p->word, sizeof(p->word));
1350 }
1351
printptraceinfo()1352 public printptraceinfo()
1353 {
1354 printf("%d fetchs, %d reads, %d writes\n", nfetchs, nreads, nwrites);
1355 }
1356
1357 /*
1358 * Redirect input.
1359 * Assuming this is called from a child, we should be careful to avoid
1360 * (possibly) shared standard I/O buffers.
1361 */
1362
infrom(filename)1363 private infrom (filename)
1364 String filename;
1365 {
1366 Fileid in;
1367
1368 in = open(filename, 0);
1369 if (in == -1) {
1370 write(2, "can't read ", 11);
1371 write(2, filename, strlen(filename));
1372 write(2, "\n", 1);
1373 _exit(1);
1374 }
1375 fswap(0, in);
1376 }
1377
1378 /*
1379 * Redirect standard output.
1380 * Same assumptions as for "infrom" above.
1381 */
1382
outto(filename)1383 private outto (filename)
1384 String filename;
1385 {
1386 Fileid out;
1387
1388 out = creat(filename, 0666);
1389 if (out == -1) {
1390 write(2, "can't write ", 12);
1391 write(2, filename, strlen(filename));
1392 write(2, "\n", 1);
1393 _exit(1);
1394 }
1395 fswap(1, out);
1396 }
1397
1398 /*
1399 * Swap file numbers, useful for redirecting standard input or output.
1400 */
1401
fswap(oldfd,newfd)1402 private fswap(oldfd, newfd)
1403 Fileid oldfd;
1404 Fileid newfd;
1405 {
1406 if (oldfd != newfd) {
1407 close(oldfd);
1408 dup(newfd);
1409 close(newfd);
1410 }
1411 }
1412
1413 /*
1414 * Signal name manipulation.
1415 */
1416
1417 private String signames[NSIG] = {
1418 0,
1419 "HUP", "INT", "QUIT", "ILL", "TRAP",
1420 "IOT", "EMT", "FPE", "KILL", "BUS",
1421 "SEGV", "SYS", "PIPE", "ALRM", "TERM",
1422 0, "STOP", "TSTP", "CONT", "CHLD",
1423 "TTIN", "TTOU", "TINT", "XCPU", "XFSZ",
1424 "VTALRM", "PROF", "WINCH", "USR1", "USR2"
1425 };
1426
1427 /*
1428 * Get the signal number associated with a given name.
1429 * The name is first translated to upper case if necessary.
1430 */
1431
siglookup(s)1432 public integer siglookup (s)
1433 String s;
1434 {
1435 register char *p, *q;
1436 char buf[100];
1437 integer i;
1438
1439 p = s;
1440 q = buf;
1441 while (*p != '\0') {
1442 if (*p >= 'a' and *p <= 'z') {
1443 *q = (*p - 'a') + 'A';
1444 } else {
1445 *q = *p;
1446 }
1447 ++p;
1448 ++q;
1449 }
1450 *q = '\0';
1451 p = buf;
1452 if (buf[0] == 'S' and buf[1] == 'I' and buf[2] == 'G') {
1453 p += 3;
1454 }
1455 i = 1;
1456 for (;;) {
1457 if (i >= sizeof(signames) div sizeof(signames[0])) {
1458 error("signal \"%s\" unknown", s);
1459 i = 0;
1460 break;
1461 }
1462 if (signames[i] != nil and streq(signames[i], p)) {
1463 break;
1464 }
1465 ++i;
1466 }
1467 return i;
1468 }
1469
1470 /*
1471 * Print all signals being ignored by the debugger.
1472 * These signals are auotmatically
1473 * passed on to the debugged process.
1474 */
1475
printsigsignored(p)1476 public printsigsignored (p)
1477 Process p;
1478 {
1479 printsigs(~p->sigset);
1480 }
1481
1482 /*
1483 * Print all signals being intercepted by
1484 * the debugger for the specified process.
1485 */
1486
printsigscaught(p)1487 public printsigscaught(p)
1488 Process p;
1489 {
1490 printsigs(p->sigset);
1491 }
1492
printsigs(set)1493 private printsigs (set)
1494 integer set;
1495 {
1496 integer s;
1497 char separator[2];
1498
1499 separator[0] = '\0';
1500 for (s = 1; s < sizeof(signames) div sizeof(signames[0]); s++) {
1501 if (set & setrep(s)) {
1502 if (signames[s] != nil) {
1503 printf("%s%s", separator, signames[s]);
1504 separator[0] = ' ';
1505 separator[1] = '\0';
1506 }
1507 }
1508 }
1509 if (separator[0] == ' ') {
1510 putchar('\n');
1511 }
1512 }
1513