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 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 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 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 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 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 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 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 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 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 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 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 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 372 private void intr() 373 { 374 signal(SIGINT, intr); 375 } 376 377 public fixintr() 378 { 379 signal(SIGINT, dbintr); 380 } 381 382 /* 383 * Resume execution. 384 */ 385 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 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 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 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 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 520 public stepto(addr) 521 Address addr; 522 { 523 xto(addr, false); 524 } 525 526 private contto (addr) 527 Address addr; 528 { 529 xto(addr, true); 530 } 531 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 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 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 623 public Boolean notstarted(p) 624 Process p; 625 { 626 return (Boolean) (p->status == NOTSTARTED); 627 } 628 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 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 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 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 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 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 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 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 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 794 private read_err() 795 { 796 /* 797 * Ignore. 798 */ 799 } 800 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 1346 private cacheflush (p) 1347 Process p; 1348 { 1349 bzero(p->word, sizeof(p->word)); 1350 } 1351 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 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 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 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 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 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 1487 public printsigscaught(p) 1488 Process p; 1489 { 1490 printsigs(p->sigset); 1491 } 1492 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