strace.c revision a50d2a87a1a8df4471bbd93f2ce9ef0541b1124b
1/* 2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $Id$ 31 */ 32 33#include "defs.h" 34 35#include <sys/types.h> 36#include <stdarg.h> 37#include <signal.h> 38#include <errno.h> 39#include <sys/param.h> 40#include <fcntl.h> 41#include <sys/resource.h> 42#include <sys/wait.h> 43#include <sys/stat.h> 44#include <pwd.h> 45#include <grp.h> 46#include <string.h> 47#include <dirent.h> 48#include <sys/utsname.h> 49#include <asm/unistd.h> 50#if defined(IA64) 51# include <asm/ptrace_offsets.h> 52#endif 53/* In some libc, these aren't declared. Do it ourself: */ 54extern char **environ; 55extern int optind; 56extern char *optarg; 57 58 59#if defined __NR_tkill 60# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 61#else 62 /* kill() may choose arbitrarily the target task of the process group 63 while we later wait on a that specific TID. PID process waits become 64 TID task specific waits for a process under ptrace(2). */ 65# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 66# define my_tkill(tid, sig) kill((tid), (sig)) 67#endif 68 69#undef KERNEL_VERSION 70#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 71 72cflag_t cflag = CFLAG_NONE; 73unsigned int followfork = 0; 74unsigned int ptrace_setoptions = 0; 75unsigned int xflag = 0; 76bool debug_flag = 0; 77bool Tflag = 0; 78bool qflag = 0; 79/* Which WSTOPSIG(status) value marks syscall traps? */ 80static unsigned int syscall_trap_sig = SIGTRAP; 81static unsigned int tflag = 0; 82static bool iflag = 0; 83static bool rflag = 0; 84static bool print_pid_pfx = 0; 85 86/* -I n */ 87enum { 88 INTR_NOT_SET = 0, 89 INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 90 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 91 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 92 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 93 NUM_INTR_OPTS 94}; 95static int opt_intr; 96/* We play with signal mask only if this mode is active: */ 97#define interactive (opt_intr == INTR_WHILE_WAIT) 98 99/* 100 * daemonized_tracer supports -D option. 101 * With this option, strace forks twice. 102 * Unlike normal case, with -D *grandparent* process exec's, 103 * becoming a traced process. Child exits (this prevents traced process 104 * from having children it doesn't expect to have), and grandchild 105 * attaches to grandparent similarly to strace -p PID. 106 * This allows for more transparent interaction in cases 107 * when process and its parent are communicating via signals, 108 * wait() etc. Without -D, strace process gets lodged in between, 109 * disrupting parent<->child link. 110 */ 111static bool daemonized_tracer = 0; 112 113#ifdef USE_SEIZE 114static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 115# define use_seize (post_attach_sigstop == 0) 116#else 117# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 118# define use_seize 0 119#endif 120 121/* Sometimes we want to print only succeeding syscalls. */ 122bool not_failing_only = 0; 123 124/* Show path associated with fd arguments */ 125bool show_fd_path = 0; 126 127/* are we filtering traces based on paths? */ 128bool tracing_paths = 0; 129 130static int exit_code = 0; 131static int strace_child = 0; 132static int strace_tracer_pid = 0; 133 134static char *username = NULL; 135static uid_t run_uid; 136static gid_t run_gid; 137 138unsigned int max_strlen = DEFAULT_STRLEN; 139static unsigned int acolumn = DEFAULT_ACOLUMN; 140static char *acolumn_spaces; 141static char *outfname = NULL; 142static FILE *outf; 143struct tcb *printing_tcp = NULL; 144static unsigned int curcol; 145static struct tcb **tcbtab; 146static unsigned int nprocs, tcbtabsize; 147static const char *progname; 148 149static char *os_release; /* from uname() */ 150 151static int detach(struct tcb *tcp); 152static int trace(void); 153static void cleanup(void); 154static void interrupt(int sig); 155static sigset_t empty_set, blocked_set; 156 157#ifdef HAVE_SIG_ATOMIC_T 158static volatile sig_atomic_t interrupted; 159#else 160static volatile int interrupted; 161#endif 162 163static void 164usage(FILE *ofp, int exitval) 165{ 166 fprintf(ofp, "\ 167usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 168 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 169 [-P path] [PROG [ARGS]]\n\ 170 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 171 [PROG [ARGS]]\n\ 172-c -- count time, calls, and errors for each syscall and report summary\n\ 173-C -- like -c but also print regular output while processes are running\n\ 174-D -- run tracer process as a detached grandchild, not as parent\n\ 175-f -- follow forks, -ff -- with output into separate files\n\ 176-F -- attempt to follow vforks\n\ 177-i -- print instruction pointer at time of syscall\n\ 178-I interruptible\n\ 179 1: no signals are blocked\n\ 180 2: fatal signals are blocked while decoding syscall (default)\n\ 181 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 182 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 183 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 184-q -- suppress messages about attaching, detaching, etc.\n\ 185-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 186-T -- print time spent in each syscall\n\ 187-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 188-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 189-y -- print paths associated with file descriptor arguments\n\ 190-h -- print help message\n\ 191-V -- print version\n\ 192-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 193-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 194 options: trace, abbrev, verbose, raw, signal, read, or write\n\ 195-o file -- send trace output to FILE instead of stderr\n\ 196-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 197-p pid -- trace process with process id PID, may be repeated\n\ 198-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 199-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 200-u username -- run command as username handling setuid and/or setgid\n\ 201-E var=val -- put var=val in the environment for command\n\ 202-E var -- remove var from the environment for command\n\ 203-P path -- trace accesses to path\n\ 204" /* this is broken, so don't document it 205-z -- print only succeeding syscalls\n\ 206 */ 207, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 208 exit(exitval); 209} 210 211static void die(void) __attribute__ ((noreturn)); 212static void die(void) 213{ 214 if (strace_tracer_pid == getpid()) { 215 cflag = 0; 216 cleanup(); 217 } 218 exit(1); 219} 220 221static void verror_msg(int err_no, const char *fmt, va_list p) 222{ 223 char *msg; 224 225 fflush(NULL); 226 227 /* We want to print entire message with single fprintf to ensure 228 * message integrity if stderr is shared with other programs. 229 * Thus we use vasprintf + single fprintf. 230 */ 231 msg = NULL; 232 if (vasprintf(&msg, fmt, p) >= 0) { 233 if (err_no) 234 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 235 else 236 fprintf(stderr, "%s: %s\n", progname, msg); 237 free(msg); 238 } else { 239 /* malloc in vasprintf failed, try it without malloc */ 240 fprintf(stderr, "%s: ", progname); 241 vfprintf(stderr, fmt, p); 242 if (err_no) 243 fprintf(stderr, ": %s\n", strerror(err_no)); 244 else 245 putc('\n', stderr); 246 } 247 /* We don't switch stderr to buffered, thus fprintf(stderr) 248 * always flushes its output and this is not necessary: */ 249 /* fflush(stderr); */ 250} 251 252void error_msg(const char *fmt, ...) 253{ 254 va_list p; 255 va_start(p, fmt); 256 verror_msg(0, fmt, p); 257 va_end(p); 258} 259 260void error_msg_and_die(const char *fmt, ...) 261{ 262 va_list p; 263 va_start(p, fmt); 264 verror_msg(0, fmt, p); 265 die(); 266} 267 268void perror_msg(const char *fmt, ...) 269{ 270 va_list p; 271 va_start(p, fmt); 272 verror_msg(errno, fmt, p); 273 va_end(p); 274} 275 276void perror_msg_and_die(const char *fmt, ...) 277{ 278 va_list p; 279 va_start(p, fmt); 280 verror_msg(errno, fmt, p); 281 die(); 282} 283 284void die_out_of_memory(void) 285{ 286 static bool recursed = 0; 287 if (recursed) 288 exit(1); 289 recursed = 1; 290 error_msg_and_die("Out of memory"); 291} 292 293/* Glue for systems without a MMU that cannot provide fork() */ 294#ifdef HAVE_FORK 295# define strace_vforked 0 296#else 297# define strace_vforked 1 298# define fork() vfork() 299#endif 300 301#ifdef USE_SEIZE 302static int 303ptrace_attach_or_seize(int pid) 304{ 305 int r; 306 if (!use_seize) 307 return ptrace(PTRACE_ATTACH, pid, 0, 0); 308 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 309 if (r) 310 return r; 311 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 312 return r; 313} 314#else 315# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 316#endif 317 318static void 319set_cloexec_flag(int fd) 320{ 321 int flags, newflags; 322 323 flags = fcntl(fd, F_GETFD); 324 if (flags < 0) { 325 /* Can happen only if fd is bad. 326 * Should never happen: if it does, we have a bug 327 * in the caller. Therefore we just abort 328 * instead of propagating the error. 329 */ 330 perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 331 } 332 333 newflags = flags | FD_CLOEXEC; 334 if (flags == newflags) 335 return; 336 337 fcntl(fd, F_SETFD, newflags); /* never fails */ 338} 339 340static void kill_save_errno(pid_t pid, int sig) 341{ 342 int saved_errno = errno; 343 344 (void) kill(pid, sig); 345 errno = saved_errno; 346} 347 348void 349tprintf(const char *fmt, ...) 350{ 351 va_list args; 352 353 va_start(args, fmt); 354 if (outf) { 355 int n = vfprintf(outf, fmt, args); 356 if (n < 0) { 357 if (outf != stderr) 358 perror(outfname == NULL 359 ? "<writing to pipe>" : outfname); 360 } else 361 curcol += n; 362 } 363 va_end(args); 364} 365 366void 367tprints(const char *str) 368{ 369 if (outf) { 370 int n = fputs(str, outf); 371 if (n >= 0) { 372 curcol += strlen(str); 373 return; 374 } 375 if (outf != stderr) 376 perror(outfname == NULL 377 ? "<writing to pipe>" : outfname); 378 } 379} 380 381void 382line_ended(void) 383{ 384 curcol = 0; 385 fflush(outf); 386 if (!printing_tcp) 387 return; 388 printing_tcp->curcol = 0; 389 printing_tcp = NULL; 390} 391 392void 393printleader(struct tcb *tcp) 394{ 395 /* If -ff, "previous tcb we printed" is always the same as current, 396 * because we have per-tcb output files. 397 */ 398 if (followfork >= 2) 399 printing_tcp = tcp; 400 401 if (printing_tcp) { 402 outf = printing_tcp->outf; 403 curcol = printing_tcp->curcol; 404 if (printing_tcp->ptrace_errno) { 405 if (printing_tcp->flags & TCB_INSYSCALL) { 406 tprints(" <unavailable>) "); 407 tabto(); 408 } 409 tprints("= ? <unavailable>\n"); 410 printing_tcp->ptrace_errno = 0; 411 printing_tcp->curcol = 0; 412 } 413 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) { 414 /* 415 * case 1: we have a shared log (i.e. not -ff), and last line 416 * wasn't finished (same or different tcb, doesn't matter). 417 * case 2: split log, we are the same tcb, but our last line 418 * didn't finish ("SIGKILL nuked us after syscall entry" etc). 419 */ 420 tprints(" <unfinished ...>\n"); 421 printing_tcp->flags |= TCB_REPRINT; 422 printing_tcp->curcol = 0; 423 } 424 } 425 426 printing_tcp = tcp; 427 outf = tcp->outf; 428 curcol = 0; 429 430 if (print_pid_pfx) 431 tprintf("%-5d ", tcp->pid); 432 else if (nprocs > 1 && !outfname) 433 tprintf("[pid %5u] ", tcp->pid); 434 435 if (tflag) { 436 char str[sizeof("HH:MM:SS")]; 437 struct timeval tv, dtv; 438 static struct timeval otv; 439 440 gettimeofday(&tv, NULL); 441 if (rflag) { 442 if (otv.tv_sec == 0) 443 otv = tv; 444 tv_sub(&dtv, &tv, &otv); 445 tprintf("%6ld.%06ld ", 446 (long) dtv.tv_sec, (long) dtv.tv_usec); 447 otv = tv; 448 } 449 else if (tflag > 2) { 450 tprintf("%ld.%06ld ", 451 (long) tv.tv_sec, (long) tv.tv_usec); 452 } 453 else { 454 time_t local = tv.tv_sec; 455 strftime(str, sizeof(str), "%T", localtime(&local)); 456 if (tflag > 1) 457 tprintf("%s.%06ld ", str, (long) tv.tv_usec); 458 else 459 tprintf("%s ", str); 460 } 461 } 462 if (iflag) 463 printcall(tcp); 464} 465 466void 467tabto(void) 468{ 469 if (curcol < acolumn) 470 tprints(acolumn_spaces + curcol); 471} 472 473/* 474 * When strace is setuid executable, we have to swap uids 475 * before and after filesystem and process management operations. 476 */ 477static void 478swap_uid(void) 479{ 480 int euid = geteuid(), uid = getuid(); 481 482 if (euid != uid && setreuid(euid, uid) < 0) { 483 perror_msg_and_die("setreuid"); 484 } 485} 486 487#if _LFS64_LARGEFILE 488# define fopen_for_output fopen64 489#else 490# define fopen_for_output fopen 491#endif 492 493static FILE * 494strace_fopen(const char *path) 495{ 496 FILE *fp; 497 498 swap_uid(); 499 fp = fopen_for_output(path, "w"); 500 if (!fp) 501 perror_msg_and_die("Can't fopen '%s'", path); 502 swap_uid(); 503 set_cloexec_flag(fileno(fp)); 504 return fp; 505} 506 507static int popen_pid = 0; 508 509#ifndef _PATH_BSHELL 510# define _PATH_BSHELL "/bin/sh" 511#endif 512 513/* 514 * We cannot use standard popen(3) here because we have to distinguish 515 * popen child process from other processes we trace, and standard popen(3) 516 * does not export its child's pid. 517 */ 518static FILE * 519strace_popen(const char *command) 520{ 521 FILE *fp; 522 int fds[2]; 523 524 swap_uid(); 525 if (pipe(fds) < 0) 526 perror_msg_and_die("pipe"); 527 528 set_cloexec_flag(fds[1]); /* never fails */ 529 530 popen_pid = vfork(); 531 if (popen_pid == -1) 532 perror_msg_and_die("vfork"); 533 534 if (popen_pid == 0) { 535 /* child */ 536 close(fds[1]); 537 if (fds[0] != 0) { 538 if (dup2(fds[0], 0)) 539 perror_msg_and_die("dup2"); 540 close(fds[0]); 541 } 542 execl(_PATH_BSHELL, "sh", "-c", command, NULL); 543 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 544 } 545 546 /* parent */ 547 close(fds[0]); 548 swap_uid(); 549 fp = fdopen(fds[1], "w"); 550 if (!fp) 551 die_out_of_memory(); 552 return fp; 553} 554 555static void 556newoutf(struct tcb *tcp) 557{ 558 if (outfname && followfork >= 2) { 559 char name[520 + sizeof(int) * 3]; 560 sprintf(name, "%.512s.%u", outfname, tcp->pid); 561 tcp->outf = strace_fopen(name); 562 } 563} 564 565static void 566process_opt_p_list(char *opt) 567{ 568 while (*opt) { 569 /* 570 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". 571 * pidof uses space as delim, pgrep uses newline. :( 572 */ 573 int pid; 574 char *delim = opt + strcspn(opt, ", \n\t"); 575 char c = *delim; 576 577 *delim = '\0'; 578 pid = atoi(opt); /* TODO: stricter parsing of the number? */ 579 if (pid <= 0) { 580 error_msg("Invalid process id: '%s'", opt); 581 *delim = c; 582 return; 583 } 584 if (pid == strace_tracer_pid) { 585 error_msg("I'm sorry, I can't let you do that, Dave."); 586 *delim = c; 587 return; 588 } 589 *delim = c; 590 alloc_tcb(pid, 0); 591 if (c == '\0') 592 break; 593 opt = delim + 1; 594 } 595} 596 597static void 598startup_attach(void) 599{ 600 int tcbi; 601 struct tcb *tcp; 602 603 /* 604 * Block user interruptions as we would leave the traced 605 * process stopped (process state T) if we would terminate in 606 * between PTRACE_ATTACH and wait4() on SIGSTOP. 607 * We rely on cleanup() from this point on. 608 */ 609 if (interactive) 610 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 611 612 if (daemonized_tracer) { 613 pid_t pid = fork(); 614 if (pid < 0) { 615 perror_msg_and_die("fork"); 616 } 617 if (pid) { /* parent */ 618 /* 619 * Wait for grandchild to attach to straced process 620 * (grandparent). Grandchild SIGKILLs us after it attached. 621 * Grandparent's wait() is unblocked by our death, 622 * it proceeds to exec the straced program. 623 */ 624 pause(); 625 _exit(0); /* paranoia */ 626 } 627 /* grandchild */ 628 /* We will be the tracer process. Remember our new pid: */ 629 strace_tracer_pid = getpid(); 630 } 631 632 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 633 tcp = tcbtab[tcbi]; 634 635 if (!(tcp->flags & TCB_INUSE)) 636 continue; 637 638 /* Is this a process we should attach to, but not yet attached? */ 639 if (tcp->flags & TCB_ATTACHED) 640 continue; /* no, we already attached it */ 641 642 /* Reinitialize the output since it may have changed */ 643 tcp->outf = outf; 644 newoutf(tcp); 645 646 if (followfork && !daemonized_tracer) { 647 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 648 DIR *dir; 649 650 sprintf(procdir, "/proc/%d/task", tcp->pid); 651 dir = opendir(procdir); 652 if (dir != NULL) { 653 unsigned int ntid = 0, nerr = 0; 654 struct dirent *de; 655 656 while ((de = readdir(dir)) != NULL) { 657 struct tcb *cur_tcp; 658 int tid; 659 660 if (de->d_fileno == 0) 661 continue; 662 tid = atoi(de->d_name); 663 if (tid <= 0) 664 continue; 665 ++ntid; 666 if (ptrace_attach_or_seize(tid) < 0) { 667 ++nerr; 668 if (debug_flag) 669 fprintf(stderr, "attach to pid %d failed\n", tid); 670 continue; 671 } 672 if (debug_flag) 673 fprintf(stderr, "attach to pid %d succeeded\n", tid); 674 cur_tcp = tcp; 675 if (tid != tcp->pid) 676 cur_tcp = alloctcb(tid); 677 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 678 } 679 closedir(dir); 680 if (interactive) { 681 sigprocmask(SIG_SETMASK, &empty_set, NULL); 682 if (interrupted) 683 goto ret; 684 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 685 } 686 ntid -= nerr; 687 if (ntid == 0) { 688 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 689 droptcb(tcp); 690 continue; 691 } 692 if (!qflag) { 693 fprintf(stderr, ntid > 1 694? "Process %u attached with %u threads - interrupt to quit\n" 695: "Process %u attached - interrupt to quit\n", 696 tcp->pid, ntid); 697 } 698 if (!(tcp->flags & TCB_ATTACHED)) { 699 /* -p PID, we failed to attach to PID itself 700 * but did attach to some of its sibling threads. 701 * Drop PID's tcp. 702 */ 703 droptcb(tcp); 704 } 705 continue; 706 } /* if (opendir worked) */ 707 } /* if (-f) */ 708 if (ptrace_attach_or_seize(tcp->pid) < 0) { 709 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 710 droptcb(tcp); 711 continue; 712 } 713 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 714 if (debug_flag) 715 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 716 717 if (daemonized_tracer) { 718 /* 719 * Make parent go away. 720 * Also makes grandparent's wait() unblock. 721 */ 722 kill(getppid(), SIGKILL); 723 } 724 725 if (!qflag) 726 fprintf(stderr, 727 "Process %u attached - interrupt to quit\n", 728 tcp->pid); 729 } /* for each tcbtab[] */ 730 731 ret: 732 if (interactive) 733 sigprocmask(SIG_SETMASK, &empty_set, NULL); 734} 735 736static void 737startup_child(char **argv) 738{ 739 struct stat statbuf; 740 const char *filename; 741 char pathname[MAXPATHLEN]; 742 int pid = 0; 743 struct tcb *tcp; 744 745 filename = argv[0]; 746 if (strchr(filename, '/')) { 747 if (strlen(filename) > sizeof pathname - 1) { 748 errno = ENAMETOOLONG; 749 perror_msg_and_die("exec"); 750 } 751 strcpy(pathname, filename); 752 } 753#ifdef USE_DEBUGGING_EXEC 754 /* 755 * Debuggers customarily check the current directory 756 * first regardless of the path but doing that gives 757 * security geeks a panic attack. 758 */ 759 else if (stat(filename, &statbuf) == 0) 760 strcpy(pathname, filename); 761#endif /* USE_DEBUGGING_EXEC */ 762 else { 763 const char *path; 764 int m, n, len; 765 766 for (path = getenv("PATH"); path && *path; path += m) { 767 const char *colon = strchr(path, ':'); 768 if (colon) { 769 n = colon - path; 770 m = n + 1; 771 } 772 else 773 m = n = strlen(path); 774 if (n == 0) { 775 if (!getcwd(pathname, MAXPATHLEN)) 776 continue; 777 len = strlen(pathname); 778 } 779 else if (n > sizeof pathname - 1) 780 continue; 781 else { 782 strncpy(pathname, path, n); 783 len = n; 784 } 785 if (len && pathname[len - 1] != '/') 786 pathname[len++] = '/'; 787 strcpy(pathname + len, filename); 788 if (stat(pathname, &statbuf) == 0 && 789 /* Accept only regular files 790 with some execute bits set. 791 XXX not perfect, might still fail */ 792 S_ISREG(statbuf.st_mode) && 793 (statbuf.st_mode & 0111)) 794 break; 795 } 796 } 797 if (stat(pathname, &statbuf) < 0) { 798 perror_msg_and_die("Can't stat '%s'", filename); 799 } 800 strace_child = pid = fork(); 801 if (pid < 0) { 802 perror_msg_and_die("fork"); 803 } 804 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 805 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 806 ) { 807 pid = getpid(); 808 if (outf != stderr) 809 close(fileno(outf)); 810 if (!daemonized_tracer && !use_seize) { 811 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 812 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 813 } 814 } 815 816 if (username != NULL) { 817 uid_t run_euid = run_uid; 818 gid_t run_egid = run_gid; 819 820 if (statbuf.st_mode & S_ISUID) 821 run_euid = statbuf.st_uid; 822 if (statbuf.st_mode & S_ISGID) 823 run_egid = statbuf.st_gid; 824 /* 825 * It is important to set groups before we 826 * lose privileges on setuid. 827 */ 828 if (initgroups(username, run_gid) < 0) { 829 perror_msg_and_die("initgroups"); 830 } 831 if (setregid(run_gid, run_egid) < 0) { 832 perror_msg_and_die("setregid"); 833 } 834 if (setreuid(run_uid, run_euid) < 0) { 835 perror_msg_and_die("setreuid"); 836 } 837 } 838 else if (geteuid() != 0) 839 setreuid(run_uid, run_uid); 840 841 if (!daemonized_tracer) { 842 /* 843 * Induce a ptrace stop. Tracer (our parent) 844 * will resume us with PTRACE_SYSCALL and display 845 * the immediately following execve syscall. 846 * Can't do this on NOMMU systems, we are after 847 * vfork: parent is blocked, stopping would deadlock. 848 */ 849 if (!strace_vforked) 850 kill(pid, SIGSTOP); 851 } else { 852 struct sigaction sv_sigchld; 853 sigaction(SIGCHLD, NULL, &sv_sigchld); 854 /* 855 * Make sure it is not SIG_IGN, otherwise wait 856 * will not block. 857 */ 858 signal(SIGCHLD, SIG_DFL); 859 /* 860 * Wait for grandchild to attach to us. 861 * It kills child after that, and wait() unblocks. 862 */ 863 alarm(3); 864 wait(NULL); 865 alarm(0); 866 sigaction(SIGCHLD, &sv_sigchld, NULL); 867 } 868 869 execv(pathname, argv); 870 perror_msg_and_die("exec"); 871 } 872 873 /* We are the tracer */ 874 875 if (!daemonized_tracer) { 876 if (!use_seize) { 877 /* child did PTRACE_TRACEME, nothing to do in parent */ 878 } else { 879 if (!strace_vforked) { 880 /* Wait until child stopped itself */ 881 int status; 882 while (waitpid(pid, &status, WSTOPPED) < 0) { 883 if (errno == EINTR) 884 continue; 885 perror_msg_and_die("waitpid"); 886 } 887 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 888 kill_save_errno(pid, SIGKILL); 889 perror_msg_and_die("Unexpected wait status %x", status); 890 } 891 } 892 /* Else: vforked case, we have no way to sync. 893 * Just attach to it as soon as possible. 894 * This means that we may miss a few first syscalls... 895 */ 896 897 if (ptrace_attach_or_seize(pid)) { 898 kill_save_errno(pid, SIGKILL); 899 perror_msg_and_die("Can't attach to %d", pid); 900 } 901 if (!strace_vforked) 902 kill(pid, SIGCONT); 903 } 904 tcp = alloctcb(pid); 905 if (!strace_vforked) 906 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop; 907 else 908 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP; 909 } 910 else { 911 /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 912 strace_tracer_pid = getpid(); 913 /* The tracee is our parent: */ 914 pid = getppid(); 915 alloctcb(pid); 916 /* attaching will be done later, by startup_attach */ 917 } 918} 919 920/* 921 * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 922 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 923 * and then see which options are supported by the kernel. 924 */ 925static void 926test_ptrace_setoptions_followfork(void) 927{ 928 int pid, expected_grandchild = 0, found_grandchild = 0; 929 const unsigned int test_options = PTRACE_O_TRACECLONE | 930 PTRACE_O_TRACEFORK | 931 PTRACE_O_TRACEVFORK; 932 933 pid = fork(); 934 if (pid < 0) 935 perror_msg_and_die("fork"); 936 if (pid == 0) { 937 pid = getpid(); 938 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 939 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 940 __func__); 941 kill_save_errno(pid, SIGSTOP); 942 if (fork() < 0) 943 perror_msg_and_die("fork"); 944 _exit(0); 945 } 946 947 while (1) { 948 int status, tracee_pid; 949 950 errno = 0; 951 tracee_pid = wait(&status); 952 if (tracee_pid <= 0) { 953 if (errno == EINTR) 954 continue; 955 if (errno == ECHILD) 956 break; 957 kill_save_errno(pid, SIGKILL); 958 perror_msg_and_die("%s: unexpected wait result %d", 959 __func__, tracee_pid); 960 } 961 if (WIFEXITED(status)) { 962 if (WEXITSTATUS(status)) { 963 if (tracee_pid != pid) 964 kill_save_errno(pid, SIGKILL); 965 error_msg_and_die("%s: unexpected exit status %u", 966 __func__, WEXITSTATUS(status)); 967 } 968 continue; 969 } 970 if (WIFSIGNALED(status)) { 971 if (tracee_pid != pid) 972 kill_save_errno(pid, SIGKILL); 973 error_msg_and_die("%s: unexpected signal %u", 974 __func__, WTERMSIG(status)); 975 } 976 if (!WIFSTOPPED(status)) { 977 if (tracee_pid != pid) 978 kill_save_errno(tracee_pid, SIGKILL); 979 kill_save_errno(pid, SIGKILL); 980 error_msg_and_die("%s: unexpected wait status %x", 981 __func__, status); 982 } 983 if (tracee_pid != pid) { 984 found_grandchild = tracee_pid; 985 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 986 kill_save_errno(tracee_pid, SIGKILL); 987 kill_save_errno(pid, SIGKILL); 988 perror_msg_and_die("PTRACE_CONT doesn't work"); 989 } 990 continue; 991 } 992 switch (WSTOPSIG(status)) { 993 case SIGSTOP: 994 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 995 && errno != EINVAL && errno != EIO) 996 perror_msg("PTRACE_SETOPTIONS"); 997 break; 998 case SIGTRAP: 999 if (status >> 16 == PTRACE_EVENT_FORK) { 1000 long msg = 0; 1001 1002 if (ptrace(PTRACE_GETEVENTMSG, pid, 1003 NULL, (long) &msg) == 0) 1004 expected_grandchild = msg; 1005 } 1006 break; 1007 } 1008 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 1009 kill_save_errno(pid, SIGKILL); 1010 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1011 } 1012 } 1013 if (expected_grandchild && expected_grandchild == found_grandchild) { 1014 ptrace_setoptions |= test_options; 1015 if (debug_flag) 1016 fprintf(stderr, "ptrace_setoptions = %#x\n", 1017 ptrace_setoptions); 1018 return; 1019 } 1020 error_msg("Test for PTRACE_O_TRACECLONE failed, " 1021 "giving up using this feature."); 1022} 1023 1024/* 1025 * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 1026 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 1027 * and then see whether it will stop with (SIGTRAP | 0x80). 1028 * 1029 * Use of this option enables correct handling of user-generated SIGTRAPs, 1030 * and SIGTRAPs generated by special instructions such as int3 on x86: 1031 * _start: .globl _start 1032 * int3 1033 * movl $42, %ebx 1034 * movl $1, %eax 1035 * int $0x80 1036 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 1037 */ 1038static void 1039test_ptrace_setoptions_for_all(void) 1040{ 1041 const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 1042 PTRACE_O_TRACEEXEC; 1043 int pid; 1044 int it_worked = 0; 1045 1046 pid = fork(); 1047 if (pid < 0) 1048 perror_msg_and_die("fork"); 1049 1050 if (pid == 0) { 1051 pid = getpid(); 1052 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 1053 /* Note: exits with exitcode 1 */ 1054 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 1055 __func__); 1056 kill(pid, SIGSTOP); 1057 _exit(0); /* parent should see entry into this syscall */ 1058 } 1059 1060 while (1) { 1061 int status, tracee_pid; 1062 1063 errno = 0; 1064 tracee_pid = wait(&status); 1065 if (tracee_pid <= 0) { 1066 if (errno == EINTR) 1067 continue; 1068 kill_save_errno(pid, SIGKILL); 1069 perror_msg_and_die("%s: unexpected wait result %d", 1070 __func__, tracee_pid); 1071 } 1072 if (WIFEXITED(status)) { 1073 if (WEXITSTATUS(status) == 0) 1074 break; 1075 error_msg_and_die("%s: unexpected exit status %u", 1076 __func__, WEXITSTATUS(status)); 1077 } 1078 if (WIFSIGNALED(status)) { 1079 error_msg_and_die("%s: unexpected signal %u", 1080 __func__, WTERMSIG(status)); 1081 } 1082 if (!WIFSTOPPED(status)) { 1083 kill(pid, SIGKILL); 1084 error_msg_and_die("%s: unexpected wait status %x", 1085 __func__, status); 1086 } 1087 if (WSTOPSIG(status) == SIGSTOP) { 1088 /* 1089 * We don't check "options aren't accepted" error. 1090 * If it happens, we'll never get (SIGTRAP | 0x80), 1091 * and thus will decide to not use the option. 1092 * IOW: the outcome of the test will be correct. 1093 */ 1094 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 1095 && errno != EINVAL && errno != EIO) 1096 perror_msg("PTRACE_SETOPTIONS"); 1097 } 1098 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 1099 it_worked = 1; 1100 } 1101 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 1102 kill_save_errno(pid, SIGKILL); 1103 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1104 } 1105 } 1106 1107 if (it_worked) { 1108 syscall_trap_sig = (SIGTRAP | 0x80); 1109 ptrace_setoptions |= test_options; 1110 if (debug_flag) 1111 fprintf(stderr, "ptrace_setoptions = %#x\n", 1112 ptrace_setoptions); 1113 return; 1114 } 1115 1116 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 1117 "giving up using this feature."); 1118} 1119 1120# ifdef USE_SEIZE 1121static void 1122test_ptrace_seize(void) 1123{ 1124 int pid; 1125 1126 pid = fork(); 1127 if (pid < 0) 1128 perror_msg_and_die("fork"); 1129 1130 if (pid == 0) { 1131 pause(); 1132 _exit(0); 1133 } 1134 1135 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 1136 * attaching tracee continues to run unless a trap condition occurs. 1137 * PTRACE_SEIZE doesn't affect signal or group stop state. 1138 */ 1139 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 1140 post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1141 } else if (debug_flag) { 1142 fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 1143 } 1144 1145 kill(pid, SIGKILL); 1146 1147 while (1) { 1148 int status, tracee_pid; 1149 1150 errno = 0; 1151 tracee_pid = waitpid(pid, &status, 0); 1152 if (tracee_pid <= 0) { 1153 if (errno == EINTR) 1154 continue; 1155 perror_msg_and_die("%s: unexpected wait result %d", 1156 __func__, tracee_pid); 1157 } 1158 if (WIFSIGNALED(status)) { 1159 return; 1160 } 1161 error_msg_and_die("%s: unexpected wait status %x", 1162 __func__, status); 1163 } 1164} 1165# else /* !USE_SEIZE */ 1166# define test_ptrace_seize() ((void)0) 1167# endif 1168 1169static void 1170get_os_release(void) 1171{ 1172 struct utsname u; 1173 if (uname(&u) < 0) 1174 perror_msg_and_die("uname"); 1175 os_release = strdup(u.release); 1176 if (!os_release) 1177 die_out_of_memory(); 1178} 1179 1180/* 1181 * Initialization part of main() was eating much stack (~0.5k), 1182 * which was unused after init. 1183 * We can reuse it if we move init code into a separate function. 1184 * 1185 * Don't want main() to inline us and defeat the reason 1186 * we have a separate function. 1187 */ 1188static void __attribute__ ((noinline)) 1189init(int argc, char *argv[]) 1190{ 1191 struct tcb *tcp; 1192 int c; 1193 int optF = 0; 1194 struct sigaction sa; 1195 1196 progname = argv[0] ? argv[0] : "strace"; 1197 1198 strace_tracer_pid = getpid(); 1199 1200 get_os_release(); 1201 1202 /* Allocate the initial tcbtab. */ 1203 tcbtabsize = argc; /* Surely enough for all -p args. */ 1204 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 1205 if (!tcbtab) 1206 die_out_of_memory(); 1207 tcp = calloc(tcbtabsize, sizeof(*tcp)); 1208 if (!tcp) 1209 die_out_of_memory(); 1210 for (c = 0; c < tcbtabsize; c++) 1211 tcbtab[c] = tcp++; 1212 1213 outf = stderr; 1214 set_sortby(DEFAULT_SORTBY); 1215 set_personality(DEFAULT_PERSONALITY); 1216 qualify("trace=all"); 1217 qualify("abbrev=all"); 1218 qualify("verbose=all"); 1219 qualify("signal=all"); 1220 while ((c = getopt(argc, argv, 1221 "+cCdfFhiqrtTvVxyz" 1222 "D" 1223 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 1224 switch (c) { 1225 case 'c': 1226 if (cflag == CFLAG_BOTH) { 1227 error_msg_and_die("-c and -C are mutually exclusive options"); 1228 } 1229 cflag = CFLAG_ONLY_STATS; 1230 break; 1231 case 'C': 1232 if (cflag == CFLAG_ONLY_STATS) { 1233 error_msg_and_die("-c and -C are mutually exclusive options"); 1234 } 1235 cflag = CFLAG_BOTH; 1236 break; 1237 case 'd': 1238 debug_flag = 1; 1239 break; 1240 case 'D': 1241 daemonized_tracer = 1; 1242 break; 1243 case 'F': 1244 optF = 1; 1245 break; 1246 case 'f': 1247 followfork++; 1248 break; 1249 case 'h': 1250 usage(stdout, 0); 1251 break; 1252 case 'i': 1253 iflag = 1; 1254 break; 1255 case 'q': 1256 qflag = 1; 1257 break; 1258 case 'r': 1259 rflag = 1; 1260 /* fall through to tflag++ */ 1261 case 't': 1262 tflag++; 1263 break; 1264 case 'T': 1265 Tflag = 1; 1266 break; 1267 case 'x': 1268 xflag++; 1269 break; 1270 case 'y': 1271 show_fd_path = 1; 1272 break; 1273 case 'v': 1274 qualify("abbrev=none"); 1275 break; 1276 case 'V': 1277 printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 1278 exit(0); 1279 break; 1280 case 'z': 1281 not_failing_only = 1; 1282 break; 1283 case 'a': 1284 acolumn = atoi(optarg); 1285 if (acolumn < 0) 1286 error_msg_and_die("Bad column width '%s'", optarg); 1287 break; 1288 case 'e': 1289 qualify(optarg); 1290 break; 1291 case 'o': 1292 outfname = strdup(optarg); 1293 break; 1294 case 'O': 1295 set_overhead(atoi(optarg)); 1296 break; 1297 case 'p': 1298 process_opt_p_list(optarg); 1299 break; 1300 case 'P': 1301 tracing_paths = 1; 1302 if (pathtrace_select(optarg)) { 1303 error_msg_and_die("Failed to select path '%s'", optarg); 1304 } 1305 break; 1306 case 's': 1307 max_strlen = atoi(optarg); 1308 if (max_strlen < 0) { 1309 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1310 } 1311 break; 1312 case 'S': 1313 set_sortby(optarg); 1314 break; 1315 case 'u': 1316 username = strdup(optarg); 1317 break; 1318 case 'E': 1319 if (putenv(optarg) < 0) 1320 die_out_of_memory(); 1321 break; 1322 case 'I': 1323 opt_intr = atoi(optarg); 1324 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1325 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1326 } 1327 break; 1328 default: 1329 usage(stderr, 1); 1330 break; 1331 } 1332 } 1333 argv += optind; 1334 /* argc -= optind; - no need, argc is not used below */ 1335 1336 acolumn_spaces = malloc(acolumn + 1); 1337 if (!acolumn_spaces) 1338 die_out_of_memory(); 1339 memset(acolumn_spaces, ' ', acolumn); 1340 acolumn_spaces[acolumn] = '\0'; 1341 1342 /* Must have PROG [ARGS], or -p PID. Not both. */ 1343 if (!argv[0] == !nprocs) 1344 usage(stderr, 1); 1345 1346 if (nprocs != 0 && daemonized_tracer) { 1347 error_msg_and_die("-D and -p are mutually exclusive options"); 1348 } 1349 1350 if (!followfork) 1351 followfork = optF; 1352 1353 if (followfork > 1 && cflag) { 1354 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1355 } 1356 1357 /* See if they want to run as another user. */ 1358 if (username != NULL) { 1359 struct passwd *pent; 1360 1361 if (getuid() != 0 || geteuid() != 0) { 1362 error_msg_and_die("You must be root to use the -u option"); 1363 } 1364 pent = getpwnam(username); 1365 if (pent == NULL) { 1366 error_msg_and_die("Cannot find user '%s'", username); 1367 } 1368 run_uid = pent->pw_uid; 1369 run_gid = pent->pw_gid; 1370 } 1371 else { 1372 run_uid = getuid(); 1373 run_gid = getgid(); 1374 } 1375 1376 if (followfork) 1377 test_ptrace_setoptions_followfork(); 1378 test_ptrace_setoptions_for_all(); 1379 test_ptrace_seize(); 1380 1381 /* Check if they want to redirect the output. */ 1382 if (outfname) { 1383 /* See if they want to pipe the output. */ 1384 if (outfname[0] == '|' || outfname[0] == '!') { 1385 /* 1386 * We can't do the <outfname>.PID funny business 1387 * when using popen, so prohibit it. 1388 */ 1389 if (followfork > 1) 1390 error_msg_and_die("Piping the output and -ff are mutually exclusive"); 1391 outf = strace_popen(outfname + 1); 1392 } 1393 else if (followfork <= 1) 1394 outf = strace_fopen(outfname); 1395 } else { 1396 /* -ff without -o FILE is the same as single -f */ 1397 if (followfork > 1) 1398 followfork = 1; 1399 } 1400 1401 if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1402 char *buf = malloc(BUFSIZ); 1403 if (!buf) 1404 die_out_of_memory(); 1405 setvbuf(outf, buf, _IOLBF, BUFSIZ); 1406 } 1407 if (outfname && argv[0]) { 1408 if (!opt_intr) 1409 opt_intr = INTR_NEVER; 1410 qflag = 1; 1411 } 1412 if (!opt_intr) 1413 opt_intr = INTR_WHILE_WAIT; 1414 1415 /* argv[0] -pPID -oFILE Default interactive setting 1416 * yes 0 0 INTR_WHILE_WAIT 1417 * no 1 0 INTR_WHILE_WAIT 1418 * yes 0 1 INTR_NEVER 1419 * no 1 1 INTR_WHILE_WAIT 1420 */ 1421 1422 /* STARTUP_CHILD must be called before the signal handlers get 1423 installed below as they are inherited into the spawned process. 1424 Also we do not need to be protected by them as during interruption 1425 in the STARTUP_CHILD mode we kill the spawned process anyway. */ 1426 if (argv[0]) 1427 startup_child(argv); 1428 1429 sigemptyset(&empty_set); 1430 sigemptyset(&blocked_set); 1431 sa.sa_handler = SIG_IGN; 1432 sigemptyset(&sa.sa_mask); 1433 sa.sa_flags = 0; 1434 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1435 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1436 if (opt_intr != INTR_ANYWHERE) { 1437 if (opt_intr == INTR_BLOCK_TSTP_TOO) 1438 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1439 /* 1440 * In interactive mode (if no -o OUTFILE, or -p PID is used), 1441 * fatal signals are blocked while syscall stop is processed, 1442 * and acted on in between, when waiting for new syscall stops. 1443 * In non-interactive mode, signals are ignored. 1444 */ 1445 if (opt_intr == INTR_WHILE_WAIT) { 1446 sigaddset(&blocked_set, SIGHUP); 1447 sigaddset(&blocked_set, SIGINT); 1448 sigaddset(&blocked_set, SIGQUIT); 1449 sigaddset(&blocked_set, SIGPIPE); 1450 sigaddset(&blocked_set, SIGTERM); 1451 sa.sa_handler = interrupt; 1452 } 1453 /* SIG_IGN, or set handler for these */ 1454 sigaction(SIGHUP, &sa, NULL); 1455 sigaction(SIGINT, &sa, NULL); 1456 sigaction(SIGQUIT, &sa, NULL); 1457 sigaction(SIGPIPE, &sa, NULL); 1458 sigaction(SIGTERM, &sa, NULL); 1459 } 1460 /* Make sure SIGCHLD has the default action so that waitpid 1461 definitely works without losing track of children. The user 1462 should not have given us a bogus state to inherit, but he might 1463 have. Arguably we should detect SIG_IGN here and pass it on 1464 to children, but probably noone really needs that. */ 1465 sa.sa_handler = SIG_DFL; 1466 sigaction(SIGCHLD, &sa, NULL); 1467 1468 if (nprocs != 0 || daemonized_tracer) 1469 startup_attach(); 1470 1471 /* Do we want pids printed in our -o OUTFILE? 1472 * -ff: no (every pid has its own file); or 1473 * -f: yes (there can be more pids in the future); or 1474 * -p PID1,PID2: yes (there are already more than one pid) 1475 */ 1476 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1)); 1477} 1478 1479static void 1480expand_tcbtab(void) 1481{ 1482 /* Allocate some more TCBs and expand the table. 1483 We don't want to relocate the TCBs because our 1484 callers have pointers and it would be a pain. 1485 So tcbtab is a table of pointers. Since we never 1486 free the TCBs, we allocate a single chunk of many. */ 1487 int i = tcbtabsize; 1488 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 1489 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 1490 if (!newtab || !newtcbs) 1491 die_out_of_memory(); 1492 tcbtabsize *= 2; 1493 tcbtab = newtab; 1494 while (i < tcbtabsize) 1495 tcbtab[i++] = newtcbs++; 1496} 1497 1498struct tcb * 1499alloc_tcb(int pid, int command_options_parsed) 1500{ 1501 int i; 1502 struct tcb *tcp; 1503 1504 if (nprocs == tcbtabsize) 1505 expand_tcbtab(); 1506 1507 for (i = 0; i < tcbtabsize; i++) { 1508 tcp = tcbtab[i]; 1509 if ((tcp->flags & TCB_INUSE) == 0) { 1510 memset(tcp, 0, sizeof(*tcp)); 1511 tcp->pid = pid; 1512 tcp->flags = TCB_INUSE; 1513 tcp->outf = outf; /* Initialise to current out file */ 1514#if SUPPORTED_PERSONALITIES > 1 1515 tcp->currpers = current_personality; 1516#endif 1517 nprocs++; 1518 if (debug_flag) 1519 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 1520 if (command_options_parsed) 1521 newoutf(tcp); 1522 return tcp; 1523 } 1524 } 1525 error_msg_and_die("bug in alloc_tcb"); 1526} 1527 1528static struct tcb * 1529pid2tcb(int pid) 1530{ 1531 int i; 1532 1533 if (pid <= 0) 1534 return NULL; 1535 1536 for (i = 0; i < tcbtabsize; i++) { 1537 struct tcb *tcp = tcbtab[i]; 1538 if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 1539 return tcp; 1540 } 1541 1542 return NULL; 1543} 1544 1545void 1546droptcb(struct tcb *tcp) 1547{ 1548 if (tcp->pid == 0) 1549 return; 1550 1551 nprocs--; 1552 if (debug_flag) 1553 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1554 1555 if (printing_tcp == tcp) 1556 printing_tcp = NULL; 1557 1558 if (outfname && followfork >= 2 && tcp->outf) { 1559 if (tcp->curcol != 0) 1560 fprintf(tcp->outf, " <detached>\n"); 1561 fclose(tcp->outf); 1562 } else if (tcp->outf) { 1563 fflush(tcp->outf); 1564 } 1565 1566 memset(tcp, 0, sizeof(*tcp)); 1567} 1568 1569/* detach traced process; continue with sig 1570 * Never call DETACH twice on the same process as both unattached and 1571 * attached-unstopped processes give the same ESRCH. For unattached process we 1572 * would SIGSTOP it and wait for its SIGSTOP notification forever. 1573 */ 1574static int 1575detach(struct tcb *tcp) 1576{ 1577 int error; 1578 int status, sigstop_expected; 1579 1580 if (tcp->flags & TCB_BPTSET) 1581 clearbpt(tcp); 1582 1583 /* 1584 * Linux wrongly insists the child be stopped 1585 * before detaching. Arghh. We go through hoops 1586 * to make a clean break of things. 1587 */ 1588#if defined(SPARC) 1589#undef PTRACE_DETACH 1590#define PTRACE_DETACH PTRACE_SUNDETACH 1591#endif 1592 1593 sigstop_expected = 0; 1594 if (tcp->flags & TCB_ATTACHED) { 1595 /* 1596 * We attached but possibly didn't see the expected SIGSTOP. 1597 * We must catch exactly one as otherwise the detached process 1598 * would be left stopped (process state T). 1599 */ 1600 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 1601 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 1602 if (error == 0) { 1603 /* On a clear day, you can see forever. */ 1604 } 1605 else if (errno != ESRCH) { 1606 /* Shouldn't happen. */ 1607 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1608 } 1609 else if (my_tkill(tcp->pid, 0) < 0) { 1610 if (errno != ESRCH) 1611 perror("detach: checking sanity"); 1612 } 1613 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) { 1614 if (errno != ESRCH) 1615 perror("detach: stopping child"); 1616 } 1617 else 1618 sigstop_expected = 1; 1619 } 1620 1621 if (sigstop_expected) { 1622 for (;;) { 1623#ifdef __WALL 1624 if (waitpid(tcp->pid, &status, __WALL) < 0) { 1625 if (errno == ECHILD) /* Already gone. */ 1626 break; 1627 if (errno != EINVAL) { 1628 perror("detach: waiting"); 1629 break; 1630 } 1631#endif /* __WALL */ 1632 /* No __WALL here. */ 1633 if (waitpid(tcp->pid, &status, 0) < 0) { 1634 if (errno != ECHILD) { 1635 perror("detach: waiting"); 1636 break; 1637 } 1638#ifdef __WCLONE 1639 /* If no processes, try clones. */ 1640 if (waitpid(tcp->pid, &status, __WCLONE) < 0) { 1641 if (errno != ECHILD) 1642 perror("detach: waiting"); 1643 break; 1644 } 1645#endif /* __WCLONE */ 1646 } 1647#ifdef __WALL 1648 } 1649#endif 1650 if (!WIFSTOPPED(status)) { 1651 /* Au revoir, mon ami. */ 1652 break; 1653 } 1654 if (WSTOPSIG(status) == SIGSTOP) { 1655 ptrace_restart(PTRACE_DETACH, tcp, 0); 1656 break; 1657 } 1658 error = ptrace_restart(PTRACE_CONT, tcp, 1659 WSTOPSIG(status) == syscall_trap_sig ? 0 1660 : WSTOPSIG(status)); 1661 if (error < 0) 1662 break; 1663 } 1664 } 1665 1666 if (!qflag && (tcp->flags & TCB_ATTACHED)) 1667 fprintf(stderr, "Process %u detached\n", tcp->pid); 1668 1669 droptcb(tcp); 1670 1671 return error; 1672} 1673 1674static void 1675cleanup(void) 1676{ 1677 int i; 1678 struct tcb *tcp; 1679 int fatal_sig; 1680 1681 /* 'interrupted' is a volatile object, fetch it only once */ 1682 fatal_sig = interrupted; 1683 if (!fatal_sig) 1684 fatal_sig = SIGTERM; 1685 1686 for (i = 0; i < tcbtabsize; i++) { 1687 tcp = tcbtab[i]; 1688 if (!(tcp->flags & TCB_INUSE)) 1689 continue; 1690 if (debug_flag) 1691 fprintf(stderr, 1692 "cleanup: looking at pid %u\n", tcp->pid); 1693 if (tcp->flags & TCB_STRACE_CHILD) { 1694 kill(tcp->pid, SIGCONT); 1695 kill(tcp->pid, fatal_sig); 1696 } 1697 detach(tcp); 1698 } 1699 if (cflag) 1700 call_summary(outf); 1701} 1702 1703static void 1704interrupt(int sig) 1705{ 1706 interrupted = sig; 1707} 1708 1709#ifndef HAVE_STRERROR 1710 1711#if !HAVE_DECL_SYS_ERRLIST 1712extern int sys_nerr; 1713extern char *sys_errlist[]; 1714#endif /* HAVE_DECL_SYS_ERRLIST */ 1715 1716const char * 1717strerror(int err_no) 1718{ 1719 static char buf[sizeof("Unknown error %d") + sizeof(int)*3]; 1720 1721 if (err_no < 1 || err_no >= sys_nerr) { 1722 sprintf(buf, "Unknown error %d", err_no); 1723 return buf; 1724 } 1725 return sys_errlist[err_no]; 1726} 1727 1728#endif /* HAVE_STERRROR */ 1729 1730#ifndef HAVE_STRSIGNAL 1731 1732#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 1733extern char *sys_siglist[]; 1734#endif 1735#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 1736extern char *_sys_siglist[]; 1737#endif 1738 1739const char * 1740strsignal(int sig) 1741{ 1742 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3]; 1743 1744 if (sig < 1 || sig >= NSIG) { 1745 sprintf(buf, "Unknown signal %d", sig); 1746 return buf; 1747 } 1748#ifdef HAVE__SYS_SIGLIST 1749 return _sys_siglist[sig]; 1750#else 1751 return sys_siglist[sig]; 1752#endif 1753} 1754 1755#endif /* HAVE_STRSIGNAL */ 1756 1757static int 1758trace(void) 1759{ 1760 struct rusage ru; 1761 struct rusage *rup = cflag ? &ru : NULL; 1762# ifdef __WALL 1763 static int wait4_options = __WALL; 1764# endif 1765 1766 while (nprocs != 0) { 1767 int pid; 1768 int wait_errno; 1769 int status, sig; 1770 int stopped; 1771 struct tcb *tcp; 1772 unsigned event; 1773 1774 if (interrupted) 1775 return 0; 1776 if (interactive) 1777 sigprocmask(SIG_SETMASK, &empty_set, NULL); 1778# ifdef __WALL 1779 pid = wait4(-1, &status, wait4_options, rup); 1780 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 1781 /* this kernel does not support __WALL */ 1782 wait4_options &= ~__WALL; 1783 pid = wait4(-1, &status, wait4_options, rup); 1784 } 1785 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 1786 /* most likely a "cloned" process */ 1787 pid = wait4(-1, &status, __WCLONE, rup); 1788 if (pid < 0) { 1789 perror_msg("wait4(__WCLONE) failed"); 1790 } 1791 } 1792# else 1793 pid = wait4(-1, &status, 0, rup); 1794# endif /* __WALL */ 1795 wait_errno = errno; 1796 if (interactive) 1797 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1798 1799 if (pid < 0) { 1800 switch (wait_errno) { 1801 case EINTR: 1802 continue; 1803 case ECHILD: 1804 /* 1805 * We would like to verify this case 1806 * but sometimes a race in Solbourne's 1807 * version of SunOS sometimes reports 1808 * ECHILD before sending us SIGCHILD. 1809 */ 1810 return 0; 1811 default: 1812 errno = wait_errno; 1813 perror_msg("wait"); 1814 return -1; 1815 } 1816 } 1817 if (pid == popen_pid) { 1818 if (WIFEXITED(status) || WIFSIGNALED(status)) 1819 popen_pid = 0; 1820 continue; 1821 } 1822 1823 event = ((unsigned)status >> 16); 1824 if (debug_flag) { 1825 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 1826 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16]; 1827 strcpy(buf, "???"); 1828 if (WIFSIGNALED(status)) 1829#ifdef WCOREDUMP 1830 sprintf(buf, "WIFSIGNALED,%ssig=%s", 1831 WCOREDUMP(status) ? "core," : "", 1832 signame(WTERMSIG(status))); 1833#else 1834 sprintf(buf, "WIFSIGNALED,sig=%s", 1835 signame(WTERMSIG(status))); 1836#endif 1837 if (WIFEXITED(status)) 1838 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 1839 if (WIFSTOPPED(status)) 1840 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 1841#ifdef WIFCONTINUED 1842 if (WIFCONTINUED(status)) 1843 strcpy(buf, "WIFCONTINUED"); 1844#endif 1845 evbuf[0] = '\0'; 1846 if (event != 0) { 1847 static const char *const event_names[] = { 1848 [PTRACE_EVENT_CLONE] = "CLONE", 1849 [PTRACE_EVENT_FORK] = "FORK", 1850 [PTRACE_EVENT_VFORK] = "VFORK", 1851 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 1852 [PTRACE_EVENT_EXEC] = "EXEC", 1853 [PTRACE_EVENT_EXIT] = "EXIT", 1854 }; 1855 const char *e; 1856 if (event < ARRAY_SIZE(event_names)) 1857 e = event_names[event]; 1858 else { 1859 sprintf(buf, "?? (%u)", event); 1860 e = buf; 1861 } 1862 sprintf(evbuf, ",PTRACE_EVENT_%s", e); 1863 } 1864 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf); 1865 } 1866 1867 /* Look up 'pid' in our table. */ 1868 tcp = pid2tcb(pid); 1869 1870 /* Under Linux, execve changes pid to thread leader's pid, 1871 * and we see this changed pid on EVENT_EXEC and later, 1872 * execve sysexit. Leader "disappears" without exit 1873 * notification. Let user know that, drop leader's tcb, 1874 * and fix up pid in execve thread's tcb. 1875 * Effectively, execve thread's tcb replaces leader's tcb. 1876 * 1877 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 1878 * on exit syscall) in multithreaded programs exactly 1879 * in order to handle this case. 1880 * 1881 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 1882 * On 2.6 and earlier, it can return garbage. 1883 */ 1884 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') { 1885 long old_pid = 0; 1886 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 1887 && old_pid > 0 1888 && old_pid != pid 1889 ) { 1890 struct tcb *execve_thread = pid2tcb(old_pid); 1891 if (tcp) { 1892 outf = tcp->outf; 1893 curcol = tcp->curcol; 1894 if (execve_thread) { 1895 if (execve_thread->curcol != 0) { 1896 /* 1897 * One case we are here is -ff: 1898 * try "strace -oLOG -ff test/threaded_execve" 1899 */ 1900 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid); 1901 execve_thread->curcol = 0; 1902 } 1903 /* swap output FILEs (needed for -ff) */ 1904 tcp->outf = execve_thread->outf; 1905 tcp->curcol = execve_thread->curcol; 1906 execve_thread->outf = outf; 1907 execve_thread->curcol = curcol; 1908 } 1909 droptcb(tcp); 1910 } 1911 tcp = execve_thread; 1912 if (tcp) { 1913 tcp->pid = pid; 1914 tcp->flags |= TCB_REPRINT; 1915 if (!cflag) { 1916 printleader(tcp); 1917 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 1918 line_ended(); 1919 } 1920 } 1921 } 1922 } 1923 1924 if (tcp == NULL) { 1925 if (followfork) { 1926 /* This is needed to go with the CLONE_PTRACE 1927 changes in process.c/util.c: we might see 1928 the child's initial trap before we see the 1929 parent return from the clone syscall. 1930 Leave the child suspended until the parent 1931 returns from its system call. Only then 1932 will we have the association of parent and 1933 child so that we know how to do clearbpt 1934 in the child. */ 1935 tcp = alloctcb(pid); 1936 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 1937 if (!qflag) 1938 fprintf(stderr, "Process %d attached\n", 1939 pid); 1940 } 1941 else 1942 /* This can happen if a clone call used 1943 CLONE_PTRACE itself. */ 1944 { 1945 if (WIFSTOPPED(status)) 1946 ptrace(PTRACE_CONT, pid, (char *) 0, 0); 1947 error_msg_and_die("Unknown pid: %u", pid); 1948 } 1949 } 1950 1951 /* Set current output file */ 1952 outf = tcp->outf; 1953 curcol = tcp->curcol; 1954 1955 if (cflag) { 1956 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 1957 tcp->stime = ru.ru_stime; 1958 } 1959 1960 if (WIFSIGNALED(status)) { 1961 if (pid == strace_child) 1962 exit_code = 0x100 | WTERMSIG(status); 1963 if (cflag != CFLAG_ONLY_STATS 1964 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 1965 printleader(tcp); 1966#ifdef WCOREDUMP 1967 tprintf("+++ killed by %s %s+++\n", 1968 signame(WTERMSIG(status)), 1969 WCOREDUMP(status) ? "(core dumped) " : ""); 1970#else 1971 tprintf("+++ killed by %s +++\n", 1972 signame(WTERMSIG(status))); 1973#endif 1974 line_ended(); 1975 } 1976 droptcb(tcp); 1977 continue; 1978 } 1979 if (WIFEXITED(status)) { 1980 if (pid == strace_child) 1981 exit_code = WEXITSTATUS(status); 1982 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 1983 printleader(tcp); 1984 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 1985 line_ended(); 1986 } 1987 droptcb(tcp); 1988 continue; 1989 } 1990 if (!WIFSTOPPED(status)) { 1991 fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 1992 droptcb(tcp); 1993 continue; 1994 } 1995 1996 /* Is this the very first time we see this tracee stopped? */ 1997 if (tcp->flags & TCB_STARTUP) { 1998 if (debug_flag) 1999 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 2000 tcp->flags &= ~TCB_STARTUP; 2001 if (tcp->flags & TCB_BPTSET) { 2002 /* 2003 * One example is a breakpoint inherited from 2004 * parent through fork(). 2005 */ 2006 if (clearbpt(tcp) < 0) { 2007 /* Pretty fatal */ 2008 droptcb(tcp); 2009 cleanup(); 2010 return -1; 2011 } 2012 } 2013 if (ptrace_setoptions) { 2014 if (debug_flag) 2015 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 2016 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 2017 if (errno != ESRCH) { 2018 /* Should never happen, really */ 2019 perror_msg_and_die("PTRACE_SETOPTIONS"); 2020 } 2021 } 2022 } 2023 } 2024 2025 sig = WSTOPSIG(status); 2026 2027 if (event != 0) { 2028 /* Ptrace event */ 2029#ifdef USE_SEIZE 2030 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 2031 /* 2032 * PTRACE_INTERRUPT-stop or group-stop. 2033 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 2034 */ 2035 if (sig == SIGSTOP 2036 || sig == SIGTSTP 2037 || sig == SIGTTIN 2038 || sig == SIGTTOU 2039 ) { 2040 stopped = 1; 2041 goto show_stopsig; 2042 } 2043 } 2044#endif 2045 goto restart_tracee_with_sig_0; 2046 } 2047 2048 /* Is this post-attach SIGSTOP? 2049 * Interestingly, the process may stop 2050 * with STOPSIG equal to some other signal 2051 * than SIGSTOP if we happend to attach 2052 * just before the process takes a signal. 2053 */ 2054 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2055 if (debug_flag) 2056 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2057 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 2058 goto restart_tracee_with_sig_0; 2059 } 2060 2061 if (sig != syscall_trap_sig) { 2062 siginfo_t si; 2063 2064 /* Nonzero (true) if tracee is stopped by signal 2065 * (as opposed to "tracee received signal"). 2066 */ 2067 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 2068#ifdef USE_SEIZE 2069 show_stopsig: 2070#endif 2071 if (cflag != CFLAG_ONLY_STATS 2072 && (qual_flags[sig] & QUAL_SIGNAL)) { 2073#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 2074 long pc = 0; 2075 long psr = 0; 2076 2077 upeek(tcp, PT_CR_IPSR, &psr); 2078 upeek(tcp, PT_CR_IIP, &pc); 2079 2080# define PSR_RI 41 2081 pc += (psr >> PSR_RI) & 0x3; 2082# define PC_FORMAT_STR " @ %lx" 2083# define PC_FORMAT_ARG , pc 2084#else 2085# define PC_FORMAT_STR "" 2086# define PC_FORMAT_ARG /* nothing */ 2087#endif 2088 printleader(tcp); 2089 if (!stopped) { 2090 tprints("--- "); 2091 printsiginfo(&si, verbose(tcp)); 2092 tprintf(" (%s)" PC_FORMAT_STR " ---\n", 2093 strsignal(sig) 2094 PC_FORMAT_ARG); 2095 } else 2096 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n", 2097 strsignal(sig), 2098 signame(sig) 2099 PC_FORMAT_ARG); 2100 line_ended(); 2101 } 2102 2103 if (!stopped) 2104 /* It's signal-delivery-stop. Inject the signal */ 2105 goto restart_tracee; 2106 2107 /* It's group-stop */ 2108#ifdef USE_SEIZE 2109 if (use_seize) { 2110 /* 2111 * This ends ptrace-stop, but does *not* end group-stop. 2112 * This makes stopping signals work properly on straced process 2113 * (that is, process really stops. It used to continue to run). 2114 */ 2115 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 2116 cleanup(); 2117 return -1; 2118 } 2119 tcp->curcol = curcol; 2120 continue; 2121 } 2122 /* We don't have PTRACE_LISTEN support... */ 2123#endif 2124 goto restart_tracee; 2125 } 2126 2127 /* We handled quick cases, we are permitted to interrupt now. */ 2128 if (interrupted) 2129 return 0; 2130 2131 /* This should be syscall entry or exit. 2132 * (Or it still can be that pesky post-execve SIGTRAP!) 2133 * Handle it. 2134 */ 2135 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2136 /* ptrace() failed in trace_syscall() with ESRCH. 2137 * Likely a result of process disappearing mid-flight. 2138 * Observed case: exit_group() terminating 2139 * all processes in thread group. 2140 * We assume that ptrace error was caused by process death. 2141 * We used to detach(tcp) here, but since we no longer 2142 * implement "detach before death" policy/hack, 2143 * we can let this process to report its death to us 2144 * normally, via WIFEXITED or WIFSIGNALED wait status. 2145 */ 2146 tcp->curcol = curcol; 2147 continue; 2148 } 2149 restart_tracee_with_sig_0: 2150 sig = 0; 2151 restart_tracee: 2152 /* Remember current print column before continuing. */ 2153 tcp->curcol = curcol; 2154 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 2155 cleanup(); 2156 return -1; 2157 } 2158 } 2159 return 0; 2160} 2161 2162int 2163main(int argc, char *argv[]) 2164{ 2165 init(argc, argv); 2166 2167 /* Run main tracing loop */ 2168 if (trace() < 0) 2169 return 1; 2170 2171 cleanup(); 2172 fflush(NULL); 2173 if (exit_code > 0xff) { 2174 /* Avoid potential core file clobbering. */ 2175 struct rlimit rlim = {0, 0}; 2176 setrlimit(RLIMIT_CORE, &rlim); 2177 2178 /* Child was killed by a signal, mimic that. */ 2179 exit_code &= 0xff; 2180 signal(exit_code, SIG_DFL); 2181 raise(exit_code); 2182 /* Paranoia - what if this signal is not fatal? 2183 Exit with 128 + signo then. */ 2184 exit_code += 128; 2185 } 2186 2187 return exit_code; 2188} 2189