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