1 /*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * Copyright 1997 Sean Eric Fagan 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by Sean Eric Fagan 17 * 4. Neither the name of the author may be used to endorse or promote 18 * products derived from this software without specific prior written 19 * permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 /* 38 * Various setup functions for truss. Not the cleanest-written code, 39 * I'm afraid. 40 */ 41 42 #include <sys/ptrace.h> 43 #include <sys/sysctl.h> 44 #include <sys/time.h> 45 #include <sys/wait.h> 46 47 #include <assert.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <signal.h> 51 #include <stdbool.h> 52 #include <stdint.h> 53 #include <stdio.h> 54 #include <stdlib.h> 55 #include <string.h> 56 #include <sysdecode.h> 57 #include <time.h> 58 #include <unistd.h> 59 60 #include "truss.h" 61 #include "syscall.h" 62 #include "extern.h" 63 64 SET_DECLARE(procabi, struct procabi); 65 66 static sig_atomic_t detaching; 67 68 static void enter_syscall(struct trussinfo *, struct threadinfo *, 69 struct ptrace_lwpinfo *); 70 static void new_proc(struct trussinfo *, pid_t, lwpid_t); 71 72 /* 73 * setup_and_wait() is called to start a process. All it really does 74 * is fork(), enable tracing in the child, and then exec the given 75 * command. At that point, the child process stops, and the parent 76 * can wake up and deal with it. 77 */ 78 void 79 setup_and_wait(struct trussinfo *info, char *command[]) 80 { 81 pid_t pid; 82 83 pid = vfork(); 84 if (pid == -1) 85 err(1, "fork failed"); 86 if (pid == 0) { /* Child */ 87 ptrace(PT_TRACE_ME, 0, 0, 0); 88 execvp(command[0], command); 89 err(1, "execvp %s", command[0]); 90 } 91 92 /* Only in the parent here */ 93 if (waitpid(pid, NULL, 0) < 0) 94 err(1, "unexpect stop in waitpid"); 95 96 new_proc(info, pid, 0); 97 } 98 99 /* 100 * start_tracing is called to attach to an existing process. 101 */ 102 void 103 start_tracing(struct trussinfo *info, pid_t pid) 104 { 105 int ret, retry; 106 107 retry = 10; 108 do { 109 ret = ptrace(PT_ATTACH, pid, NULL, 0); 110 usleep(200); 111 } while (ret && retry-- > 0); 112 if (ret) 113 err(1, "can not attach to target process"); 114 115 if (waitpid(pid, NULL, 0) < 0) 116 err(1, "Unexpect stop in waitpid"); 117 118 new_proc(info, pid, 0); 119 } 120 121 /* 122 * Restore a process back to it's pre-truss state. 123 * Called for SIGINT, SIGTERM, SIGQUIT. This only 124 * applies if truss was told to monitor an already-existing 125 * process. 126 */ 127 void 128 restore_proc(int signo __unused) 129 { 130 131 detaching = 1; 132 } 133 134 static void 135 detach_proc(pid_t pid) 136 { 137 138 /* stop the child so that we can detach */ 139 kill(pid, SIGSTOP); 140 if (waitpid(pid, NULL, 0) < 0) 141 err(1, "Unexpected stop in waitpid"); 142 143 if (ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) 144 err(1, "Can not detach the process"); 145 146 kill(pid, SIGCONT); 147 } 148 149 /* 150 * Determine the ABI. This is called after every exec, and when 151 * a process is first monitored. 152 */ 153 static struct procabi * 154 find_abi(pid_t pid) 155 { 156 struct procabi **pabi; 157 size_t len; 158 int error; 159 int mib[4]; 160 char progt[32]; 161 162 len = sizeof(progt); 163 mib[0] = CTL_KERN; 164 mib[1] = KERN_PROC; 165 mib[2] = KERN_PROC_SV_NAME; 166 mib[3] = pid; 167 error = sysctl(mib, 4, progt, &len, NULL, 0); 168 if (error != 0) 169 err(2, "can not get sysvec name"); 170 171 SET_FOREACH(pabi, procabi) { 172 if (strcmp((*pabi)->type, progt) == 0) 173 return (*pabi); 174 } 175 warnx("ABI %s for pid %ld is not supported", progt, (long)pid); 176 return (NULL); 177 } 178 179 static struct threadinfo * 180 new_thread(struct procinfo *p, lwpid_t lwpid) 181 { 182 struct threadinfo *nt; 183 184 /* 185 * If this happens it means there is a bug in truss. Unfortunately 186 * this will kill any processes truss is attached to. 187 */ 188 LIST_FOREACH(nt, &p->threadlist, entries) { 189 if (nt->tid == lwpid) 190 errx(1, "Duplicate thread for LWP %ld", (long)lwpid); 191 } 192 193 nt = calloc(1, sizeof(struct threadinfo)); 194 if (nt == NULL) 195 err(1, "calloc() failed"); 196 nt->proc = p; 197 nt->tid = lwpid; 198 LIST_INSERT_HEAD(&p->threadlist, nt, entries); 199 return (nt); 200 } 201 202 static void 203 free_thread(struct threadinfo *t) 204 { 205 206 LIST_REMOVE(t, entries); 207 free(t); 208 } 209 210 static void 211 add_threads(struct trussinfo *info, struct procinfo *p) 212 { 213 struct ptrace_lwpinfo pl; 214 struct threadinfo *t; 215 lwpid_t *lwps; 216 int i, nlwps; 217 218 nlwps = ptrace(PT_GETNUMLWPS, p->pid, NULL, 0); 219 if (nlwps == -1) 220 err(1, "Unable to fetch number of LWPs"); 221 assert(nlwps > 0); 222 lwps = calloc(nlwps, sizeof(*lwps)); 223 nlwps = ptrace(PT_GETLWPLIST, p->pid, (caddr_t)lwps, nlwps); 224 if (nlwps == -1) 225 err(1, "Unable to fetch LWP list"); 226 for (i = 0; i < nlwps; i++) { 227 t = new_thread(p, lwps[i]); 228 if (ptrace(PT_LWPINFO, lwps[i], (caddr_t)&pl, sizeof(pl)) == -1) 229 err(1, "ptrace(PT_LWPINFO)"); 230 if (pl.pl_flags & PL_FLAG_SCE) { 231 info->curthread = t; 232 enter_syscall(info, t, &pl); 233 } 234 } 235 free(lwps); 236 } 237 238 static void 239 new_proc(struct trussinfo *info, pid_t pid, lwpid_t lwpid) 240 { 241 struct procinfo *np; 242 243 /* 244 * If this happens it means there is a bug in truss. Unfortunately 245 * this will kill any processes truss is attached to. 246 */ 247 LIST_FOREACH(np, &info->proclist, entries) { 248 if (np->pid == pid) 249 errx(1, "Duplicate process for pid %ld", (long)pid); 250 } 251 252 if (info->flags & FOLLOWFORKS) 253 if (ptrace(PT_FOLLOW_FORK, pid, NULL, 1) == -1) 254 err(1, "Unable to follow forks for pid %ld", (long)pid); 255 if (ptrace(PT_LWP_EVENTS, pid, NULL, 1) == -1) 256 err(1, "Unable to enable LWP events for pid %ld", (long)pid); 257 np = calloc(1, sizeof(struct procinfo)); 258 np->pid = pid; 259 np->abi = find_abi(pid); 260 LIST_INIT(&np->threadlist); 261 LIST_INSERT_HEAD(&info->proclist, np, entries); 262 263 if (lwpid != 0) 264 new_thread(np, lwpid); 265 else 266 add_threads(info, np); 267 } 268 269 static void 270 free_proc(struct procinfo *p) 271 { 272 struct threadinfo *t, *t2; 273 274 LIST_FOREACH_SAFE(t, &p->threadlist, entries, t2) { 275 free(t); 276 } 277 LIST_REMOVE(p, entries); 278 free(p); 279 } 280 281 static void 282 detach_all_procs(struct trussinfo *info) 283 { 284 struct procinfo *p, *p2; 285 286 LIST_FOREACH_SAFE(p, &info->proclist, entries, p2) { 287 detach_proc(p->pid); 288 free_proc(p); 289 } 290 } 291 292 static struct procinfo * 293 find_proc(struct trussinfo *info, pid_t pid) 294 { 295 struct procinfo *np; 296 297 LIST_FOREACH(np, &info->proclist, entries) { 298 if (np->pid == pid) 299 return (np); 300 } 301 302 return (NULL); 303 } 304 305 /* 306 * Change curthread member based on (pid, lwpid). 307 */ 308 static void 309 find_thread(struct trussinfo *info, pid_t pid, lwpid_t lwpid) 310 { 311 struct procinfo *np; 312 struct threadinfo *nt; 313 314 np = find_proc(info, pid); 315 assert(np != NULL); 316 317 LIST_FOREACH(nt, &np->threadlist, entries) { 318 if (nt->tid == lwpid) { 319 info->curthread = nt; 320 return; 321 } 322 } 323 errx(1, "could not find thread"); 324 } 325 326 /* 327 * When a process exits, it should have exactly one thread left. 328 * All of the other threads should have reported thread exit events. 329 */ 330 static void 331 find_exit_thread(struct trussinfo *info, pid_t pid) 332 { 333 struct procinfo *p; 334 335 p = find_proc(info, pid); 336 assert(p != NULL); 337 338 info->curthread = LIST_FIRST(&p->threadlist); 339 assert(info->curthread != NULL); 340 assert(LIST_NEXT(info->curthread, entries) == NULL); 341 } 342 343 static void 344 alloc_syscall(struct threadinfo *t, struct ptrace_lwpinfo *pl) 345 { 346 u_int i; 347 348 assert(t->in_syscall == 0); 349 assert(t->cs.number == 0); 350 assert(t->cs.sc == NULL); 351 assert(t->cs.nargs == 0); 352 for (i = 0; i < nitems(t->cs.s_args); i++) 353 assert(t->cs.s_args[i] == NULL); 354 memset(t->cs.args, 0, sizeof(t->cs.args)); 355 t->cs.number = pl->pl_syscall_code; 356 t->in_syscall = 1; 357 } 358 359 static void 360 free_syscall(struct threadinfo *t) 361 { 362 u_int i; 363 364 for (i = 0; i < t->cs.nargs; i++) 365 free(t->cs.s_args[i]); 366 memset(&t->cs, 0, sizeof(t->cs)); 367 t->in_syscall = 0; 368 } 369 370 static void 371 enter_syscall(struct trussinfo *info, struct threadinfo *t, 372 struct ptrace_lwpinfo *pl) 373 { 374 struct syscall *sc; 375 u_int i, narg; 376 377 alloc_syscall(t, pl); 378 narg = MIN(pl->pl_syscall_narg, nitems(t->cs.args)); 379 if (narg != 0 && t->proc->abi->fetch_args(info, narg) != 0) { 380 free_syscall(t); 381 return; 382 } 383 384 sc = get_syscall(t, t->cs.number, narg); 385 if (sc->unknown) 386 fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n", 387 t->proc->abi->type, t->cs.number); 388 389 t->cs.nargs = sc->nargs; 390 assert(sc->nargs <= nitems(t->cs.s_args)); 391 392 t->cs.sc = sc; 393 394 /* 395 * At this point, we set up the system call arguments. 396 * We ignore any OUT ones, however -- those are arguments that 397 * are set by the system call, and so are probably meaningless 398 * now. This doesn't currently support arguments that are 399 * passed in *and* out, however. 400 */ 401 #if DEBUG 402 fprintf(stderr, "syscall %s(", sc->name); 403 #endif 404 for (i = 0; i < t->cs.nargs; i++) { 405 #if DEBUG 406 fprintf(stderr, "0x%lx%s", t->cs.args[sc->args[i].offset], 407 i < (t->cs.nargs - 1) ? "," : ""); 408 #endif 409 if (!(sc->args[i].type & OUT)) { 410 t->cs.s_args[i] = print_arg(&sc->args[i], 411 t->cs.args, 0, info); 412 } 413 } 414 #if DEBUG 415 fprintf(stderr, ")\n"); 416 #endif 417 418 clock_gettime(CLOCK_REALTIME, &t->before); 419 } 420 421 /* 422 * When a thread exits voluntarily (including when a thread calls 423 * exit() to trigger a process exit), the thread's internal state 424 * holds the arguments passed to the exit system call. When the 425 * thread's exit is reported, log that system call without a return 426 * value. 427 */ 428 static void 429 thread_exit_syscall(struct trussinfo *info) 430 { 431 struct threadinfo *t; 432 433 t = info->curthread; 434 if (!t->in_syscall) 435 return; 436 437 clock_gettime(CLOCK_REALTIME, &t->after); 438 439 print_syscall_ret(info, 0, NULL); 440 free_syscall(t); 441 } 442 443 static void 444 exit_syscall(struct trussinfo *info, struct ptrace_lwpinfo *pl) 445 { 446 struct threadinfo *t; 447 struct procinfo *p; 448 struct syscall *sc; 449 long retval[2]; 450 u_int i; 451 int errorp; 452 453 t = info->curthread; 454 if (!t->in_syscall) 455 return; 456 457 clock_gettime(CLOCK_REALTIME, &t->after); 458 p = t->proc; 459 if (p->abi->fetch_retval(info, retval, &errorp) < 0) { 460 free_syscall(t); 461 return; 462 } 463 464 sc = t->cs.sc; 465 /* 466 * Here, we only look for arguments that have OUT masked in -- 467 * otherwise, they were handled in enter_syscall(). 468 */ 469 for (i = 0; i < sc->nargs; i++) { 470 char *temp; 471 472 if (sc->args[i].type & OUT) { 473 /* 474 * If an error occurred, then don't bother 475 * getting the data; it may not be valid. 476 */ 477 if (errorp) { 478 asprintf(&temp, "0x%lx", 479 t->cs.args[sc->args[i].offset]); 480 } else { 481 temp = print_arg(&sc->args[i], 482 t->cs.args, retval, info); 483 } 484 t->cs.s_args[i] = temp; 485 } 486 } 487 488 print_syscall_ret(info, errorp, retval); 489 free_syscall(t); 490 491 /* 492 * If the process executed a new image, check the ABI. If the 493 * new ABI isn't supported, stop tracing this process. 494 */ 495 if (pl->pl_flags & PL_FLAG_EXEC) { 496 assert(LIST_NEXT(LIST_FIRST(&p->threadlist), entries) == NULL); 497 p->abi = find_abi(p->pid); 498 if (p->abi == NULL) { 499 if (ptrace(PT_DETACH, p->pid, (caddr_t)1, 0) < 0) 500 err(1, "Can not detach the process"); 501 free_proc(p); 502 } 503 } 504 } 505 506 int 507 print_line_prefix(struct trussinfo *info) 508 { 509 struct timespec timediff; 510 struct threadinfo *t; 511 int len; 512 513 len = 0; 514 t = info->curthread; 515 if (info->flags & (FOLLOWFORKS | DISPLAYTIDS)) { 516 if (info->flags & FOLLOWFORKS) 517 len += fprintf(info->outfile, "%5d", t->proc->pid); 518 if ((info->flags & (FOLLOWFORKS | DISPLAYTIDS)) == 519 (FOLLOWFORKS | DISPLAYTIDS)) 520 len += fprintf(info->outfile, " "); 521 if (info->flags & DISPLAYTIDS) 522 len += fprintf(info->outfile, "%6d", t->tid); 523 len += fprintf(info->outfile, ": "); 524 } 525 if (info->flags & ABSOLUTETIMESTAMPS) { 526 timespecsub(&t->after, &info->start_time, &timediff); 527 len += fprintf(info->outfile, "%jd.%09ld ", 528 (intmax_t)timediff.tv_sec, timediff.tv_nsec); 529 } 530 if (info->flags & RELATIVETIMESTAMPS) { 531 timespecsub(&t->after, &t->before, &timediff); 532 len += fprintf(info->outfile, "%jd.%09ld ", 533 (intmax_t)timediff.tv_sec, timediff.tv_nsec); 534 } 535 return (len); 536 } 537 538 static void 539 report_thread_death(struct trussinfo *info) 540 { 541 struct threadinfo *t; 542 543 t = info->curthread; 544 clock_gettime(CLOCK_REALTIME, &t->after); 545 print_line_prefix(info); 546 fprintf(info->outfile, "<thread %ld exited>\n", (long)t->tid); 547 } 548 549 static void 550 report_thread_birth(struct trussinfo *info) 551 { 552 struct threadinfo *t; 553 554 t = info->curthread; 555 clock_gettime(CLOCK_REALTIME, &t->after); 556 t->before = t->after; 557 print_line_prefix(info); 558 fprintf(info->outfile, "<new thread %ld>\n", (long)t->tid); 559 } 560 561 static void 562 report_exit(struct trussinfo *info, siginfo_t *si) 563 { 564 struct threadinfo *t; 565 566 t = info->curthread; 567 clock_gettime(CLOCK_REALTIME, &t->after); 568 print_line_prefix(info); 569 if (si->si_code == CLD_EXITED) 570 fprintf(info->outfile, "process exit, rval = %u\n", 571 si->si_status); 572 else 573 fprintf(info->outfile, "process killed, signal = %u%s\n", 574 si->si_status, si->si_code == CLD_DUMPED ? 575 " (core dumped)" : ""); 576 } 577 578 static void 579 report_new_child(struct trussinfo *info) 580 { 581 struct threadinfo *t; 582 583 t = info->curthread; 584 clock_gettime(CLOCK_REALTIME, &t->after); 585 t->before = t->after; 586 print_line_prefix(info); 587 fprintf(info->outfile, "<new process>\n"); 588 } 589 590 void 591 decode_siginfo(FILE *fp, siginfo_t *si) 592 { 593 const char *str; 594 595 fprintf(fp, " code="); 596 str = sysdecode_sigcode(si->si_signo, si->si_code); 597 if (str == NULL) 598 fprintf(fp, "%d", si->si_code); 599 else 600 fprintf(fp, "%s", str); 601 switch (si->si_code) { 602 case SI_NOINFO: 603 break; 604 case SI_QUEUE: 605 fprintf(fp, " value=%p", si->si_value.sival_ptr); 606 /* FALLTHROUGH */ 607 case SI_USER: 608 case SI_LWP: 609 fprintf(fp, " pid=%jd uid=%jd", (intmax_t)si->si_pid, 610 (intmax_t)si->si_uid); 611 break; 612 case SI_TIMER: 613 fprintf(fp, " value=%p", si->si_value.sival_ptr); 614 fprintf(fp, " timerid=%d", si->si_timerid); 615 fprintf(fp, " overrun=%d", si->si_overrun); 616 if (si->si_errno != 0) 617 fprintf(fp, " errno=%d", si->si_errno); 618 break; 619 case SI_ASYNCIO: 620 fprintf(fp, " value=%p", si->si_value.sival_ptr); 621 break; 622 case SI_MESGQ: 623 fprintf(fp, " value=%p", si->si_value.sival_ptr); 624 fprintf(fp, " mqd=%d", si->si_mqd); 625 break; 626 default: 627 switch (si->si_signo) { 628 case SIGILL: 629 case SIGFPE: 630 case SIGSEGV: 631 case SIGBUS: 632 fprintf(fp, " trapno=%d", si->si_trapno); 633 fprintf(fp, " addr=%p", si->si_addr); 634 break; 635 case SIGCHLD: 636 fprintf(fp, " pid=%jd uid=%jd", (intmax_t)si->si_pid, 637 (intmax_t)si->si_uid); 638 fprintf(fp, " status=%d", si->si_status); 639 break; 640 } 641 } 642 } 643 644 static void 645 report_signal(struct trussinfo *info, siginfo_t *si, struct ptrace_lwpinfo *pl) 646 { 647 struct threadinfo *t; 648 const char *signame; 649 650 t = info->curthread; 651 clock_gettime(CLOCK_REALTIME, &t->after); 652 print_line_prefix(info); 653 signame = sysdecode_signal(si->si_status); 654 if (signame == NULL) 655 signame = "?"; 656 fprintf(info->outfile, "SIGNAL %u (%s)", si->si_status, signame); 657 if (pl->pl_event == PL_EVENT_SIGNAL && pl->pl_flags & PL_FLAG_SI) 658 decode_siginfo(info->outfile, &pl->pl_siginfo); 659 fprintf(info->outfile, "\n"); 660 661 } 662 663 /* 664 * Wait for events until all the processes have exited or truss has been 665 * asked to stop. 666 */ 667 void 668 eventloop(struct trussinfo *info) 669 { 670 struct ptrace_lwpinfo pl; 671 siginfo_t si; 672 int pending_signal; 673 674 while (!LIST_EMPTY(&info->proclist)) { 675 if (detaching) { 676 detach_all_procs(info); 677 return; 678 } 679 680 if (waitid(P_ALL, 0, &si, WTRAPPED | WEXITED) == -1) { 681 if (errno == EINTR) 682 continue; 683 err(1, "Unexpected error from waitid"); 684 } 685 686 assert(si.si_signo == SIGCHLD); 687 688 switch (si.si_code) { 689 case CLD_EXITED: 690 case CLD_KILLED: 691 case CLD_DUMPED: 692 find_exit_thread(info, si.si_pid); 693 if ((info->flags & COUNTONLY) == 0) { 694 if (si.si_code == CLD_EXITED) 695 thread_exit_syscall(info); 696 report_exit(info, &si); 697 } 698 free_proc(info->curthread->proc); 699 info->curthread = NULL; 700 break; 701 case CLD_TRAPPED: 702 if (ptrace(PT_LWPINFO, si.si_pid, (caddr_t)&pl, 703 sizeof(pl)) == -1) 704 err(1, "ptrace(PT_LWPINFO)"); 705 706 if (pl.pl_flags & PL_FLAG_CHILD) { 707 new_proc(info, si.si_pid, pl.pl_lwpid); 708 assert(LIST_FIRST(&info->proclist)->abi != 709 NULL); 710 } else if (pl.pl_flags & PL_FLAG_BORN) 711 new_thread(find_proc(info, si.si_pid), 712 pl.pl_lwpid); 713 find_thread(info, si.si_pid, pl.pl_lwpid); 714 715 if (si.si_status == SIGTRAP && 716 (pl.pl_flags & (PL_FLAG_BORN|PL_FLAG_EXITED| 717 PL_FLAG_SCE|PL_FLAG_SCX)) != 0) { 718 if (pl.pl_flags & PL_FLAG_BORN) { 719 if ((info->flags & COUNTONLY) == 0) 720 report_thread_birth(info); 721 } else if (pl.pl_flags & PL_FLAG_EXITED) { 722 if ((info->flags & COUNTONLY) == 0) 723 report_thread_death(info); 724 free_thread(info->curthread); 725 info->curthread = NULL; 726 } else if (pl.pl_flags & PL_FLAG_SCE) 727 enter_syscall(info, info->curthread, &pl); 728 else if (pl.pl_flags & PL_FLAG_SCX) 729 exit_syscall(info, &pl); 730 pending_signal = 0; 731 } else if (pl.pl_flags & PL_FLAG_CHILD) { 732 if ((info->flags & COUNTONLY) == 0) 733 report_new_child(info); 734 pending_signal = 0; 735 } else { 736 if ((info->flags & NOSIGS) == 0) 737 report_signal(info, &si, &pl); 738 pending_signal = si.si_status; 739 } 740 ptrace(PT_SYSCALL, si.si_pid, (caddr_t)1, 741 pending_signal); 742 break; 743 case CLD_STOPPED: 744 errx(1, "waitid reported CLD_STOPPED"); 745 case CLD_CONTINUED: 746 break; 747 } 748 } 749 } 750