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