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