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