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