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