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