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