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