1 /*- 2 * Copyright 1997 Sean Eric Fagan 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. All advertising materials mentioning features or use of this software 13 * must display the following acknowledgement: 14 * This product includes software developed by Sean Eric Fagan 15 * 4. Neither the name of the author may be used to endorse or promote 16 * products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __FBSDID("$FreeBSD$"); 34 35 /* 36 * Various setup functions for truss. Not the cleanest-written code, 37 * I'm afraid. 38 */ 39 40 #include <sys/ptrace.h> 41 #include <sys/sysctl.h> 42 #include <sys/wait.h> 43 44 #include <assert.h> 45 #include <err.h> 46 #include <errno.h> 47 #include <signal.h> 48 #include <stdint.h> 49 #include <stdio.h> 50 #include <stdlib.h> 51 #include <string.h> 52 #include <sysdecode.h> 53 #include <time.h> 54 #include <unistd.h> 55 56 #include "truss.h" 57 #include "syscall.h" 58 #include "extern.h" 59 60 SET_DECLARE(procabi, struct procabi); 61 62 static sig_atomic_t detaching; 63 64 static void enter_syscall(struct trussinfo *, struct threadinfo *, 65 struct ptrace_lwpinfo *); 66 static void new_proc(struct trussinfo *, pid_t, lwpid_t); 67 68 /* 69 * setup_and_wait() is called to start a process. All it really does 70 * is fork(), enable tracing in the child, and then exec the given 71 * command. At that point, the child process stops, and the parent 72 * can wake up and deal with it. 73 */ 74 void 75 setup_and_wait(struct trussinfo *info, char *command[]) 76 { 77 pid_t pid; 78 79 pid = vfork(); 80 if (pid == -1) 81 err(1, "fork failed"); 82 if (pid == 0) { /* Child */ 83 ptrace(PT_TRACE_ME, 0, 0, 0); 84 execvp(command[0], command); 85 err(1, "execvp %s", command[0]); 86 } 87 88 /* Only in the parent here */ 89 if (waitpid(pid, NULL, 0) < 0) 90 err(1, "unexpect stop in waitpid"); 91 92 new_proc(info, pid, 0); 93 } 94 95 /* 96 * start_tracing is called to attach to an existing process. 97 */ 98 void 99 start_tracing(struct trussinfo *info, pid_t pid) 100 { 101 int ret, retry; 102 103 retry = 10; 104 do { 105 ret = ptrace(PT_ATTACH, pid, NULL, 0); 106 usleep(200); 107 } while (ret && retry-- > 0); 108 if (ret) 109 err(1, "can not attach to target process"); 110 111 if (waitpid(pid, NULL, 0) < 0) 112 err(1, "Unexpect stop in waitpid"); 113 114 new_proc(info, pid, 0); 115 } 116 117 /* 118 * Restore a process back to it's pre-truss state. 119 * Called for SIGINT, SIGTERM, SIGQUIT. This only 120 * applies if truss was told to monitor an already-existing 121 * process. 122 */ 123 void 124 restore_proc(int signo __unused) 125 { 126 127 detaching = 1; 128 } 129 130 static void 131 detach_proc(pid_t pid) 132 { 133 134 /* stop the child so that we can detach */ 135 kill(pid, SIGSTOP); 136 if (waitpid(pid, NULL, 0) < 0) 137 err(1, "Unexpected stop in waitpid"); 138 139 if (ptrace(PT_DETACH, pid, (caddr_t)1, 0) < 0) 140 err(1, "Can not detach the process"); 141 142 kill(pid, SIGCONT); 143 } 144 145 /* 146 * Determine the ABI. This is called after every exec, and when 147 * a process is first monitored. 148 */ 149 static struct procabi * 150 find_abi(pid_t pid) 151 { 152 struct procabi **pabi; 153 size_t len; 154 int error; 155 int mib[4]; 156 char progt[32]; 157 158 len = sizeof(progt); 159 mib[0] = CTL_KERN; 160 mib[1] = KERN_PROC; 161 mib[2] = KERN_PROC_SV_NAME; 162 mib[3] = pid; 163 error = sysctl(mib, 4, progt, &len, NULL, 0); 164 if (error != 0) 165 err(2, "can not get sysvec name"); 166 167 SET_FOREACH(pabi, procabi) { 168 if (strcmp((*pabi)->type, progt) == 0) 169 return (*pabi); 170 } 171 warnx("ABI %s for pid %ld is not supported", progt, (long)pid); 172 return (NULL); 173 } 174 175 static struct threadinfo * 176 new_thread(struct procinfo *p, lwpid_t lwpid) 177 { 178 struct threadinfo *nt; 179 180 /* 181 * If this happens it means there is a bug in truss. Unfortunately 182 * this will kill any processes truss is attached to. 183 */ 184 LIST_FOREACH(nt, &p->threadlist, entries) { 185 if (nt->tid == lwpid) 186 errx(1, "Duplicate thread for LWP %ld", (long)lwpid); 187 } 188 189 nt = calloc(1, sizeof(struct threadinfo)); 190 if (nt == NULL) 191 err(1, "calloc() failed"); 192 nt->proc = p; 193 nt->tid = lwpid; 194 LIST_INSERT_HEAD(&p->threadlist, nt, entries); 195 return (nt); 196 } 197 198 static void 199 free_thread(struct threadinfo *t) 200 { 201 202 LIST_REMOVE(t, entries); 203 free(t); 204 } 205 206 static void 207 add_threads(struct trussinfo *info, struct procinfo *p) 208 { 209 struct ptrace_lwpinfo pl; 210 struct threadinfo *t; 211 lwpid_t *lwps; 212 int i, nlwps; 213 214 nlwps = ptrace(PT_GETNUMLWPS, p->pid, NULL, 0); 215 if (nlwps == -1) 216 err(1, "Unable to fetch number of LWPs"); 217 assert(nlwps > 0); 218 lwps = calloc(nlwps, sizeof(*lwps)); 219 nlwps = ptrace(PT_GETLWPLIST, p->pid, (caddr_t)lwps, nlwps); 220 if (nlwps == -1) 221 err(1, "Unable to fetch LWP list"); 222 for (i = 0; i < nlwps; i++) { 223 t = new_thread(p, lwps[i]); 224 if (ptrace(PT_LWPINFO, lwps[i], (caddr_t)&pl, sizeof(pl)) == -1) 225 err(1, "ptrace(PT_LWPINFO)"); 226 if (pl.pl_flags & PL_FLAG_SCE) { 227 info->curthread = t; 228 enter_syscall(info, t, &pl); 229 } 230 } 231 free(lwps); 232 } 233 234 static void 235 new_proc(struct trussinfo *info, pid_t pid, lwpid_t lwpid) 236 { 237 struct procinfo *np; 238 239 /* 240 * If this happens it means there is a bug in truss. Unfortunately 241 * this will kill any processes truss is attached to. 242 */ 243 LIST_FOREACH(np, &info->proclist, entries) { 244 if (np->pid == pid) 245 errx(1, "Duplicate process for pid %ld", (long)pid); 246 } 247 248 if (info->flags & FOLLOWFORKS) 249 if (ptrace(PT_FOLLOW_FORK, pid, NULL, 1) == -1) 250 err(1, "Unable to follow forks for pid %ld", (long)pid); 251 if (ptrace(PT_LWP_EVENTS, pid, NULL, 1) == -1) 252 err(1, "Unable to enable LWP events for pid %ld", (long)pid); 253 np = calloc(1, sizeof(struct procinfo)); 254 np->pid = pid; 255 np->abi = find_abi(pid); 256 LIST_INIT(&np->threadlist); 257 LIST_INSERT_HEAD(&info->proclist, np, entries); 258 259 if (lwpid != 0) 260 new_thread(np, lwpid); 261 else 262 add_threads(info, np); 263 } 264 265 static void 266 free_proc(struct procinfo *p) 267 { 268 struct threadinfo *t, *t2; 269 270 LIST_FOREACH_SAFE(t, &p->threadlist, entries, t2) { 271 free(t); 272 } 273 LIST_REMOVE(p, entries); 274 free(p); 275 } 276 277 static void 278 detach_all_procs(struct trussinfo *info) 279 { 280 struct procinfo *p, *p2; 281 282 LIST_FOREACH_SAFE(p, &info->proclist, entries, p2) { 283 detach_proc(p->pid); 284 free_proc(p); 285 } 286 } 287 288 static struct procinfo * 289 find_proc(struct trussinfo *info, pid_t pid) 290 { 291 struct procinfo *np; 292 293 LIST_FOREACH(np, &info->proclist, entries) { 294 if (np->pid == pid) 295 return (np); 296 } 297 298 return (NULL); 299 } 300 301 /* 302 * Change curthread member based on (pid, lwpid). 303 */ 304 static void 305 find_thread(struct trussinfo *info, pid_t pid, lwpid_t lwpid) 306 { 307 struct procinfo *np; 308 struct threadinfo *nt; 309 310 np = find_proc(info, pid); 311 assert(np != NULL); 312 313 LIST_FOREACH(nt, &np->threadlist, entries) { 314 if (nt->tid == lwpid) { 315 info->curthread = nt; 316 return; 317 } 318 } 319 errx(1, "could not find thread"); 320 } 321 322 /* 323 * When a process exits, it should have exactly one thread left. 324 * All of the other threads should have reported thread exit events. 325 */ 326 static void 327 find_exit_thread(struct trussinfo *info, pid_t pid) 328 { 329 struct procinfo *p; 330 331 p = find_proc(info, pid); 332 assert(p != NULL); 333 334 info->curthread = LIST_FIRST(&p->threadlist); 335 assert(info->curthread != NULL); 336 assert(LIST_NEXT(info->curthread, entries) == NULL); 337 } 338 339 static void 340 alloc_syscall(struct threadinfo *t, struct ptrace_lwpinfo *pl) 341 { 342 u_int i; 343 344 assert(t->in_syscall == 0); 345 assert(t->cs.number == 0); 346 assert(t->cs.name == NULL); 347 assert(t->cs.nargs == 0); 348 for (i = 0; i < nitems(t->cs.s_args); i++) 349 assert(t->cs.s_args[i] == NULL); 350 memset(t->cs.args, 0, sizeof(t->cs.args)); 351 t->cs.number = pl->pl_syscall_code; 352 t->in_syscall = 1; 353 } 354 355 static void 356 free_syscall(struct threadinfo *t) 357 { 358 u_int i; 359 360 for (i = 0; i < t->cs.nargs; i++) 361 free(t->cs.s_args[i]); 362 memset(&t->cs, 0, sizeof(t->cs)); 363 t->in_syscall = 0; 364 } 365 366 static void 367 enter_syscall(struct trussinfo *info, struct threadinfo *t, 368 struct ptrace_lwpinfo *pl) 369 { 370 struct syscall *sc; 371 u_int i, narg; 372 373 alloc_syscall(t, pl); 374 narg = MIN(pl->pl_syscall_narg, nitems(t->cs.args)); 375 if (narg != 0 && t->proc->abi->fetch_args(info, narg) != 0) { 376 free_syscall(t); 377 return; 378 } 379 380 t->cs.name = sysdecode_syscallname(t->proc->abi->abi, t->cs.number); 381 if (t->cs.name == NULL) 382 fprintf(info->outfile, "-- UNKNOWN %s SYSCALL %d --\n", 383 t->proc->abi->type, t->cs.number); 384 385 sc = get_syscall(t->cs.name, narg); 386 t->cs.nargs = sc->nargs; 387 assert(sc->nargs <= nitems(t->cs.s_args)); 388 389 t->cs.sc = sc; 390 391 /* 392 * At this point, we set up the system call arguments. 393 * We ignore any OUT ones, however -- those are arguments that 394 * are set by the system call, and so are probably meaningless 395 * now. This doesn't currently support arguments that are 396 * passed in *and* out, however. 397 */ 398 if (t->cs.name != NULL) { 399 #if DEBUG 400 fprintf(stderr, "syscall %s(", t->cs.name); 401 #endif 402 for (i = 0; i < t->cs.nargs; i++) { 403 #if DEBUG 404 fprintf(stderr, "0x%lx%s", sc ? 405 t->cs.args[sc->args[i].offset] : t->cs.args[i], 406 i < (t->cs.nargs - 1) ? "," : ""); 407 #endif 408 if (!(sc->args[i].type & OUT)) { 409 t->cs.s_args[i] = print_arg(&sc->args[i], 410 t->cs.args, 0, info); 411 } 412 } 413 #if DEBUG 414 fprintf(stderr, ")\n"); 415 #endif 416 } 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 timespecsubt(&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 timespecsubt(&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 static void 591 report_signal(struct trussinfo *info, siginfo_t *si) 592 { 593 struct threadinfo *t; 594 char *signame; 595 596 t = info->curthread; 597 clock_gettime(CLOCK_REALTIME, &t->after); 598 print_line_prefix(info); 599 signame = strsig(si->si_status); 600 fprintf(info->outfile, "SIGNAL %u (%s)\n", si->si_status, 601 signame == NULL ? "?" : signame); 602 } 603 604 /* 605 * Wait for events until all the processes have exited or truss has been 606 * asked to stop. 607 */ 608 void 609 eventloop(struct trussinfo *info) 610 { 611 struct ptrace_lwpinfo pl; 612 siginfo_t si; 613 int pending_signal; 614 615 while (!LIST_EMPTY(&info->proclist)) { 616 if (detaching) { 617 detach_all_procs(info); 618 return; 619 } 620 621 if (waitid(P_ALL, 0, &si, WTRAPPED | WEXITED) == -1) { 622 if (errno == EINTR) 623 continue; 624 err(1, "Unexpected error from waitid"); 625 } 626 627 assert(si.si_signo == SIGCHLD); 628 629 switch (si.si_code) { 630 case CLD_EXITED: 631 case CLD_KILLED: 632 case CLD_DUMPED: 633 find_exit_thread(info, si.si_pid); 634 if ((info->flags & COUNTONLY) == 0) { 635 if (si.si_code == CLD_EXITED) 636 thread_exit_syscall(info); 637 report_exit(info, &si); 638 } 639 free_proc(info->curthread->proc); 640 info->curthread = NULL; 641 break; 642 case CLD_TRAPPED: 643 if (ptrace(PT_LWPINFO, si.si_pid, (caddr_t)&pl, 644 sizeof(pl)) == -1) 645 err(1, "ptrace(PT_LWPINFO)"); 646 647 if (pl.pl_flags & PL_FLAG_CHILD) { 648 new_proc(info, si.si_pid, pl.pl_lwpid); 649 assert(LIST_FIRST(&info->proclist)->abi != 650 NULL); 651 } else if (pl.pl_flags & PL_FLAG_BORN) 652 new_thread(find_proc(info, si.si_pid), 653 pl.pl_lwpid); 654 find_thread(info, si.si_pid, pl.pl_lwpid); 655 656 if (si.si_status == SIGTRAP && 657 (pl.pl_flags & (PL_FLAG_BORN|PL_FLAG_EXITED| 658 PL_FLAG_SCE|PL_FLAG_SCX)) != 0) { 659 if (pl.pl_flags & PL_FLAG_BORN) { 660 if ((info->flags & COUNTONLY) == 0) 661 report_thread_birth(info); 662 } else if (pl.pl_flags & PL_FLAG_EXITED) { 663 if ((info->flags & COUNTONLY) == 0) 664 report_thread_death(info); 665 free_thread(info->curthread); 666 info->curthread = NULL; 667 } else if (pl.pl_flags & PL_FLAG_SCE) 668 enter_syscall(info, info->curthread, &pl); 669 else if (pl.pl_flags & PL_FLAG_SCX) 670 exit_syscall(info, &pl); 671 pending_signal = 0; 672 } else if (pl.pl_flags & PL_FLAG_CHILD) { 673 if ((info->flags & COUNTONLY) == 0) 674 report_new_child(info); 675 pending_signal = 0; 676 } else { 677 if ((info->flags & NOSIGS) == 0) 678 report_signal(info, &si); 679 pending_signal = si.si_status; 680 } 681 ptrace(PT_SYSCALL, si.si_pid, (caddr_t)1, 682 pending_signal); 683 break; 684 case CLD_STOPPED: 685 errx(1, "waitid reported CLD_STOPPED"); 686 case CLD_CONTINUED: 687 break; 688 } 689 } 690 } 691