1 /* trace(1) - the MINIX3 system call tracer - by D.C. van Moolenbroek */ 2 3 #include "inc.h" 4 5 #include <signal.h> 6 #include <sys/wait.h> 7 #include <unistd.h> 8 #include <err.h> 9 10 /* Global variables, used only for a subset of the command line options. */ 11 int timestamps; /* 0 = none, 1 = time w/o usecs, 2 = time w/usecs */ 12 int allnames; /* FALSE = structure field names, TRUE = all names */ 13 unsigned int valuesonly; /* 0 = normal, 1 = no symbols, 2 = no structures */ 14 unsigned int verbose; /* 0 = essentials, 1 = elaborate, 2 = everything */ 15 16 /* Local variables, for signal handling. */ 17 static int got_signal, got_info; 18 19 /* 20 * Signal handler for signals that are supposed to make us terminate. Let the 21 * main loop do the actual work, since it might be in the middle of processing 22 * a process status change right now. 23 */ 24 static void 25 sig_handler(int __unused sig) 26 { 27 28 got_signal = TRUE; 29 30 } 31 32 /* 33 * Signal handler for the SIGINFO signal. Let the main loop report on all 34 * processes currenty being traced. Since SIGINFO is sent to the current 35 * process group, traced children may get the signal as well. This is both 36 * intentional and impossible to prevent. 37 */ 38 static void 39 info_handler(int __unused sig) 40 { 41 42 got_info = TRUE; 43 } 44 45 /* 46 * Print a list of traced processes and their call status. We must not 47 * interfere with actual process output, so perform out-of-band printing 48 * (with info lines rather than lines prefixed by each process's PID). 49 */ 50 static void 51 list_info(void) 52 { 53 struct trace_proc *proc; 54 int no_call, in_call; 55 56 put_newline(); 57 58 for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) { 59 /* 60 * When attaching to an existing process, there is no way to 61 * find out whether the process is in a system call or not. 62 */ 63 no_call = (proc->trace_flags & TF_NOCALL); 64 in_call = (proc->trace_flags & TF_INCALL); 65 assert(!in_call || !no_call); 66 67 put_fmt(NULL, "Tracing %s (pid %d), %s%s%s", proc->name, 68 proc->pid, no_call ? "call status unknown" : 69 (in_call ? "in a " : "not in a call"), 70 in_call ? call_name(proc) : "", 71 in_call ? " call" : ""); 72 put_newline(); 73 } 74 } 75 76 /* 77 * Either we have just started or attached to the given process, it the process 78 * has performed a successful execve() call. Obtain the new process name, and 79 * print a banner for it. 80 */ 81 static void 82 new_exec(struct trace_proc * proc) 83 { 84 85 /* Failure to obtain the process name is worrisome, but not fatal.. */ 86 if (kernel_get_name(proc->pid, proc->name, sizeof(proc->name)) < 0) 87 strlcpy(proc->name, "<unknown>", sizeof(proc->name)); 88 89 put_newline(); 90 put_fmt(proc, "Tracing %s (pid %d)", proc->name, proc->pid); 91 put_newline(); 92 } 93 94 /* 95 * We have started or attached to a process. Set the appropriate flags, and 96 * print a banner showing that we are now tracing it. 97 */ 98 static void 99 new_proc(struct trace_proc * proc, int follow_fork) 100 { 101 int fl; 102 103 /* Set the desired tracing options. */ 104 fl = TO_ALTEXEC; 105 if (follow_fork) fl |= TO_TRACEFORK; 106 107 (void)ptrace(T_SETOPT, proc->pid, 0, fl); 108 109 /* 110 * When attaching to an arbitrary process, this process might be in the 111 * middle of an execve(). Now that we have enabled TO_ALTEXEC, we may 112 * now get a SIGSTOP signal next. Guard against this by marking the 113 * first system call as a possible execve(). 114 */ 115 if ((proc->trace_flags & (TF_ATTACH | TF_STOPPING)) == TF_ATTACH) 116 proc->trace_flags |= TF_EXEC; 117 118 new_exec(proc); 119 } 120 121 /* 122 * A process has terminated or is being detached. Print the resulting status. 123 */ 124 static void 125 discard_proc(struct trace_proc * proc, int status) 126 { 127 const char *signame; 128 129 /* 130 * The exit() calls are of type no-return, meaning they are expected 131 * not to return. However, calls of this type may in fact return an 132 * error, in which case the error must be printed. Thus, such calls 133 * are not actually finished until the end of the call-leave phase. 134 * For exit() calls, a successful call will never get to the call-leave 135 * phase. The result is that such calls will end up being shown as 136 * suspended, which is unintuitive. To counter this, we pretend that a 137 * clean process exit is in fact preceded by a call-leave event, thus 138 * allowing the call to be printed without suspension. An example: 139 * 140 * 3| exit(0) <..> 141 * 2| setsid() = 2 142 * [A] 3| exit(0) 143 * 3| Process exited normally with code 0 144 * 145 * The [A] line is the result of the following code. 146 */ 147 if (WIFEXITED(status) && (proc->trace_flags & TF_INCALL)) 148 call_leave(proc, TRUE /*skip*/); 149 150 put_newline(); 151 if (WIFEXITED(status)) { 152 put_fmt(proc, "Process exited normally with code %d", 153 WEXITSTATUS(status)); 154 } else if (WIFSIGNALED(status)) { 155 if ((signame = get_signal_name(WTERMSIG(status))) != NULL) 156 put_fmt(proc, "Process terminated from signal %s", 157 signame); 158 else 159 put_fmt(proc, "Process terminated from signal %d", 160 WTERMSIG(status)); 161 } else if (WIFSTOPPED(status)) 162 put_text(proc, "Process detached"); 163 else 164 put_fmt(proc, "Bogus wait result (%04x)", status); 165 put_newline(); 166 167 proc_del(proc); 168 } 169 170 /* 171 * The given process has been stopped on a system call, either entering or 172 * leaving that call. 173 */ 174 static void 175 handle_call(struct trace_proc * proc, int show_stack) 176 { 177 reg_t pc, sp; 178 int class, skip, new_ctx; 179 180 proc->trace_flags &= ~TF_NOCALL; 181 182 if (proc->trace_flags & TF_SKIP) { 183 /* Skip the call leave phase after a successful execve(). */ 184 proc->trace_flags &= ~(TF_INCALL | TF_SKIP); 185 } else if (!(proc->trace_flags & TF_INCALL)) { 186 /* 187 * The call_enter call returns the class of the call: 188 * TC_NORMAL, TC_EXEC, or TC_SIGRET. TC_EXEC means that an 189 * execve() call is being performed. This means that if a 190 * SIGSTOP follows for the current process, the process has 191 * successfully started a different executable. TC_SIGRET 192 * means that if successful, the call will have a bogus return 193 * value. TC_NORMAL means that the call requires no exception. 194 */ 195 class = call_enter(proc, show_stack); 196 197 switch (class) { 198 case TC_NORMAL: 199 break; 200 case TC_EXEC: 201 proc->trace_flags |= TF_EXEC; 202 break; 203 case TC_SIGRET: 204 proc->trace_flags |= TF_CTX_SKIP; 205 break; 206 default: 207 assert(0); 208 } 209 210 /* Save the current program counter and stack pointer. */ 211 if (!kernel_get_context(proc->pid, &pc, &sp, NULL /*fp*/)) { 212 proc->last_pc = pc; 213 proc->last_sp = sp; 214 } else 215 proc->last_pc = proc->last_sp = 0; 216 217 proc->trace_flags |= TF_INCALL; 218 } else { 219 /* 220 * Check if the program counter or stack pointer have changed 221 * during the system call. If so, this is a strong indication 222 * that a sigreturn call has succeeded, and thus its result 223 * must be skipped, since the result register will not contain 224 * the result of the call. 225 */ 226 new_ctx = (proc->last_pc != 0 && 227 !kernel_get_context(proc->pid, &pc, &sp, NULL /*fp*/) && 228 (pc != proc->last_pc || sp != proc->last_sp)); 229 230 skip = ((proc->trace_flags & TF_CTX_SKIP) && new_ctx); 231 232 call_leave(proc, skip); 233 234 /* 235 * On such context changes, also print a short dashed line. 236 * This helps in identifying signal handler invocations, 237 * although it is not reliable for that purpose: no dashed line 238 * will be printed if a signal handler is invoked while the 239 * process is not making a system call. 240 */ 241 if (new_ctx) { 242 put_text(proc, "---"); 243 put_newline(); 244 } 245 246 proc->trace_flags &= ~(TF_INCALL | TF_CTX_SKIP | TF_EXEC); 247 } 248 } 249 250 /* 251 * The given process has received the given signal. Report the receipt. Due 252 * to the way that signal handling with traced processes works, the signal may 253 * in fact be delivered to the process much later, or never--a problem inherent 254 * to the way signals are handled in PM right now (namely, deferring signal 255 * delivery would let the traced process block signals meant for the tracer). 256 */ 257 static void 258 report_signal(struct trace_proc * proc, int sig, int show_stack) 259 { 260 const char *signame; 261 262 /* 263 * Print a stack trace only if we are not in a call; otherwise, we 264 * would simply get the same stack trace twice and mess up the output 265 * in the process, because call suspension is not expected if we are 266 * tracing a single process only. 267 * FIXME: the check should be for whether we actually print the call.. 268 */ 269 if (show_stack && !(proc->trace_flags & TF_INCALL)) 270 kernel_put_stacktrace(proc); 271 272 /* 273 * If this process is in the middle of a call, the signal will be 274 * printed within the call. This will always happen on the call split, 275 * that is, between the call's entering (out) and leaving (in) phases. 276 * This also means that the recording of the call-enter phase may be 277 * replayed more than once, and the call may be suspended more than 278 * once--after all, a signal is not necessarily followed immediately 279 * by the call result. If the process is not in the middle of a call, 280 * the signal will end up on a separate line. In both cases, multiple 281 * consecutive signals may be printed right after one another. The 282 * following scenario shows a number of possible combinations: 283 * 284 * 2| foo(<..> 285 * 3| ** SIGHUP ** ** SIGUSR1 ** 286 * 3| bar() = <..> 287 * 2|*foo(** SIGUSR1 ** ** SIGUSR2 ** <..> 288 * 3|*bar() = ** SIGCHLD ** 0 289 * 2|*foo(** SIGINT ** &0xef852000) = -1 [EINTR] 290 * 3| kill(3, SIGTERM) = ** SIGTERM ** <..> 291 * 3| Process terminated from signal SIGTERM 292 */ 293 294 call_replay(proc); 295 296 if (!valuesonly && (signame = get_signal_name(sig)) != NULL) 297 put_fmt(proc, "** %s **", signame); 298 else 299 put_fmt(proc, "** SIGNAL %d **", sig); 300 301 put_space(proc); 302 303 output_flush(); 304 } 305 306 /* 307 * Wait for the given process ID to stop on the given signal. Upon success, 308 * the function will return zero. Upon failure, it will return -1, and errno 309 * will be either set to an error code, or to zero in order to indicate that 310 * the process exited instead. 311 */ 312 static int 313 wait_sig(pid_t pid, int sig) 314 { 315 int status; 316 317 for (;;) { 318 if (waitpid(pid, &status, 0) == -1) { 319 if (errno == EINTR) continue; 320 321 return -1; 322 } 323 324 if (!WIFSTOPPED(status)) { 325 /* The process terminated just now. */ 326 errno = 0; 327 328 return -1; 329 } 330 331 if (WSTOPSIG(status) == sig) 332 break; 333 334 (void)ptrace(T_RESUME, pid, 0, WSTOPSIG(status)); 335 } 336 337 return 0; 338 } 339 340 /* 341 * Attach to the given process, and wait for the resulting SIGSTOP signal. 342 * Other signals may arrive first; we pass these on to the process without 343 * reporting them, thus logically modelling them as having arrived before we 344 * attached to the process. The process might also exit in the meantime, 345 * typically as a result of a lethal signal; following the same logical model, 346 * we pretend the process did not exist in the first place. Since the SIGSTOP 347 * signal will be pending right after attaching to the process, this procedure 348 * will never block. 349 */ 350 static int 351 attach(pid_t pid) 352 { 353 354 if (ptrace(T_ATTACH, pid, 0, 0) != 0) { 355 warn("Unable to attach to pid %d", pid); 356 357 return -1; 358 } 359 360 if (wait_sig(pid, SIGSTOP) != 0) { 361 /* If the process terminated, report it as not found. */ 362 if (errno == 0) 363 errno = ESRCH; 364 365 warn("Unable to attach to pid %d", pid); 366 367 return -1; 368 } 369 370 /* Verify that we can read values from the kernel at all. */ 371 if (kernel_check(pid) == FALSE) { 372 (void)ptrace(T_DETACH, pid, 0, 0); 373 374 warnx("Kernel magic check failed, recompile trace(1)"); 375 376 return -1; 377 } 378 379 /* 380 * System services are managed by RS, which prevents them from 381 * being traced properly by PM. Attaching to a service could 382 * therefore cause problems, so we should detach immediately. 383 */ 384 if (kernel_is_service(pid) == TRUE) { 385 (void)ptrace(T_DETACH, pid, 0, 0); 386 387 warnx("Cannot attach to system services!"); 388 389 return -1; 390 } 391 392 return 0; 393 } 394 395 /* 396 * Detach from all processes, knowning that they were all processes to which we 397 * attached explicitly (i.e., not started by us) and are all currently stopped. 398 */ 399 static void 400 detach_stopped(void) 401 { 402 struct trace_proc *proc; 403 404 for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) 405 (void)ptrace(T_DETACH, proc->pid, 0, 0); 406 } 407 408 /* 409 * Start detaching from all processes to which we previously attached. The 410 * function is expected to return before detaching is completed, and the caller 411 * must deal with the new situation appropriately. Do not touch any processes 412 * started by us (to allow graceful termination), unless force is set, in which 413 * case those processes are killed. 414 */ 415 static void 416 detach_running(int force) 417 { 418 struct trace_proc *proc; 419 420 for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) { 421 if (proc->trace_flags & TF_ATTACH) { 422 /* Already detaching? Then do nothing. */ 423 if (proc->trace_flags & TF_DETACH) 424 continue; 425 426 if (!(proc->trace_flags & TF_STOPPING)) 427 (void)kill(proc->pid, SIGSTOP); 428 429 proc->trace_flags |= TF_DETACH | TF_STOPPING; 430 } else { 431 /* 432 * The child processes may be ignoring SIGINTs, so upon 433 * the second try, force them to terminate. 434 */ 435 if (force) 436 (void)kill(proc->pid, SIGKILL); 437 } 438 } 439 } 440 441 /* 442 * Print command usage. 443 */ 444 static void __dead 445 usage(void) 446 { 447 448 (void)fprintf(stderr, "usage: %s [-fgNstVv] [-o file] [-p pid] " 449 "[command]\n", getprogname()); 450 451 exit(EXIT_FAILURE); 452 } 453 454 /* 455 * The main function of the system call tracer. 456 */ 457 int 458 main(int argc, char * argv[]) 459 { 460 struct trace_proc *proc; 461 const char *output_file; 462 int status, sig, follow_fork, show_stack, grouping, first_signal; 463 pid_t pid, last_pid; 464 int c, error; 465 466 setprogname(argv[0]); 467 468 proc_init(); 469 470 follow_fork = FALSE; 471 show_stack = FALSE; 472 grouping = FALSE; 473 output_file = NULL; 474 475 timestamps = 0; 476 allnames = FALSE; 477 verbose = 0; 478 valuesonly = 0; 479 480 while ((c = getopt(argc, argv, "fgNstVvo:p:")) != -1) { 481 switch (c) { 482 case 'f': 483 follow_fork = TRUE; 484 break; 485 case 'g': 486 grouping = TRUE; 487 break; 488 case 'N': 489 allnames = TRUE; 490 break; 491 case 's': 492 show_stack = TRUE; 493 break; 494 case 't': 495 timestamps++; 496 break; 497 case 'V': 498 valuesonly++; 499 break; 500 case 'v': 501 verbose++; 502 break; 503 case 'o': 504 output_file = optarg; 505 break; 506 case 'p': 507 pid = atoi(optarg); 508 if (pid <= 0) 509 usage(); 510 511 if (proc_get(pid) == NULL && proc_add(pid) == NULL) 512 err(EXIT_FAILURE, NULL); 513 514 break; 515 default: 516 usage(); 517 } 518 } 519 520 argv += optind; 521 argc -= optind; 522 523 first_signal = TRUE; 524 got_signal = FALSE; 525 got_info = FALSE; 526 527 signal(SIGINT, sig_handler); 528 signal(SIGINFO, info_handler); 529 530 /* Attach to any processes for which PIDs were given. */ 531 for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) { 532 if (attach(proc->pid) != 0) { 533 /* 534 * Detach from the processes that we have attached to 535 * so far, i.e. the ones with the TF_ATTACH flag. 536 */ 537 detach_stopped(); 538 539 return EXIT_FAILURE; 540 } 541 542 proc->trace_flags = TF_ATTACH | TF_NOCALL; 543 } 544 545 /* If a command is given, start a child that executes the command. */ 546 if (argc >= 1) { 547 pid = fork(); 548 549 switch (pid) { 550 case -1: 551 warn("Unable to fork"); 552 553 detach_stopped(); 554 555 return EXIT_FAILURE; 556 557 case 0: 558 (void)ptrace(T_OK, 0, 0, 0); 559 560 (void)execvp(argv[0], argv); 561 562 err(EXIT_FAILURE, "Unable to start %s", argv[0]); 563 564 default: 565 break; 566 } 567 568 /* 569 * The first signal will now be SIGTRAP from the execvp(), 570 * unless that fails, in which case the child will terminate. 571 */ 572 if (wait_sig(pid, SIGTRAP) != 0) { 573 /* 574 * If the child exited, the most likely cause is a 575 * failure to execute the command. Let the child 576 * report the error, and do not say anything here. 577 */ 578 if (errno != 0) 579 warn("Unable to start process"); 580 581 detach_stopped(); 582 583 return EXIT_FAILURE; 584 } 585 586 /* If we haven't already, perform the kernel magic check. */ 587 if (proc_count() == 0 && kernel_check(pid) == FALSE) { 588 warnx("Kernel magic check failed, recompile trace(1)"); 589 590 (void)kill(pid, SIGKILL); 591 592 detach_stopped(); 593 594 return EXIT_FAILURE; 595 } 596 597 if ((proc = proc_add(pid)) == NULL) { 598 warn(NULL); 599 600 (void)kill(pid, SIGKILL); 601 602 detach_stopped(); 603 604 return EXIT_FAILURE; 605 } 606 607 proc->trace_flags = 0; 608 } else 609 pid = -1; 610 611 /* The user will have to give us at least one process to trace. */ 612 if (proc_count() == 0) 613 usage(); 614 615 /* 616 * Open an alternative output file if needed. After that, standard 617 * error should no longer be used directly, and all output has to go 618 * through the output module. 619 */ 620 if (output_init(output_file) < 0) { 621 warn("Unable to open output file"); 622 623 if (pid > 0) 624 (void)kill(pid, SIGKILL); 625 626 detach_stopped(); 627 628 return EXIT_FAILURE; 629 } 630 631 /* 632 * All the traced processes are currently stopped. Initialize, report, 633 * and resume them. 634 */ 635 for (proc = proc_next(NULL); proc != NULL; proc = proc_next(proc)) { 636 new_proc(proc, follow_fork); 637 638 (void)ptrace(T_SYSCALL, proc->pid, 0, 0); 639 } 640 641 /* 642 * Handle events until there are no traced processes left. 643 */ 644 last_pid = 0; 645 error = FALSE; 646 647 for (;;) { 648 /* If an output error occurred, exit as soon as possible. */ 649 if (!error && output_error()) { 650 detach_running(TRUE /*force*/); 651 652 error = TRUE; 653 } 654 655 /* 656 * If the user pressed ^C once, start detaching the processes 657 * that we did not start, if any. If the user pressed ^C 658 * twice, kill the process that we did start, if any. 659 */ 660 if (got_signal) { 661 detach_running(!first_signal); 662 663 got_signal = FALSE; 664 first_signal = FALSE; 665 } 666 667 /* Upon getting SIGINFO, print a list of traced processes. */ 668 if (got_info) { 669 list_info(); 670 671 got_info = FALSE; 672 } 673 674 /* 675 * Block until something happens to a traced process. If 676 * enabled from the command line, first try waiting for the 677 * last process for which we got results, so as to reduce call 678 * suspensions a bit. 679 */ 680 if (grouping && last_pid > 0 && 681 waitpid(last_pid, &status, WNOHANG) > 0) 682 pid = last_pid; 683 else 684 if ((pid = waitpid(-1, &status, 0)) <= 0) { 685 if (pid == -1 && errno == EINTR) continue; 686 if (pid == -1 && errno == ECHILD) break; /* all done */ 687 688 put_fmt(NULL, "Unexpected waitpid failure: %s", 689 (pid == 0) ? "No result" : strerror(errno)); 690 put_newline(); 691 692 /* 693 * We need waitpid to function correctly in order to 694 * detach from any attached processes, so we can do 695 * little more than just exit, effectively killing all 696 * traced processes. 697 */ 698 return EXIT_FAILURE; 699 } 700 701 last_pid = 0; 702 703 /* Get the trace data structure for the process. */ 704 if ((proc = proc_get(pid)) == NULL) { 705 /* 706 * The waitpid() call returned the status of a process 707 * that we have not yet seen. This must be a newly 708 * forked child. If it is not stopped, it must have 709 * died immediately, and we choose not to report it. 710 */ 711 if (!WIFSTOPPED(status)) 712 continue; 713 714 if ((proc = proc_add(pid)) == NULL) { 715 put_fmt(NULL, 716 "Error attaching to new child %d: %s", 717 pid, strerror(errno)); 718 put_newline(); 719 720 /* 721 * Out of memory allocating a new child object! 722 * We can not trace this child, so just let it 723 * run free by detaching from it. 724 */ 725 if (WSTOPSIG(status) != SIGSTOP) { 726 (void)ptrace(T_RESUME, pid, 0, 727 WSTOPSIG(status)); 728 729 if (wait_sig(pid, SIGSTOP) != 0) 730 continue; /* it died.. */ 731 } 732 733 (void)ptrace(T_DETACH, pid, 0, 0); 734 735 continue; 736 } 737 738 /* 739 * We must specify TF_ATTACH here, even though it may 740 * be a child of a process we started, in which case it 741 * should be killed when we exit. We do not keep track 742 * of ancestry though, so better safe than sorry. 743 */ 744 proc->trace_flags = TF_ATTACH | TF_STOPPING; 745 746 new_proc(proc, follow_fork); 747 748 /* Repeat entering the fork call for the child. */ 749 handle_call(proc, show_stack); 750 } 751 752 /* If the process died, report its status and clean it up. */ 753 if (!WIFSTOPPED(status)) { 754 discard_proc(proc, status); 755 756 continue; 757 } 758 759 sig = WSTOPSIG(status); 760 761 if (sig == SIGSTOP && (proc->trace_flags & TF_STOPPING)) { 762 /* We expected the process to be stopped; now it is. */ 763 proc->trace_flags &= ~TF_STOPPING; 764 765 if (proc->trace_flags & TF_DETACH) { 766 if (ptrace(T_DETACH, proc->pid, 0, 0) == 0) 767 discard_proc(proc, status); 768 769 /* 770 * If detaching failed, the process must have 771 * died, and we'll get notified through wait(). 772 */ 773 continue; 774 } 775 776 sig = 0; 777 } else if (sig == SIGSTOP && (proc->trace_flags & TF_EXEC)) { 778 /* The process has performed a successful execve(). */ 779 call_leave(proc, TRUE /*skip*/); 780 781 put_text(proc, "---"); 782 783 new_exec(proc); 784 785 /* 786 * A successful execve() has no result, in the sense 787 * that there is no reply message. We should therefore 788 * not even try to copy in the reply message from the 789 * original location, because it will be invalid. 790 * Thus, we skip the exec's call leave phase entirely. 791 */ 792 proc->trace_flags &= ~TF_EXEC; 793 proc->trace_flags |= TF_SKIP; 794 795 sig = 0; 796 } else if (sig == SIGTRAP) { 797 /* The process is entering or leaving a system call. */ 798 if (!(proc->trace_flags & TF_DETACH)) 799 handle_call(proc, show_stack); 800 801 sig = 0; 802 } else { 803 /* The process has received a signal. */ 804 report_signal(proc, sig, show_stack); 805 806 /* 807 * Only in this case do we pass the signal to the 808 * traced process. 809 */ 810 } 811 812 /* 813 * Resume process execution. If this call fails, the process 814 * has probably died. We will find out soon enough. 815 */ 816 (void)ptrace(T_SYSCALL, proc->pid, 0, sig); 817 818 last_pid = proc->pid; 819 } 820 821 return (error) ? EXIT_FAILURE : EXIT_SUCCESS; 822 } 823