strace.c revision cdab1becb03eeae442719027fc26a17da464e5de
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 * $Id$ 31 */ 32 33#include "defs.h" 34 35#include <sys/types.h> 36#include <stdarg.h> 37#include <signal.h> 38#include <errno.h> 39#include <sys/param.h> 40#include <fcntl.h> 41#include <sys/resource.h> 42#include <sys/wait.h> 43#include <sys/stat.h> 44#include <pwd.h> 45#include <grp.h> 46#include <string.h> 47#include <dirent.h> 48#include <sys/utsname.h> 49 50#ifdef LINUX 51# include <asm/unistd.h> 52# if defined __NR_tkill 53# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 54# else 55 /* kill() may choose arbitrarily the target task of the process group 56 while we later wait on a that specific TID. PID process waits become 57 TID task specific waits for a process under ptrace(2). */ 58# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 59# define my_tkill(tid, sig) kill((tid), (sig)) 60# endif 61#endif 62 63#if defined(IA64) && defined(LINUX) 64# include <asm/ptrace_offsets.h> 65#endif 66 67#ifdef USE_PROCFS 68#include <poll.h> 69#endif 70 71#ifdef SVR4 72#include <sys/stropts.h> 73#ifdef HAVE_MP_PROCFS 74#ifdef HAVE_SYS_UIO_H 75#include <sys/uio.h> 76#endif 77#endif 78#endif 79extern char **environ; 80extern int optind; 81extern char *optarg; 82 83 84int debug = 0, followfork = 0; 85unsigned int ptrace_setoptions = 0; 86/* Which WSTOPSIG(status) value marks syscall traps? */ 87static unsigned int syscall_trap_sig = SIGTRAP; 88int dtime = 0, xflag = 0, qflag = 0; 89cflag_t cflag = CFLAG_NONE; 90static int iflag = 0, pflag_seen = 0, rflag = 0, tflag = 0; 91 92/* -I n */ 93enum { 94 INTR_NOT_SET = 0, 95 INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 96 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 97 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 98 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 99 NUM_INTR_OPTS 100}; 101static int opt_intr; 102/* We play with signal mask only if this mode is active: */ 103#define interactive (opt_intr == INTR_WHILE_WAIT) 104 105/* 106 * daemonized_tracer supports -D option. 107 * With this option, strace forks twice. 108 * Unlike normal case, with -D *grandparent* process exec's, 109 * becoming a traced process. Child exits (this prevents traced process 110 * from having children it doesn't expect to have), and grandchild 111 * attaches to grandparent similarly to strace -p PID. 112 * This allows for more transparent interaction in cases 113 * when process and its parent are communicating via signals, 114 * wait() etc. Without -D, strace process gets lodged in between, 115 * disrupting parent<->child link. 116 */ 117static bool daemonized_tracer = 0; 118 119#ifdef USE_SEIZE 120static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 121# define use_seize (post_attach_sigstop == 0) 122#else 123# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 124# define use_seize 0 125#endif 126 127/* Sometimes we want to print only succeeding syscalls. */ 128int not_failing_only = 0; 129 130/* Show path associated with fd arguments */ 131int show_fd_path = 0; 132 133/* are we filtering traces based on paths? */ 134int tracing_paths = 0; 135 136static int exit_code = 0; 137static int strace_child = 0; 138static int strace_tracer_pid = 0; 139 140static char *username = NULL; 141static uid_t run_uid; 142static gid_t run_gid; 143 144int max_strlen = DEFAULT_STRLEN; 145static int acolumn = DEFAULT_ACOLUMN; 146static char *acolumn_spaces; 147static char *outfname = NULL; 148static FILE *outf; 149struct tcb *printing_tcp = NULL; 150static int curcol; 151static struct tcb **tcbtab; 152static unsigned int nprocs, tcbtabsize; 153static const char *progname; 154 155static char *os_release; /* from uname() */ 156 157static int detach(struct tcb *tcp); 158static int trace(void); 159static void cleanup(void); 160static void interrupt(int sig); 161static sigset_t empty_set, blocked_set; 162 163#ifdef HAVE_SIG_ATOMIC_T 164static volatile sig_atomic_t interrupted; 165#else 166static volatile int interrupted; 167#endif 168 169#ifdef USE_PROCFS 170 171static struct tcb *pfd2tcb(int pfd); 172static void reaper(int sig); 173static void rebuild_pollv(void); 174static struct pollfd *pollv; 175 176#ifndef HAVE_POLLABLE_PROCFS 177 178static void proc_poll_open(void); 179static void proc_poller(int pfd); 180 181struct proc_pollfd { 182 int fd; 183 int revents; 184 int pid; 185}; 186 187static int poller_pid; 188static int proc_poll_pipe[2] = { -1, -1 }; 189 190#endif /* !HAVE_POLLABLE_PROCFS */ 191 192#ifdef HAVE_MP_PROCFS 193#define POLLWANT POLLWRNORM 194#else 195#define POLLWANT POLLPRI 196#endif 197#endif /* USE_PROCFS */ 198 199static void 200usage(FILE *ofp, int exitval) 201{ 202 fprintf(ofp, "\ 203usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 204 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 205 [-P path] [PROG [ARGS]]\n\ 206 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 207 [PROG [ARGS]]\n\ 208-c -- count time, calls, and errors for each syscall and report summary\n\ 209-C -- like -c but also print regular output while processes are running\n\ 210-D -- run tracer process as a detached grandchild, not as parent\n\ 211-f -- follow forks, -ff -- with output into separate files\n\ 212-F -- attempt to follow vforks\n\ 213-i -- print instruction pointer at time of syscall\n\ 214-I interruptible\n\ 215 1: no signals are blocked\n\ 216 2: fatal signals are blocked while decoding syscall (default)\n\ 217 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 218 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 219 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 220-q -- suppress messages about attaching, detaching, etc.\n\ 221-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 222-T -- print time spent in each syscall\n\ 223-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 224-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 225-y -- print paths associated with file descriptor arguments\n\ 226-h -- print help message\n\ 227-V -- print version\n\ 228-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 229-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 230 options: trace, abbrev, verbose, raw, signal, read, or write\n\ 231-o file -- send trace output to FILE instead of stderr\n\ 232-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 233-p pid -- trace process with process id PID, may be repeated\n\ 234-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 235-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 236-u username -- run command as username handling setuid and/or setgid\n\ 237-E var=val -- put var=val in the environment for command\n\ 238-E var -- remove var from the environment for command\n\ 239-P path -- trace accesses to path\n\ 240" /* this is broken, so don't document it 241-z -- print only succeeding syscalls\n\ 242 */ 243, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 244 exit(exitval); 245} 246 247static void die(void) __attribute__ ((noreturn)); 248static void die(void) 249{ 250 if (strace_tracer_pid == getpid()) { 251 cflag = 0; 252 cleanup(); 253 } 254 exit(1); 255} 256 257static void verror_msg(int err_no, const char *fmt, va_list p) 258{ 259 char *msg; 260 261 fflush(NULL); 262 263 /* We want to print entire message with single fprintf to ensure 264 * message integrity if stderr is shared with other programs. 265 * Thus we use vasprintf + single fprintf. 266 */ 267 msg = NULL; 268 if (vasprintf(&msg, fmt, p) >= 0) { 269 if (err_no) 270 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 271 else 272 fprintf(stderr, "%s: %s\n", progname, msg); 273 free(msg); 274 } else { 275 /* malloc in vasprintf failed, try it without malloc */ 276 fprintf(stderr, "%s: ", progname); 277 vfprintf(stderr, fmt, p); 278 if (err_no) 279 fprintf(stderr, ": %s\n", strerror(err_no)); 280 else 281 putc('\n', stderr); 282 } 283 /* We don't switch stderr to buffered, thus fprintf(stderr) 284 * always flushes its output and this is not necessary: */ 285 /* fflush(stderr); */ 286} 287 288void error_msg(const char *fmt, ...) 289{ 290 va_list p; 291 va_start(p, fmt); 292 verror_msg(0, fmt, p); 293 va_end(p); 294} 295 296void error_msg_and_die(const char *fmt, ...) 297{ 298 va_list p; 299 va_start(p, fmt); 300 verror_msg(0, fmt, p); 301 die(); 302} 303 304void perror_msg(const char *fmt, ...) 305{ 306 va_list p; 307 va_start(p, fmt); 308 verror_msg(errno, fmt, p); 309 va_end(p); 310} 311 312void perror_msg_and_die(const char *fmt, ...) 313{ 314 va_list p; 315 va_start(p, fmt); 316 verror_msg(errno, fmt, p); 317 die(); 318} 319 320void die_out_of_memory(void) 321{ 322 static bool recursed = 0; 323 if (recursed) 324 exit(1); 325 recursed = 1; 326 error_msg_and_die("Out of memory"); 327} 328 329#ifdef SVR4 330#ifdef MIPS 331void 332foobar() 333{ 334} 335#endif /* MIPS */ 336#endif /* SVR4 */ 337 338/* Glue for systems without a MMU that cannot provide fork() */ 339#ifdef HAVE_FORK 340# define strace_vforked 0 341#else 342# define strace_vforked 1 343# define fork() vfork() 344#endif 345 346#ifdef USE_SEIZE 347static int 348ptrace_attach_or_seize(int pid) 349{ 350 int r; 351 if (!use_seize) 352 return ptrace(PTRACE_ATTACH, pid, 0, 0); 353 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 354 if (r) 355 return r; 356 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 357 return r; 358} 359#else 360# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 361#endif 362 363static void 364set_cloexec_flag(int fd) 365{ 366 int flags, newflags; 367 368 flags = fcntl(fd, F_GETFD); 369 if (flags < 0) { 370 /* Can happen only if fd is bad. 371 * Should never happen: if it does, we have a bug 372 * in the caller. Therefore we just abort 373 * instead of propagating the error. 374 */ 375 perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 376 } 377 378 newflags = flags | FD_CLOEXEC; 379 if (flags == newflags) 380 return; 381 382 fcntl(fd, F_SETFD, newflags); /* never fails */ 383} 384 385/* 386 * When strace is setuid executable, we have to swap uids 387 * before and after filesystem and process management operations. 388 */ 389static void 390swap_uid(void) 391{ 392#ifndef SVR4 393 int euid = geteuid(), uid = getuid(); 394 395 if (euid != uid && setreuid(euid, uid) < 0) { 396 perror_msg_and_die("setreuid"); 397 } 398#endif 399} 400 401#if _LFS64_LARGEFILE 402# define fopen_for_output fopen64 403#else 404# define fopen_for_output fopen 405#endif 406 407static FILE * 408strace_fopen(const char *path) 409{ 410 FILE *fp; 411 412 swap_uid(); 413 fp = fopen_for_output(path, "w"); 414 if (!fp) 415 perror_msg_and_die("Can't fopen '%s'", path); 416 swap_uid(); 417 set_cloexec_flag(fileno(fp)); 418 return fp; 419} 420 421static int popen_pid = 0; 422 423#ifndef _PATH_BSHELL 424# define _PATH_BSHELL "/bin/sh" 425#endif 426 427/* 428 * We cannot use standard popen(3) here because we have to distinguish 429 * popen child process from other processes we trace, and standard popen(3) 430 * does not export its child's pid. 431 */ 432static FILE * 433strace_popen(const char *command) 434{ 435 FILE *fp; 436 int fds[2]; 437 438 swap_uid(); 439 if (pipe(fds) < 0) 440 perror_msg_and_die("pipe"); 441 442 set_cloexec_flag(fds[1]); /* never fails */ 443 444 popen_pid = vfork(); 445 if (popen_pid == -1) 446 perror_msg_and_die("vfork"); 447 448 if (popen_pid == 0) { 449 /* child */ 450 close(fds[1]); 451 if (fds[0] != 0) { 452 if (dup2(fds[0], 0)) 453 perror_msg_and_die("dup2"); 454 close(fds[0]); 455 } 456 execl(_PATH_BSHELL, "sh", "-c", command, NULL); 457 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 458 } 459 460 /* parent */ 461 close(fds[0]); 462 swap_uid(); 463 fp = fdopen(fds[1], "w"); 464 if (!fp) 465 die_out_of_memory(); 466 return fp; 467} 468 469static void 470newoutf(struct tcb *tcp) 471{ 472 if (outfname && followfork > 1) { 473 char name[520 + sizeof(int) * 3]; 474 sprintf(name, "%.512s.%u", outfname, tcp->pid); 475 tcp->outf = strace_fopen(name); 476 } 477} 478 479static void 480startup_attach(void) 481{ 482 int tcbi; 483 struct tcb *tcp; 484 485 /* 486 * Block user interruptions as we would leave the traced 487 * process stopped (process state T) if we would terminate in 488 * between PTRACE_ATTACH and wait4() on SIGSTOP. 489 * We rely on cleanup() from this point on. 490 */ 491 if (interactive) 492 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 493 494 if (daemonized_tracer) { 495 pid_t pid = fork(); 496 if (pid < 0) { 497 perror_msg_and_die("fork"); 498 } 499 if (pid) { /* parent */ 500 /* 501 * Wait for grandchild to attach to straced process 502 * (grandparent). Grandchild SIGKILLs us after it attached. 503 * Grandparent's wait() is unblocked by our death, 504 * it proceeds to exec the straced program. 505 */ 506 pause(); 507 _exit(0); /* paranoia */ 508 } 509 /* grandchild */ 510 /* We will be the tracer process. Remember our new pid: */ 511 strace_tracer_pid = getpid(); 512 } 513 514 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 515 tcp = tcbtab[tcbi]; 516 517 /* Is this a process we should attach to, but not yet attached? */ 518 if ((tcp->flags & (TCB_ATTACHED | TCB_STARTUP)) != TCB_ATTACHED) 519 continue; /* no */ 520 521 /* Reinitialize the output since it may have changed */ 522 tcp->outf = outf; 523 newoutf(tcp); 524 525#ifdef USE_PROCFS 526 if (proc_open(tcp, 1) < 0) { 527 fprintf(stderr, "trouble opening proc file\n"); 528 droptcb(tcp); 529 continue; 530 } 531#else /* !USE_PROCFS */ 532# ifdef LINUX 533 if (followfork && !daemonized_tracer) { 534 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 535 DIR *dir; 536 537 sprintf(procdir, "/proc/%d/task", tcp->pid); 538 dir = opendir(procdir); 539 if (dir != NULL) { 540 unsigned int ntid = 0, nerr = 0; 541 struct dirent *de; 542 543 while ((de = readdir(dir)) != NULL) { 544 struct tcb *cur_tcp; 545 int tid; 546 547 if (de->d_fileno == 0) 548 continue; 549 tid = atoi(de->d_name); 550 if (tid <= 0) 551 continue; 552 ++ntid; 553 if (ptrace_attach_or_seize(tid) < 0) { 554 ++nerr; 555 if (debug) 556 fprintf(stderr, "attach to pid %d failed\n", tid); 557 continue; 558 } 559 if (debug) 560 fprintf(stderr, "attach to pid %d succeeded\n", tid); 561 cur_tcp = tcp; 562 if (tid != tcp->pid) 563 cur_tcp = alloctcb(tid); 564 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 565 } 566 closedir(dir); 567 if (interactive) { 568 sigprocmask(SIG_SETMASK, &empty_set, NULL); 569 if (interrupted) 570 goto ret; 571 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 572 } 573 ntid -= nerr; 574 if (ntid == 0) { 575 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 576 droptcb(tcp); 577 continue; 578 } 579 if (!qflag) { 580 fprintf(stderr, ntid > 1 581? "Process %u attached with %u threads - interrupt to quit\n" 582: "Process %u attached - interrupt to quit\n", 583 tcp->pid, ntid); 584 } 585 if (!(tcp->flags & TCB_STARTUP)) { 586 /* -p PID, we failed to attach to PID itself 587 * but did attach to some of its sibling threads. 588 * Drop PID's tcp. 589 */ 590 droptcb(tcp); 591 } 592 continue; 593 } /* if (opendir worked) */ 594 } /* if (-f) */ 595# endif /* LINUX */ 596 if (ptrace_attach_or_seize(tcp->pid) < 0) { 597 perror("attach: ptrace(PTRACE_ATTACH, ...)"); 598 droptcb(tcp); 599 continue; 600 } 601 tcp->flags |= TCB_STARTUP | post_attach_sigstop; 602 if (debug) 603 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 604 605 if (daemonized_tracer) { 606 /* 607 * It is our grandparent we trace, not a -p PID. 608 * Don't want to just detach on exit, so... 609 */ 610 tcp->flags &= ~TCB_ATTACHED; 611 /* 612 * Make parent go away. 613 * Also makes grandparent's wait() unblock. 614 */ 615 kill(getppid(), SIGKILL); 616 } 617 618#endif /* !USE_PROCFS */ 619 if (!qflag) 620 fprintf(stderr, 621 "Process %u attached - interrupt to quit\n", 622 tcp->pid); 623 } /* for each tcbtab[] */ 624 625 ret: 626 if (interactive) 627 sigprocmask(SIG_SETMASK, &empty_set, NULL); 628} 629 630static void 631startup_child(char **argv) 632{ 633 struct stat statbuf; 634 const char *filename; 635 char pathname[MAXPATHLEN]; 636 int pid = 0; 637 struct tcb *tcp; 638 639 filename = argv[0]; 640 if (strchr(filename, '/')) { 641 if (strlen(filename) > sizeof pathname - 1) { 642 errno = ENAMETOOLONG; 643 perror_msg_and_die("exec"); 644 } 645 strcpy(pathname, filename); 646 } 647#ifdef USE_DEBUGGING_EXEC 648 /* 649 * Debuggers customarily check the current directory 650 * first regardless of the path but doing that gives 651 * security geeks a panic attack. 652 */ 653 else if (stat(filename, &statbuf) == 0) 654 strcpy(pathname, filename); 655#endif /* USE_DEBUGGING_EXEC */ 656 else { 657 const char *path; 658 int m, n, len; 659 660 for (path = getenv("PATH"); path && *path; path += m) { 661 const char *colon = strchr(path, ':'); 662 if (colon) { 663 n = colon - path; 664 m = n + 1; 665 } 666 else 667 m = n = strlen(path); 668 if (n == 0) { 669 if (!getcwd(pathname, MAXPATHLEN)) 670 continue; 671 len = strlen(pathname); 672 } 673 else if (n > sizeof pathname - 1) 674 continue; 675 else { 676 strncpy(pathname, path, n); 677 len = n; 678 } 679 if (len && pathname[len - 1] != '/') 680 pathname[len++] = '/'; 681 strcpy(pathname + len, filename); 682 if (stat(pathname, &statbuf) == 0 && 683 /* Accept only regular files 684 with some execute bits set. 685 XXX not perfect, might still fail */ 686 S_ISREG(statbuf.st_mode) && 687 (statbuf.st_mode & 0111)) 688 break; 689 } 690 } 691 if (stat(pathname, &statbuf) < 0) { 692 perror_msg_and_die("Can't stat '%s'", filename); 693 } 694 strace_child = pid = fork(); 695 if (pid < 0) { 696 perror_msg_and_die("fork"); 697 } 698 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 699 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 700 ) { 701 pid = getpid(); 702 if (outf != stderr) 703 close(fileno(outf)); 704#ifdef USE_PROCFS 705# ifdef MIPS 706 /* Kludge for SGI, see proc_open for details. */ 707 sa.sa_handler = foobar; 708 sa.sa_flags = 0; 709 sigemptyset(&sa.sa_mask); 710 sigaction(SIGINT, &sa, NULL); 711# endif 712# ifndef FREEBSD 713 pause(); 714# else 715 kill(pid, SIGSTOP); 716# endif 717#else /* !USE_PROCFS */ 718 if (!daemonized_tracer && !use_seize) { 719 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 720 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 721 } 722 } 723 724 if (username != NULL) { 725 uid_t run_euid = run_uid; 726 gid_t run_egid = run_gid; 727 728 if (statbuf.st_mode & S_ISUID) 729 run_euid = statbuf.st_uid; 730 if (statbuf.st_mode & S_ISGID) 731 run_egid = statbuf.st_gid; 732 /* 733 * It is important to set groups before we 734 * lose privileges on setuid. 735 */ 736 if (initgroups(username, run_gid) < 0) { 737 perror_msg_and_die("initgroups"); 738 } 739 if (setregid(run_gid, run_egid) < 0) { 740 perror_msg_and_die("setregid"); 741 } 742 if (setreuid(run_uid, run_euid) < 0) { 743 perror_msg_and_die("setreuid"); 744 } 745 } 746 else if (geteuid() != 0) 747 setreuid(run_uid, run_uid); 748 749 if (!daemonized_tracer) { 750 /* 751 * Induce a ptrace stop. Tracer (our parent) 752 * will resume us with PTRACE_SYSCALL and display 753 * the immediately following execve syscall. 754 * Can't do this on NOMMU systems, we are after 755 * vfork: parent is blocked, stopping would deadlock. 756 */ 757 if (!strace_vforked) 758 kill(pid, SIGSTOP); 759 } else { 760 struct sigaction sv_sigchld; 761 sigaction(SIGCHLD, NULL, &sv_sigchld); 762 /* 763 * Make sure it is not SIG_IGN, otherwise wait 764 * will not block. 765 */ 766 signal(SIGCHLD, SIG_DFL); 767 /* 768 * Wait for grandchild to attach to us. 769 * It kills child after that, and wait() unblocks. 770 */ 771 alarm(3); 772 wait(NULL); 773 alarm(0); 774 sigaction(SIGCHLD, &sv_sigchld, NULL); 775 } 776#endif /* !USE_PROCFS */ 777 778 execv(pathname, argv); 779 perror_msg_and_die("exec"); 780 } 781 782 /* We are the tracer */ 783 784 if (!daemonized_tracer) { 785 if (!use_seize) { 786 /* child did PTRACE_TRACEME, nothing to do in parent */ 787 } else { 788 if (!strace_vforked) { 789 /* Wait until child stopped itself */ 790 int status; 791 while (waitpid(pid, &status, WSTOPPED) < 0) { 792 if (errno == EINTR) 793 continue; 794 perror_msg_and_die("waitpid"); 795 } 796 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 797 kill(pid, SIGKILL); 798 perror_msg_and_die("Unexpected wait status %x", status); 799 } 800 } 801 /* Else: vforked case, we have no way to sync. 802 * Just attach to it as soon as possible. 803 * This means that we may miss a few first syscalls... 804 */ 805 806 if (ptrace_attach_or_seize(pid)) { 807 kill(pid, SIGKILL); 808 perror_msg_and_die("Can't attach to %d", pid); 809 } 810 if (!strace_vforked) 811 kill(pid, SIGCONT); 812 } 813 tcp = alloctcb(pid); 814 if (!strace_vforked) 815 tcp->flags |= TCB_STARTUP | post_attach_sigstop; 816 else 817 tcp->flags |= TCB_STARTUP; 818 } 819 else { 820 /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 821 strace_tracer_pid = getpid(); 822 /* The tracee is our parent: */ 823 pid = getppid(); 824 tcp = alloctcb(pid); 825 /* We want subsequent startup_attach() to attach to it: */ 826 tcp->flags |= TCB_ATTACHED; 827 } 828#ifdef USE_PROCFS 829 if (proc_open(tcp, 0) < 0) { 830 perror_msg_and_die("trouble opening proc file"); 831 } 832#endif 833} 834 835#ifdef LINUX 836static void kill_save_errno(pid_t pid, int sig) 837{ 838 int saved_errno = errno; 839 840 (void) kill(pid, sig); 841 errno = saved_errno; 842} 843 844/* 845 * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 846 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 847 * and then see which options are supported by the kernel. 848 */ 849static void 850test_ptrace_setoptions_followfork(void) 851{ 852 int pid, expected_grandchild = 0, found_grandchild = 0; 853 const unsigned int test_options = PTRACE_O_TRACECLONE | 854 PTRACE_O_TRACEFORK | 855 PTRACE_O_TRACEVFORK; 856 857 pid = fork(); 858 if (pid < 0) 859 perror_msg_and_die("fork"); 860 if (pid == 0) { 861 pid = getpid(); 862 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 863 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 864 __func__); 865 kill(pid, SIGSTOP); 866 if (fork() < 0) 867 perror_msg_and_die("fork"); 868 _exit(0); 869 } 870 871 while (1) { 872 int status, tracee_pid; 873 874 errno = 0; 875 tracee_pid = wait(&status); 876 if (tracee_pid <= 0) { 877 if (errno == EINTR) 878 continue; 879 else if (errno == ECHILD) 880 break; 881 kill_save_errno(pid, SIGKILL); 882 perror_msg_and_die("%s: unexpected wait result %d", 883 __func__, tracee_pid); 884 } 885 if (WIFEXITED(status)) { 886 if (WEXITSTATUS(status)) { 887 if (tracee_pid != pid) 888 kill_save_errno(pid, SIGKILL); 889 error_msg_and_die("%s: unexpected exit status %u", 890 __func__, WEXITSTATUS(status)); 891 } 892 continue; 893 } 894 if (WIFSIGNALED(status)) { 895 if (tracee_pid != pid) 896 kill_save_errno(pid, SIGKILL); 897 error_msg_and_die("%s: unexpected signal %u", 898 __func__, WTERMSIG(status)); 899 } 900 if (!WIFSTOPPED(status)) { 901 if (tracee_pid != pid) 902 kill_save_errno(tracee_pid, SIGKILL); 903 kill(pid, SIGKILL); 904 error_msg_and_die("%s: unexpected wait status %x", 905 __func__, status); 906 } 907 if (tracee_pid != pid) { 908 found_grandchild = tracee_pid; 909 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 910 kill_save_errno(tracee_pid, SIGKILL); 911 kill_save_errno(pid, SIGKILL); 912 perror_msg_and_die("PTRACE_CONT doesn't work"); 913 } 914 continue; 915 } 916 switch (WSTOPSIG(status)) { 917 case SIGSTOP: 918 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 919 && errno != EINVAL && errno != EIO) 920 perror_msg("PTRACE_SETOPTIONS"); 921 break; 922 case SIGTRAP: 923 if (status >> 16 == PTRACE_EVENT_FORK) { 924 long msg = 0; 925 926 if (ptrace(PTRACE_GETEVENTMSG, pid, 927 NULL, (long) &msg) == 0) 928 expected_grandchild = msg; 929 } 930 break; 931 } 932 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 933 kill_save_errno(pid, SIGKILL); 934 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 935 } 936 } 937 if (expected_grandchild && expected_grandchild == found_grandchild) { 938 ptrace_setoptions |= test_options; 939 if (debug) 940 fprintf(stderr, "ptrace_setoptions = %#x\n", 941 ptrace_setoptions); 942 return; 943 } 944 error_msg("Test for PTRACE_O_TRACECLONE failed, " 945 "giving up using this feature."); 946} 947 948/* 949 * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 950 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 951 * and then see whether it will stop with (SIGTRAP | 0x80). 952 * 953 * Use of this option enables correct handling of user-generated SIGTRAPs, 954 * and SIGTRAPs generated by special instructions such as int3 on x86: 955 * _start: .globl _start 956 * int3 957 * movl $42, %ebx 958 * movl $1, %eax 959 * int $0x80 960 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 961 */ 962static void 963test_ptrace_setoptions_for_all(void) 964{ 965 const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 966 PTRACE_O_TRACEEXEC; 967 int pid; 968 int it_worked = 0; 969 970 pid = fork(); 971 if (pid < 0) 972 perror_msg_and_die("fork"); 973 974 if (pid == 0) { 975 pid = getpid(); 976 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 977 /* Note: exits with exitcode 1 */ 978 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 979 __func__); 980 kill(pid, SIGSTOP); 981 _exit(0); /* parent should see entry into this syscall */ 982 } 983 984 while (1) { 985 int status, tracee_pid; 986 987 errno = 0; 988 tracee_pid = wait(&status); 989 if (tracee_pid <= 0) { 990 if (errno == EINTR) 991 continue; 992 kill_save_errno(pid, SIGKILL); 993 perror_msg_and_die("%s: unexpected wait result %d", 994 __func__, tracee_pid); 995 } 996 if (WIFEXITED(status)) { 997 if (WEXITSTATUS(status) == 0) 998 break; 999 error_msg_and_die("%s: unexpected exit status %u", 1000 __func__, WEXITSTATUS(status)); 1001 } 1002 if (WIFSIGNALED(status)) { 1003 error_msg_and_die("%s: unexpected signal %u", 1004 __func__, WTERMSIG(status)); 1005 } 1006 if (!WIFSTOPPED(status)) { 1007 kill(pid, SIGKILL); 1008 error_msg_and_die("%s: unexpected wait status %x", 1009 __func__, status); 1010 } 1011 if (WSTOPSIG(status) == SIGSTOP) { 1012 /* 1013 * We don't check "options aren't accepted" error. 1014 * If it happens, we'll never get (SIGTRAP | 0x80), 1015 * and thus will decide to not use the option. 1016 * IOW: the outcome of the test will be correct. 1017 */ 1018 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 1019 && errno != EINVAL && errno != EIO) 1020 perror_msg("PTRACE_SETOPTIONS"); 1021 } 1022 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 1023 it_worked = 1; 1024 } 1025 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 1026 kill_save_errno(pid, SIGKILL); 1027 perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1028 } 1029 } 1030 1031 if (it_worked) { 1032 syscall_trap_sig = (SIGTRAP | 0x80); 1033 ptrace_setoptions |= test_options; 1034 if (debug) 1035 fprintf(stderr, "ptrace_setoptions = %#x\n", 1036 ptrace_setoptions); 1037 return; 1038 } 1039 1040 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 1041 "giving up using this feature."); 1042} 1043 1044# ifdef USE_SEIZE 1045static void 1046test_ptrace_seize(void) 1047{ 1048 int pid; 1049 1050 pid = fork(); 1051 if (pid < 0) 1052 perror_msg_and_die("fork"); 1053 1054 if (pid == 0) { 1055 pause(); 1056 _exit(0); 1057 } 1058 1059 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 1060 * attaching tracee continues to run unless a trap condition occurs. 1061 * PTRACE_SEIZE doesn't affect signal or group stop state. 1062 */ 1063 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 1064 post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1065 } else if (debug) { 1066 fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 1067 } 1068 1069 kill(pid, SIGKILL); 1070 1071 while (1) { 1072 int status, tracee_pid; 1073 1074 errno = 0; 1075 tracee_pid = waitpid(pid, &status, 0); 1076 if (tracee_pid <= 0) { 1077 if (errno == EINTR) 1078 continue; 1079 perror_msg_and_die("%s: unexpected wait result %d", 1080 __func__, tracee_pid); 1081 } 1082 if (WIFSIGNALED(status)) { 1083 return; 1084 } 1085 error_msg_and_die("%s: unexpected wait status %x", 1086 __func__, status); 1087 } 1088} 1089# else /* !USE_SEIZE */ 1090# define test_ptrace_seize() ((void)0) 1091# endif 1092 1093#endif 1094 1095/* Noinline: don't want main to have struct utsname permanently on stack */ 1096static void __attribute__ ((noinline)) 1097get_os_release(void) 1098{ 1099 struct utsname u; 1100 if (uname(&u) < 0) 1101 perror_msg_and_die("uname"); 1102 os_release = strdup(u.release); 1103 if (!os_release) 1104 die_out_of_memory(); 1105} 1106 1107int 1108main(int argc, char *argv[]) 1109{ 1110 struct tcb *tcp; 1111 int c, pid = 0; 1112 int optF = 0; 1113 struct sigaction sa; 1114 1115 progname = argv[0] ? argv[0] : "strace"; 1116 1117 strace_tracer_pid = getpid(); 1118 1119 get_os_release(); 1120 1121 /* Allocate the initial tcbtab. */ 1122 tcbtabsize = argc; /* Surely enough for all -p args. */ 1123 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 1124 if (!tcbtab) 1125 die_out_of_memory(); 1126 tcp = calloc(tcbtabsize, sizeof(*tcp)); 1127 if (!tcp) 1128 die_out_of_memory(); 1129 for (c = 0; c < tcbtabsize; c++) 1130 tcbtab[c] = tcp++; 1131 1132 outf = stderr; 1133 set_sortby(DEFAULT_SORTBY); 1134 set_personality(DEFAULT_PERSONALITY); 1135 qualify("trace=all"); 1136 qualify("abbrev=all"); 1137 qualify("verbose=all"); 1138 qualify("signal=all"); 1139 while ((c = getopt(argc, argv, 1140 "+cCdfFhiqrtTvVxyz" 1141#ifndef USE_PROCFS 1142 "D" 1143#endif 1144 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 1145 switch (c) { 1146 case 'c': 1147 if (cflag == CFLAG_BOTH) { 1148 error_msg_and_die("-c and -C are mutually exclusive options"); 1149 } 1150 cflag = CFLAG_ONLY_STATS; 1151 break; 1152 case 'C': 1153 if (cflag == CFLAG_ONLY_STATS) { 1154 error_msg_and_die("-c and -C are mutually exclusive options"); 1155 } 1156 cflag = CFLAG_BOTH; 1157 break; 1158 case 'd': 1159 debug++; 1160 break; 1161#ifndef USE_PROCFS 1162 case 'D': 1163 daemonized_tracer = 1; 1164 break; 1165#endif 1166 case 'F': 1167 optF = 1; 1168 break; 1169 case 'f': 1170 followfork++; 1171 break; 1172 case 'h': 1173 usage(stdout, 0); 1174 break; 1175 case 'i': 1176 iflag++; 1177 break; 1178 case 'q': 1179 qflag++; 1180 break; 1181 case 'r': 1182 rflag++; 1183 tflag++; 1184 break; 1185 case 't': 1186 tflag++; 1187 break; 1188 case 'T': 1189 dtime++; 1190 break; 1191 case 'x': 1192 xflag++; 1193 break; 1194 case 'y': 1195 show_fd_path = 1; 1196 break; 1197 case 'v': 1198 qualify("abbrev=none"); 1199 break; 1200 case 'V': 1201 printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 1202 exit(0); 1203 break; 1204 case 'z': 1205 not_failing_only = 1; 1206 break; 1207 case 'a': 1208 acolumn = atoi(optarg); 1209 if (acolumn < 0) 1210 error_msg_and_die("Bad column width '%s'", optarg); 1211 break; 1212 case 'e': 1213 qualify(optarg); 1214 break; 1215 case 'o': 1216 outfname = strdup(optarg); 1217 break; 1218 case 'O': 1219 set_overhead(atoi(optarg)); 1220 break; 1221 case 'p': 1222 pid = atoi(optarg); 1223 if (pid <= 0) { 1224 error_msg("Invalid process id: '%s'", optarg); 1225 break; 1226 } 1227 if (pid == strace_tracer_pid) { 1228 error_msg("I'm sorry, I can't let you do that, Dave."); 1229 break; 1230 } 1231 tcp = alloc_tcb(pid, 0); 1232 tcp->flags |= TCB_ATTACHED; 1233 pflag_seen++; 1234 break; 1235 case 'P': 1236 tracing_paths = 1; 1237 if (pathtrace_select(optarg)) { 1238 error_msg_and_die("Failed to select path '%s'", optarg); 1239 } 1240 break; 1241 case 's': 1242 max_strlen = atoi(optarg); 1243 if (max_strlen < 0) { 1244 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1245 } 1246 break; 1247 case 'S': 1248 set_sortby(optarg); 1249 break; 1250 case 'u': 1251 username = strdup(optarg); 1252 break; 1253 case 'E': 1254 if (putenv(optarg) < 0) 1255 die_out_of_memory(); 1256 break; 1257 case 'I': 1258 opt_intr = atoi(optarg); 1259 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1260 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1261 } 1262 break; 1263 default: 1264 usage(stderr, 1); 1265 break; 1266 } 1267 } 1268 argv += optind; 1269 /* argc -= optind; - no need, argc is not used below */ 1270 1271 acolumn_spaces = malloc(acolumn + 1); 1272 if (!acolumn_spaces) 1273 die_out_of_memory(); 1274 memset(acolumn_spaces, ' ', acolumn); 1275 acolumn_spaces[acolumn] = '\0'; 1276 1277 /* Must have PROG [ARGS], or -p PID. Not both. */ 1278 if (!argv[0] == !pflag_seen) 1279 usage(stderr, 1); 1280 1281 if (pflag_seen && daemonized_tracer) { 1282 error_msg_and_die("-D and -p are mutually exclusive options"); 1283 } 1284 1285 if (!followfork) 1286 followfork = optF; 1287 1288 if (followfork > 1 && cflag) { 1289 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1290 } 1291 1292 /* See if they want to run as another user. */ 1293 if (username != NULL) { 1294 struct passwd *pent; 1295 1296 if (getuid() != 0 || geteuid() != 0) { 1297 error_msg_and_die("You must be root to use the -u option"); 1298 } 1299 pent = getpwnam(username); 1300 if (pent == NULL) { 1301 error_msg_and_die("Cannot find user '%s'", username); 1302 } 1303 run_uid = pent->pw_uid; 1304 run_gid = pent->pw_gid; 1305 } 1306 else { 1307 run_uid = getuid(); 1308 run_gid = getgid(); 1309 } 1310 1311#ifdef LINUX 1312 if (followfork) 1313 test_ptrace_setoptions_followfork(); 1314 test_ptrace_setoptions_for_all(); 1315 test_ptrace_seize(); 1316#endif 1317 1318 /* Check if they want to redirect the output. */ 1319 if (outfname) { 1320 /* See if they want to pipe the output. */ 1321 if (outfname[0] == '|' || outfname[0] == '!') { 1322 /* 1323 * We can't do the <outfname>.PID funny business 1324 * when using popen, so prohibit it. 1325 */ 1326 if (followfork > 1) 1327 error_msg_and_die("Piping the output and -ff are mutually exclusive"); 1328 outf = strace_popen(outfname + 1); 1329 } 1330 else if (followfork <= 1) 1331 outf = strace_fopen(outfname); 1332 } 1333 1334 if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1335 char *buf = malloc(BUFSIZ); 1336 if (!buf) 1337 die_out_of_memory(); 1338 setvbuf(outf, buf, _IOLBF, BUFSIZ); 1339 } 1340 if (outfname && argv[0]) { 1341 if (!opt_intr) 1342 opt_intr = INTR_NEVER; 1343 qflag = 1; 1344 } 1345 if (!opt_intr) 1346 opt_intr = INTR_WHILE_WAIT; 1347 1348 /* argv[0] -pPID -oFILE Default interactive setting 1349 * yes 0 0 INTR_WHILE_WAIT 1350 * no 1 0 INTR_WHILE_WAIT 1351 * yes 0 1 INTR_NEVER 1352 * no 1 1 INTR_WHILE_WAIT 1353 */ 1354 1355 /* STARTUP_CHILD must be called before the signal handlers get 1356 installed below as they are inherited into the spawned process. 1357 Also we do not need to be protected by them as during interruption 1358 in the STARTUP_CHILD mode we kill the spawned process anyway. */ 1359 if (argv[0]) 1360 startup_child(argv); 1361 1362 sigemptyset(&empty_set); 1363 sigemptyset(&blocked_set); 1364 sa.sa_handler = SIG_IGN; 1365 sigemptyset(&sa.sa_mask); 1366 sa.sa_flags = 0; 1367 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1368 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1369 if (opt_intr != INTR_ANYWHERE) { 1370 if (opt_intr == INTR_BLOCK_TSTP_TOO) 1371 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1372 /* 1373 * In interactive mode (if no -o OUTFILE, or -p PID is used), 1374 * fatal signals are blocked while syscall stop is processed, 1375 * and acted on in between, when waiting for new syscall stops. 1376 * In non-interactive mode, signals are ignored. 1377 */ 1378 if (opt_intr == INTR_WHILE_WAIT) { 1379 sigaddset(&blocked_set, SIGHUP); 1380 sigaddset(&blocked_set, SIGINT); 1381 sigaddset(&blocked_set, SIGQUIT); 1382 sigaddset(&blocked_set, SIGPIPE); 1383 sigaddset(&blocked_set, SIGTERM); 1384 sa.sa_handler = interrupt; 1385#ifdef SUNOS4 1386 /* POSIX signals on sunos4.1 are a little broken. */ 1387 sa.sa_flags = SA_INTERRUPT; 1388#endif 1389 } 1390 /* SIG_IGN, or set handler for these */ 1391 sigaction(SIGHUP, &sa, NULL); 1392 sigaction(SIGINT, &sa, NULL); 1393 sigaction(SIGQUIT, &sa, NULL); 1394 sigaction(SIGPIPE, &sa, NULL); 1395 sigaction(SIGTERM, &sa, NULL); 1396 } 1397#ifdef USE_PROCFS 1398 sa.sa_handler = reaper; 1399 sigaction(SIGCHLD, &sa, NULL); 1400#else 1401 /* Make sure SIGCHLD has the default action so that waitpid 1402 definitely works without losing track of children. The user 1403 should not have given us a bogus state to inherit, but he might 1404 have. Arguably we should detect SIG_IGN here and pass it on 1405 to children, but probably noone really needs that. */ 1406 sa.sa_handler = SIG_DFL; 1407 sigaction(SIGCHLD, &sa, NULL); 1408#endif /* USE_PROCFS */ 1409 1410 if (pflag_seen || daemonized_tracer) 1411 startup_attach(); 1412 1413 if (trace() < 0) 1414 exit(1); 1415 1416 cleanup(); 1417 fflush(NULL); 1418 if (exit_code > 0xff) { 1419 /* Child was killed by a signal, mimic that. */ 1420 exit_code &= 0xff; 1421 signal(exit_code, SIG_DFL); 1422 raise(exit_code); 1423 /* Paranoia - what if this signal is not fatal? 1424 Exit with 128 + signo then. */ 1425 exit_code += 128; 1426 } 1427 exit(exit_code); 1428} 1429 1430static void 1431expand_tcbtab(void) 1432{ 1433 /* Allocate some more TCBs and expand the table. 1434 We don't want to relocate the TCBs because our 1435 callers have pointers and it would be a pain. 1436 So tcbtab is a table of pointers. Since we never 1437 free the TCBs, we allocate a single chunk of many. */ 1438 int i = tcbtabsize; 1439 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 1440 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 1441 if (!newtab || !newtcbs) 1442 die_out_of_memory(); 1443 tcbtabsize *= 2; 1444 tcbtab = newtab; 1445 while (i < tcbtabsize) 1446 tcbtab[i++] = newtcbs++; 1447} 1448 1449struct tcb * 1450alloc_tcb(int pid, int command_options_parsed) 1451{ 1452 int i; 1453 struct tcb *tcp; 1454 1455 if (nprocs == tcbtabsize) 1456 expand_tcbtab(); 1457 1458 for (i = 0; i < tcbtabsize; i++) { 1459 tcp = tcbtab[i]; 1460 if ((tcp->flags & TCB_INUSE) == 0) { 1461 memset(tcp, 0, sizeof(*tcp)); 1462 tcp->pid = pid; 1463 tcp->flags = TCB_INUSE; 1464 tcp->outf = outf; /* Initialise to current out file */ 1465#if SUPPORTED_PERSONALITIES > 1 1466 tcp->currpers = current_personality; 1467#endif 1468#ifdef USE_PROCFS 1469 tcp->pfd = -1; 1470#endif 1471 nprocs++; 1472 if (debug) 1473 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 1474 if (command_options_parsed) 1475 newoutf(tcp); 1476 return tcp; 1477 } 1478 } 1479 error_msg_and_die("bug in alloc_tcb"); 1480} 1481 1482#ifdef USE_PROCFS 1483int 1484proc_open(struct tcb *tcp, int attaching) 1485{ 1486 char proc[32]; 1487 long arg; 1488#ifdef SVR4 1489 int i; 1490 sysset_t syscalls; 1491 sigset_t signals; 1492 fltset_t faults; 1493#endif 1494#ifndef HAVE_POLLABLE_PROCFS 1495 static int last_pfd; 1496#endif 1497 1498#ifdef HAVE_MP_PROCFS 1499 /* Open the process pseudo-files in /proc. */ 1500 sprintf(proc, "/proc/%d/ctl", tcp->pid); 1501 tcp->pfd = open(proc, O_WRONLY|O_EXCL); 1502 if (tcp->pfd < 0) { 1503 perror("strace: open(\"/proc/...\", ...)"); 1504 return -1; 1505 } 1506 set_cloexec_flag(tcp->pfd); 1507 sprintf(proc, "/proc/%d/status", tcp->pid); 1508 tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL); 1509 if (tcp->pfd_stat < 0) { 1510 perror("strace: open(\"/proc/...\", ...)"); 1511 return -1; 1512 } 1513 set_cloexec_flag(tcp->pfd_stat); 1514 sprintf(proc, "/proc/%d/as", tcp->pid); 1515 tcp->pfd_as = open(proc, O_RDONLY|O_EXCL); 1516 if (tcp->pfd_as < 0) { 1517 perror("strace: open(\"/proc/...\", ...)"); 1518 return -1; 1519 } 1520 set_cloexec_flag(tcp->pfd_as); 1521#else 1522 /* Open the process pseudo-file in /proc. */ 1523# ifndef FREEBSD 1524 sprintf(proc, "/proc/%d", tcp->pid); 1525 tcp->pfd = open(proc, O_RDWR|O_EXCL); 1526# else 1527 sprintf(proc, "/proc/%d/mem", tcp->pid); 1528 tcp->pfd = open(proc, O_RDWR); 1529# endif 1530 if (tcp->pfd < 0) { 1531 perror("strace: open(\"/proc/...\", ...)"); 1532 return -1; 1533 } 1534 set_cloexec_flag(tcp->pfd); 1535#endif 1536#ifdef FREEBSD 1537 sprintf(proc, "/proc/%d/regs", tcp->pid); 1538 tcp->pfd_reg = open(proc, O_RDONLY); 1539 if (tcp->pfd_reg < 0) { 1540 perror("strace: open(\"/proc/.../regs\", ...)"); 1541 return -1; 1542 } 1543 if (cflag) { 1544 sprintf(proc, "/proc/%d/status", tcp->pid); 1545 tcp->pfd_status = open(proc, O_RDONLY); 1546 if (tcp->pfd_status < 0) { 1547 perror("strace: open(\"/proc/.../status\", ...)"); 1548 return -1; 1549 } 1550 } else 1551 tcp->pfd_status = -1; 1552#endif /* FREEBSD */ 1553 rebuild_pollv(); 1554 if (!attaching) { 1555 /* 1556 * Wait for the child to pause. Because of a race 1557 * condition we have to poll for the event. 1558 */ 1559 for (;;) { 1560 if (IOCTL_STATUS(tcp) < 0) { 1561 perror("strace: PIOCSTATUS"); 1562 return -1; 1563 } 1564 if (tcp->status.PR_FLAGS & PR_ASLEEP) 1565 break; 1566 } 1567 } 1568#ifndef FREEBSD 1569 /* Stop the process so that we own the stop. */ 1570 if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 1571 perror("strace: PIOCSTOP"); 1572 return -1; 1573 } 1574#endif 1575#ifdef PIOCSET 1576 /* Set Run-on-Last-Close. */ 1577 arg = PR_RLC; 1578 if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 1579 perror("PIOCSET PR_RLC"); 1580 return -1; 1581 } 1582 /* Set or Reset Inherit-on-Fork. */ 1583 arg = PR_FORK; 1584 if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 1585 perror("PIOC{SET,RESET} PR_FORK"); 1586 return -1; 1587 } 1588#else /* !PIOCSET */ 1589#ifndef FREEBSD 1590 if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 1591 perror("PIOCSRLC"); 1592 return -1; 1593 } 1594 if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 1595 perror("PIOC{S,R}FORK"); 1596 return -1; 1597 } 1598#else /* FREEBSD */ 1599 /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 1600 if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 1601 perror("PIOCGFL"); 1602 return -1; 1603 } 1604 arg &= ~PF_LINGER; 1605 if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 1606 perror("PIOCSFL"); 1607 return -1; 1608 } 1609#endif /* FREEBSD */ 1610#endif /* !PIOCSET */ 1611#ifndef FREEBSD 1612 /* Enable all syscall entries we care about. */ 1613 premptyset(&syscalls); 1614 for (i = 1; i < MAX_QUALS; ++i) { 1615 if (i > (sizeof syscalls) * CHAR_BIT) break; 1616 if (qual_flags[i] & QUAL_TRACE) praddset(&syscalls, i); 1617 } 1618 praddset(&syscalls, SYS_execve); 1619 if (followfork) { 1620 praddset(&syscalls, SYS_fork); 1621#ifdef SYS_forkall 1622 praddset(&syscalls, SYS_forkall); 1623#endif 1624#ifdef SYS_fork1 1625 praddset(&syscalls, SYS_fork1); 1626#endif 1627#ifdef SYS_rfork1 1628 praddset(&syscalls, SYS_rfork1); 1629#endif 1630#ifdef SYS_rforkall 1631 praddset(&syscalls, SYS_rforkall); 1632#endif 1633 } 1634 if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 1635 perror("PIOCSENTRY"); 1636 return -1; 1637 } 1638 /* Enable the syscall exits. */ 1639 if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 1640 perror("PIOSEXIT"); 1641 return -1; 1642 } 1643 /* Enable signals we care about. */ 1644 premptyset(&signals); 1645 for (i = 1; i < MAX_QUALS; ++i) { 1646 if (i > (sizeof signals) * CHAR_BIT) break; 1647 if (qual_flags[i] & QUAL_SIGNAL) praddset(&signals, i); 1648 } 1649 if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 1650 perror("PIOCSTRACE"); 1651 return -1; 1652 } 1653 /* Enable faults we care about */ 1654 premptyset(&faults); 1655 for (i = 1; i < MAX_QUALS; ++i) { 1656 if (i > (sizeof faults) * CHAR_BIT) break; 1657 if (qual_flags[i] & QUAL_FAULT) praddset(&faults, i); 1658 } 1659 if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 1660 perror("PIOCSFAULT"); 1661 return -1; 1662 } 1663#else /* FREEBSD */ 1664 /* set events flags. */ 1665 arg = S_SIG | S_SCE | S_SCX; 1666 if (ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 1667 perror("PIOCBIS"); 1668 return -1; 1669 } 1670#endif /* FREEBSD */ 1671 if (!attaching) { 1672#ifdef MIPS 1673 /* 1674 * The SGI PRSABORT doesn't work for pause() so 1675 * we send it a caught signal to wake it up. 1676 */ 1677 kill(tcp->pid, SIGINT); 1678#else /* !MIPS */ 1679#ifdef PRSABORT 1680 /* The child is in a pause(), abort it. */ 1681 arg = PRSABORT; 1682 if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 1683 perror("PIOCRUN"); 1684 return -1; 1685 } 1686#endif 1687#endif /* !MIPS*/ 1688#ifdef FREEBSD 1689 /* wake up the child if it received the SIGSTOP */ 1690 kill(tcp->pid, SIGCONT); 1691#endif 1692 for (;;) { 1693 /* Wait for the child to do something. */ 1694 if (IOCTL_WSTOP(tcp) < 0) { 1695 perror("PIOCWSTOP"); 1696 return -1; 1697 } 1698 if (tcp->status.PR_WHY == PR_SYSENTRY) { 1699 tcp->flags &= ~TCB_INSYSCALL; 1700 get_scno(tcp); 1701 if (known_scno(tcp) == SYS_execve) 1702 break; 1703 } 1704 /* Set it running: maybe execve will be next. */ 1705#ifndef FREEBSD 1706 arg = 0; 1707 if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 1708#else 1709 if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 1710#endif 1711 { 1712 perror("PIOCRUN"); 1713 return -1; 1714 } 1715#ifdef FREEBSD 1716 /* handle the case where we "opened" the child before 1717 it did the kill -STOP */ 1718 if (tcp->status.PR_WHY == PR_SIGNALLED && 1719 tcp->status.PR_WHAT == SIGSTOP) 1720 kill(tcp->pid, SIGCONT); 1721#endif 1722 } 1723 } 1724#ifdef FREEBSD 1725 else { 1726 if (attaching < 2) { 1727 /* We are attaching to an already running process. 1728 * Try to figure out the state of the process in syscalls, 1729 * to handle the first event well. 1730 * This is done by having a look at the "wchan" property of the 1731 * process, which tells where it is stopped (if it is). */ 1732 FILE * status; 1733 char wchan[20]; /* should be enough */ 1734 1735 sprintf(proc, "/proc/%d/status", tcp->pid); 1736 status = fopen(proc, "r"); 1737 if (status && 1738 (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 1739 "%*d,%*d %*d,%*d %19s", wchan) == 1) && 1740 strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 1741 strcmp(wchan, "stopevent")) { 1742 /* The process is asleep in the middle of a syscall. 1743 Fake the syscall entry event */ 1744 tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 1745 tcp->status.PR_WHY = PR_SYSENTRY; 1746 trace_syscall(tcp); 1747 } 1748 if (status) 1749 fclose(status); 1750 } /* otherwise it's a fork being followed */ 1751 } 1752#endif /* FREEBSD */ 1753#ifndef HAVE_POLLABLE_PROCFS 1754 if (proc_poll_pipe[0] != -1) 1755 proc_poller(tcp->pfd); 1756 else if (nprocs > 1) { 1757 proc_poll_open(); 1758 proc_poller(last_pfd); 1759 proc_poller(tcp->pfd); 1760 } 1761 last_pfd = tcp->pfd; 1762#endif /* !HAVE_POLLABLE_PROCFS */ 1763 return 0; 1764} 1765 1766#endif /* USE_PROCFS */ 1767 1768static struct tcb * 1769pid2tcb(int pid) 1770{ 1771 int i; 1772 1773 if (pid <= 0) 1774 return NULL; 1775 1776 for (i = 0; i < tcbtabsize; i++) { 1777 struct tcb *tcp = tcbtab[i]; 1778 if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 1779 return tcp; 1780 } 1781 1782 return NULL; 1783} 1784 1785#ifdef USE_PROCFS 1786 1787static struct tcb * 1788first_used_tcb(void) 1789{ 1790 int i; 1791 struct tcb *tcp; 1792 for (i = 0; i < tcbtabsize; i++) { 1793 tcp = tcbtab[i]; 1794 if (tcp->flags & TCB_INUSE) 1795 return tcp; 1796 } 1797 return NULL; 1798} 1799 1800static struct tcb * 1801pfd2tcb(int pfd) 1802{ 1803 int i; 1804 1805 for (i = 0; i < tcbtabsize; i++) { 1806 struct tcb *tcp = tcbtab[i]; 1807 if (tcp->pfd != pfd) 1808 continue; 1809 if (tcp->flags & TCB_INUSE) 1810 return tcp; 1811 } 1812 return NULL; 1813} 1814 1815#endif /* USE_PROCFS */ 1816 1817void 1818droptcb(struct tcb *tcp) 1819{ 1820 if (tcp->pid == 0) 1821 return; 1822 1823 nprocs--; 1824 if (debug) 1825 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1826 1827#ifdef USE_PROCFS 1828 if (tcp->pfd != -1) { 1829 close(tcp->pfd); 1830 tcp->pfd = -1; 1831# ifdef FREEBSD 1832 if (tcp->pfd_reg != -1) { 1833 close(tcp->pfd_reg); 1834 tcp->pfd_reg = -1; 1835 } 1836 if (tcp->pfd_status != -1) { 1837 close(tcp->pfd_status); 1838 tcp->pfd_status = -1; 1839 } 1840# endif 1841 tcp->flags = 0; /* rebuild_pollv needs it */ 1842 rebuild_pollv(); 1843 } 1844#endif 1845 1846 if (outfname && followfork > 1 && tcp->outf) 1847 fclose(tcp->outf); 1848 1849 memset(tcp, 0, sizeof(*tcp)); 1850} 1851 1852/* detach traced process; continue with sig 1853 Never call DETACH twice on the same process as both unattached and 1854 attached-unstopped processes give the same ESRCH. For unattached process we 1855 would SIGSTOP it and wait for its SIGSTOP notification forever. */ 1856 1857static int 1858detach(struct tcb *tcp) 1859{ 1860 int error = 0; 1861#ifdef LINUX 1862 int status, catch_sigstop; 1863#endif 1864 1865 if (tcp->flags & TCB_BPTSET) 1866 clearbpt(tcp); 1867 1868#ifdef LINUX 1869 /* 1870 * Linux wrongly insists the child be stopped 1871 * before detaching. Arghh. We go through hoops 1872 * to make a clean break of things. 1873 */ 1874#if defined(SPARC) 1875#undef PTRACE_DETACH 1876#define PTRACE_DETACH PTRACE_SUNDETACH 1877#endif 1878 /* 1879 * We attached but possibly didn't see the expected SIGSTOP. 1880 * We must catch exactly one as otherwise the detached process 1881 * would be left stopped (process state T). 1882 */ 1883 catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 1884 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 1885 if (error == 0) { 1886 /* On a clear day, you can see forever. */ 1887 } 1888 else if (errno != ESRCH) { 1889 /* Shouldn't happen. */ 1890 perror("detach: ptrace(PTRACE_DETACH, ...)"); 1891 } 1892 else if (my_tkill(tcp->pid, 0) < 0) { 1893 if (errno != ESRCH) 1894 perror("detach: checking sanity"); 1895 } 1896 else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) { 1897 if (errno != ESRCH) 1898 perror("detach: stopping child"); 1899 } 1900 else 1901 catch_sigstop = 1; 1902 if (catch_sigstop) { 1903 for (;;) { 1904#ifdef __WALL 1905 if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 1906 if (errno == ECHILD) /* Already gone. */ 1907 break; 1908 if (errno != EINVAL) { 1909 perror("detach: waiting"); 1910 break; 1911 } 1912#endif /* __WALL */ 1913 /* No __WALL here. */ 1914 if (waitpid(tcp->pid, &status, 0) < 0) { 1915 if (errno != ECHILD) { 1916 perror("detach: waiting"); 1917 break; 1918 } 1919#ifdef __WCLONE 1920 /* If no processes, try clones. */ 1921 if (wait4(tcp->pid, &status, __WCLONE, 1922 NULL) < 0) { 1923 if (errno != ECHILD) 1924 perror("detach: waiting"); 1925 break; 1926 } 1927#endif /* __WCLONE */ 1928 } 1929#ifdef __WALL 1930 } 1931#endif 1932 if (!WIFSTOPPED(status)) { 1933 /* Au revoir, mon ami. */ 1934 break; 1935 } 1936 if (WSTOPSIG(status) == SIGSTOP) { 1937 ptrace_restart(PTRACE_DETACH, tcp, 0); 1938 break; 1939 } 1940 error = ptrace_restart(PTRACE_CONT, tcp, 1941 WSTOPSIG(status) == syscall_trap_sig ? 0 1942 : WSTOPSIG(status)); 1943 if (error < 0) 1944 break; 1945 } 1946 } 1947#endif /* LINUX */ 1948 1949#if defined(SUNOS4) 1950 /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 1951 error = ptrace_restart(PTRACE_DETACH, tcp, 0); 1952#endif /* SUNOS4 */ 1953 1954 if (!qflag) 1955 fprintf(stderr, "Process %u detached\n", tcp->pid); 1956 1957 droptcb(tcp); 1958 1959 return error; 1960} 1961 1962#ifdef USE_PROCFS 1963 1964static void reaper(int sig) 1965{ 1966 int pid; 1967 int status; 1968 1969 while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 1970 } 1971} 1972 1973#endif /* USE_PROCFS */ 1974 1975static void 1976cleanup(void) 1977{ 1978 int i; 1979 struct tcb *tcp; 1980 int fatal_sig; 1981 1982 /* 'interrupted' is a volatile object, fetch it only once */ 1983 fatal_sig = interrupted; 1984 if (!fatal_sig) 1985 fatal_sig = SIGTERM; 1986 1987 for (i = 0; i < tcbtabsize; i++) { 1988 tcp = tcbtab[i]; 1989 if (!(tcp->flags & TCB_INUSE)) 1990 continue; 1991 if (debug) 1992 fprintf(stderr, 1993 "cleanup: looking at pid %u\n", tcp->pid); 1994 if (printing_tcp && 1995 (!outfname || followfork < 2 || printing_tcp == tcp)) { 1996 tprints(" <unfinished ...>\n"); 1997 printing_tcp = NULL; 1998 } 1999 if (tcp->flags & TCB_ATTACHED) 2000 detach(tcp); 2001 else { 2002 kill(tcp->pid, SIGCONT); 2003 kill(tcp->pid, fatal_sig); 2004 } 2005 } 2006 if (cflag) 2007 call_summary(outf); 2008} 2009 2010static void 2011interrupt(int sig) 2012{ 2013 interrupted = sig; 2014} 2015 2016#ifndef HAVE_STRERROR 2017 2018#if !HAVE_DECL_SYS_ERRLIST 2019extern int sys_nerr; 2020extern char *sys_errlist[]; 2021#endif /* HAVE_DECL_SYS_ERRLIST */ 2022 2023const char * 2024strerror(int err_no) 2025{ 2026 static char buf[64]; 2027 2028 if (err_no < 1 || err_no >= sys_nerr) { 2029 sprintf(buf, "Unknown error %d", err_no); 2030 return buf; 2031 } 2032 return sys_errlist[err_no]; 2033} 2034 2035#endif /* HAVE_STERRROR */ 2036 2037#ifndef HAVE_STRSIGNAL 2038 2039#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 2040extern char *sys_siglist[]; 2041#endif 2042#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 2043extern char *_sys_siglist[]; 2044#endif 2045 2046const char * 2047strsignal(int sig) 2048{ 2049 static char buf[64]; 2050 2051 if (sig < 1 || sig >= NSIG) { 2052 sprintf(buf, "Unknown signal %d", sig); 2053 return buf; 2054 } 2055#ifdef HAVE__SYS_SIGLIST 2056 return _sys_siglist[sig]; 2057#else 2058 return sys_siglist[sig]; 2059#endif 2060} 2061 2062#endif /* HAVE_STRSIGNAL */ 2063 2064#ifdef USE_PROCFS 2065 2066static void 2067rebuild_pollv(void) 2068{ 2069 int i, j; 2070 2071 free(pollv); 2072 pollv = malloc(nprocs * sizeof(pollv[0])); 2073 if (!pollv) 2074 die_out_of_memory(); 2075 2076 for (i = j = 0; i < tcbtabsize; i++) { 2077 struct tcb *tcp = tcbtab[i]; 2078 if (!(tcp->flags & TCB_INUSE)) 2079 continue; 2080 pollv[j].fd = tcp->pfd; 2081 pollv[j].events = POLLWANT; 2082 j++; 2083 } 2084 if (j != nprocs) { 2085 error_msg_and_die("proc miscount"); 2086 } 2087} 2088 2089#ifndef HAVE_POLLABLE_PROCFS 2090 2091static void 2092proc_poll_open(void) 2093{ 2094 int i; 2095 2096 if (pipe(proc_poll_pipe) < 0) { 2097 perror_msg_and_die("pipe"); 2098 } 2099 for (i = 0; i < 2; i++) { 2100 set_cloexec_flag(proc_poll_pipe[i]); 2101 } 2102} 2103 2104static int 2105proc_poll(struct pollfd *pollv, int nfds, int timeout) 2106{ 2107 int i; 2108 int n; 2109 struct proc_pollfd pollinfo; 2110 2111 n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo)); 2112 if (n < 0) 2113 return n; 2114 if (n != sizeof(struct proc_pollfd)) { 2115 error_msg_and_die("panic: short read: %d", n); 2116 } 2117 for (i = 0; i < nprocs; i++) { 2118 if (pollv[i].fd == pollinfo.fd) 2119 pollv[i].revents = pollinfo.revents; 2120 else 2121 pollv[i].revents = 0; 2122 } 2123 poller_pid = pollinfo.pid; 2124 return 1; 2125} 2126 2127static void 2128wakeup_handler(int sig) 2129{ 2130} 2131 2132static void 2133proc_poller(int pfd) 2134{ 2135 struct proc_pollfd pollinfo; 2136 struct sigaction sa; 2137 sigset_t blocked_set, empty_set; 2138 int i; 2139 int n; 2140 struct rlimit rl; 2141#ifdef FREEBSD 2142 struct procfs_status pfs; 2143#endif /* FREEBSD */ 2144 2145 switch (fork()) { 2146 case -1: 2147 perror_msg_and_die("fork"); 2148 case 0: 2149 break; 2150 default: 2151 return; 2152 } 2153 2154 sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 2155 sa.sa_flags = 0; 2156 sigemptyset(&sa.sa_mask); 2157 sigaction(SIGHUP, &sa, NULL); 2158 sigaction(SIGINT, &sa, NULL); 2159 sigaction(SIGQUIT, &sa, NULL); 2160 sigaction(SIGPIPE, &sa, NULL); 2161 sigaction(SIGTERM, &sa, NULL); 2162 sa.sa_handler = wakeup_handler; 2163 sigaction(SIGUSR1, &sa, NULL); 2164 sigemptyset(&blocked_set); 2165 sigaddset(&blocked_set, SIGUSR1); 2166 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 2167 sigemptyset(&empty_set); 2168 2169 if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 2170 perror_msg_and_die("getrlimit(RLIMIT_NOFILE, ...)"); 2171 } 2172 n = rl.rlim_cur; 2173 for (i = 0; i < n; i++) { 2174 if (i != pfd && i != proc_poll_pipe[1]) 2175 close(i); 2176 } 2177 2178 pollinfo.fd = pfd; 2179 pollinfo.pid = getpid(); 2180 for (;;) { 2181#ifndef FREEBSD 2182 if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 2183#else 2184 if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 2185#endif 2186 { 2187 switch (errno) { 2188 case EINTR: 2189 continue; 2190 case EBADF: 2191 pollinfo.revents = POLLERR; 2192 break; 2193 case ENOENT: 2194 pollinfo.revents = POLLHUP; 2195 break; 2196 default: 2197 perror("proc_poller: PIOCWSTOP"); 2198 } 2199 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 2200 _exit(0); 2201 } 2202 pollinfo.revents = POLLWANT; 2203 write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 2204 sigsuspend(&empty_set); 2205 } 2206} 2207 2208#endif /* !HAVE_POLLABLE_PROCFS */ 2209 2210static int 2211choose_pfd() 2212{ 2213 int i, j; 2214 struct tcb *tcp; 2215 2216 static int last; 2217 2218 if (followfork < 2 && 2219 last < nprocs && (pollv[last].revents & POLLWANT)) { 2220 /* 2221 * The previous process is ready to run again. We'll 2222 * let it do so if it is currently in a syscall. This 2223 * heuristic improves the readability of the trace. 2224 */ 2225 tcp = pfd2tcb(pollv[last].fd); 2226 if (tcp && exiting(tcp)) 2227 return pollv[last].fd; 2228 } 2229 2230 for (i = 0; i < nprocs; i++) { 2231 /* Let competing children run round robin. */ 2232 j = (i + last + 1) % nprocs; 2233 if (pollv[j].revents & (POLLHUP | POLLERR)) { 2234 tcp = pfd2tcb(pollv[j].fd); 2235 if (!tcp) { 2236 error_msg_and_die("lost proc"); 2237 } 2238 droptcb(tcp); 2239 return -1; 2240 } 2241 if (pollv[j].revents & POLLWANT) { 2242 last = j; 2243 return pollv[j].fd; 2244 } 2245 } 2246 error_msg_and_die("nothing ready"); 2247} 2248 2249static int 2250trace(void) 2251{ 2252#ifdef POLL_HACK 2253 struct tcb *in_syscall = NULL; 2254#endif 2255 struct tcb *tcp; 2256 int pfd; 2257 int what; 2258 int ioctl_result = 0, ioctl_errno = 0; 2259 long arg; 2260 2261 for (;;) { 2262 if (interactive) 2263 sigprocmask(SIG_SETMASK, &empty_set, NULL); 2264 2265 if (nprocs == 0) 2266 break; 2267 2268 switch (nprocs) { 2269 case 1: 2270#ifndef HAVE_POLLABLE_PROCFS 2271 if (proc_poll_pipe[0] == -1) { 2272#endif 2273 tcp = first_used_tcb(); 2274 if (!tcp) 2275 continue; 2276 pfd = tcp->pfd; 2277 if (pfd == -1) 2278 continue; 2279 break; 2280#ifndef HAVE_POLLABLE_PROCFS 2281 } 2282 /* fall through ... */ 2283#endif /* !HAVE_POLLABLE_PROCFS */ 2284 default: 2285#ifdef HAVE_POLLABLE_PROCFS 2286#ifdef POLL_HACK 2287 /* On some systems (e.g. UnixWare) we get too much ugly 2288 "unfinished..." stuff when multiple proceses are in 2289 syscalls. Here's a nasty hack */ 2290 2291 if (in_syscall) { 2292 struct pollfd pv; 2293 tcp = in_syscall; 2294 in_syscall = NULL; 2295 pv.fd = tcp->pfd; 2296 pv.events = POLLWANT; 2297 what = poll(&pv, 1, 1); 2298 if (what < 0) { 2299 if (interrupted) 2300 return 0; 2301 continue; 2302 } 2303 else if (what == 1 && pv.revents & POLLWANT) { 2304 goto FOUND; 2305 } 2306 } 2307#endif 2308 2309 if (poll(pollv, nprocs, INFTIM) < 0) { 2310 if (interrupted) 2311 return 0; 2312 continue; 2313 } 2314#else /* !HAVE_POLLABLE_PROCFS */ 2315 if (proc_poll(pollv, nprocs, INFTIM) < 0) { 2316 if (interrupted) 2317 return 0; 2318 continue; 2319 } 2320#endif /* !HAVE_POLLABLE_PROCFS */ 2321 pfd = choose_pfd(); 2322 if (pfd == -1) 2323 continue; 2324 break; 2325 } 2326 2327 /* Look up `pfd' in our table. */ 2328 tcp = pfd2tcb(pfd); 2329 if (tcp == NULL) { 2330 error_msg_and_die("unknown pfd: %u", pfd); 2331 } 2332#ifdef POLL_HACK 2333 FOUND: 2334#endif 2335 /* Get the status of the process. */ 2336 if (!interrupted) { 2337#ifndef FREEBSD 2338 ioctl_result = IOCTL_WSTOP(tcp); 2339#else /* FREEBSD */ 2340 /* Thanks to some scheduling mystery, the first poller 2341 sometimes waits for the already processed end of fork 2342 event. Doing a non blocking poll here solves the problem. */ 2343 if (proc_poll_pipe[0] != -1) 2344 ioctl_result = IOCTL_STATUS(tcp); 2345 else 2346 ioctl_result = IOCTL_WSTOP(tcp); 2347#endif /* FREEBSD */ 2348 ioctl_errno = errno; 2349#ifndef HAVE_POLLABLE_PROCFS 2350 if (proc_poll_pipe[0] != -1) { 2351 if (ioctl_result < 0) 2352 kill(poller_pid, SIGKILL); 2353 else 2354 kill(poller_pid, SIGUSR1); 2355 } 2356#endif /* !HAVE_POLLABLE_PROCFS */ 2357 } 2358 if (interrupted) 2359 return 0; 2360 2361 if (interactive) 2362 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 2363 2364 if (ioctl_result < 0) { 2365 /* Find out what happened if it failed. */ 2366 switch (ioctl_errno) { 2367 case EINTR: 2368 case EBADF: 2369 continue; 2370#ifdef FREEBSD 2371 case ENOTTY: 2372#endif 2373 case ENOENT: 2374 droptcb(tcp); 2375 continue; 2376 default: 2377 perror_msg_and_die("PIOCWSTOP"); 2378 } 2379 } 2380 2381#ifdef FREEBSD 2382 if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 2383 /* discard first event for a syscall we never entered */ 2384 IOCTL(tcp->pfd, PIOCRUN, 0); 2385 continue; 2386 } 2387#endif 2388 2389 /* clear the just started flag */ 2390 tcp->flags &= ~TCB_STARTUP; 2391 2392 /* set current output file */ 2393 outf = tcp->outf; 2394 curcol = tcp->curcol; 2395 2396 if (cflag) { 2397 struct timeval stime; 2398#ifdef FREEBSD 2399 char buf[1024]; 2400 int len; 2401 2402 len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0); 2403 if (len > 0) { 2404 buf[len] = '\0'; 2405 sscanf(buf, 2406 "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 2407 &stime.tv_sec, &stime.tv_usec); 2408 } else 2409 stime.tv_sec = stime.tv_usec = 0; 2410#else /* !FREEBSD */ 2411 stime.tv_sec = tcp->status.pr_stime.tv_sec; 2412 stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 2413#endif /* !FREEBSD */ 2414 tv_sub(&tcp->dtime, &stime, &tcp->stime); 2415 tcp->stime = stime; 2416 } 2417 what = tcp->status.PR_WHAT; 2418 switch (tcp->status.PR_WHY) { 2419#ifndef FREEBSD 2420 case PR_REQUESTED: 2421 if (tcp->status.PR_FLAGS & PR_ASLEEP) { 2422 tcp->status.PR_WHY = PR_SYSENTRY; 2423 if (trace_syscall(tcp) < 0) { 2424 error_msg_and_die("syscall trouble"); 2425 } 2426 } 2427 break; 2428#endif /* !FREEBSD */ 2429 case PR_SYSENTRY: 2430#ifdef POLL_HACK 2431 in_syscall = tcp; 2432#endif 2433 case PR_SYSEXIT: 2434 if (trace_syscall(tcp) < 0) { 2435 error_msg_and_die("syscall trouble"); 2436 } 2437 break; 2438 case PR_SIGNALLED: 2439 if (cflag != CFLAG_ONLY_STATS 2440 && (qual_flags[what] & QUAL_SIGNAL)) { 2441 printleader(tcp); 2442 tprintf("--- %s (%s) ---\n", 2443 signame(what), strsignal(what)); 2444 printing_tcp = NULL; 2445#ifdef PR_INFO 2446 if (tcp->status.PR_INFO.si_signo == what) { 2447 printleader(tcp); 2448 tprints(" siginfo="); 2449 printsiginfo(&tcp->status.PR_INFO, 1); 2450 tprints("\n"); 2451 printing_tcp = NULL; 2452 } 2453#endif 2454 } 2455 break; 2456 case PR_FAULTED: 2457 if (cflag != CFLAGS_ONLY_STATS 2458 && (qual_flags[what] & QUAL_FAULT)) { 2459 printleader(tcp); 2460 tprintf("=== FAULT %d ===\n", what); 2461 printing_tcp = NULL; 2462 } 2463 break; 2464#ifdef FREEBSD 2465 case 0: /* handle case we polled for nothing */ 2466 continue; 2467#endif 2468 default: 2469 error_msg_and_die("odd stop %d", tcp->status.PR_WHY); 2470 break; 2471 } 2472 /* Remember current print column before continuing. */ 2473 tcp->curcol = curcol; 2474 arg = 0; 2475#ifndef FREEBSD 2476 if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 2477#else 2478 if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 2479#endif 2480 { 2481 perror_msg_and_die("PIOCRUN"); 2482 } 2483 } 2484 return 0; 2485} 2486 2487#else /* !USE_PROCFS */ 2488 2489static int 2490trace(void) 2491{ 2492#ifdef LINUX 2493 struct rusage ru; 2494 struct rusage *rup = cflag ? &ru : NULL; 2495# ifdef __WALL 2496 static int wait4_options = __WALL; 2497# endif 2498#endif /* LINUX */ 2499 2500 while (nprocs != 0) { 2501 int pid; 2502 int wait_errno; 2503 int status, sig; 2504 int stopped; 2505 struct tcb *tcp; 2506 unsigned event; 2507 2508 if (interrupted) 2509 return 0; 2510 if (interactive) 2511 sigprocmask(SIG_SETMASK, &empty_set, NULL); 2512#ifdef LINUX 2513# ifdef __WALL 2514 pid = wait4(-1, &status, wait4_options, rup); 2515 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 2516 /* this kernel does not support __WALL */ 2517 wait4_options &= ~__WALL; 2518 pid = wait4(-1, &status, wait4_options, rup); 2519 } 2520 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 2521 /* most likely a "cloned" process */ 2522 pid = wait4(-1, &status, __WCLONE, rup); 2523 if (pid < 0) { 2524 perror_msg("wait4(__WCLONE) failed"); 2525 } 2526 } 2527# else 2528 pid = wait4(-1, &status, 0, rup); 2529# endif /* __WALL */ 2530#endif /* LINUX */ 2531#ifdef SUNOS4 2532 pid = wait(&status); 2533#endif 2534 wait_errno = errno; 2535 if (interactive) 2536 sigprocmask(SIG_BLOCK, &blocked_set, NULL); 2537 2538 if (pid < 0) { 2539 switch (wait_errno) { 2540 case EINTR: 2541 continue; 2542 case ECHILD: 2543 /* 2544 * We would like to verify this case 2545 * but sometimes a race in Solbourne's 2546 * version of SunOS sometimes reports 2547 * ECHILD before sending us SIGCHILD. 2548 */ 2549 return 0; 2550 default: 2551 errno = wait_errno; 2552 perror("strace: wait"); 2553 return -1; 2554 } 2555 } 2556 if (pid == popen_pid) { 2557 if (WIFEXITED(status) || WIFSIGNALED(status)) 2558 popen_pid = 0; 2559 continue; 2560 } 2561 2562 event = ((unsigned)status >> 16); 2563 if (debug) { 2564 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 2565#ifdef LINUX 2566 if (event != 0) { 2567 static const char *const event_names[] = { 2568 [PTRACE_EVENT_CLONE] = "CLONE", 2569 [PTRACE_EVENT_FORK] = "FORK", 2570 [PTRACE_EVENT_VFORK] = "VFORK", 2571 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 2572 [PTRACE_EVENT_EXEC] = "EXEC", 2573 [PTRACE_EVENT_EXIT] = "EXIT", 2574 }; 2575 const char *e; 2576 if (event < ARRAY_SIZE(event_names)) 2577 e = event_names[event]; 2578 else { 2579 sprintf(buf, "?? (%u)", event); 2580 e = buf; 2581 } 2582 fprintf(stderr, " PTRACE_EVENT_%s", e); 2583 } 2584#endif 2585 strcpy(buf, "???"); 2586 if (WIFSIGNALED(status)) 2587#ifdef WCOREDUMP 2588 sprintf(buf, "WIFSIGNALED,%ssig=%s", 2589 WCOREDUMP(status) ? "core," : "", 2590 signame(WTERMSIG(status))); 2591#else 2592 sprintf(buf, "WIFSIGNALED,sig=%s", 2593 signame(WTERMSIG(status))); 2594#endif 2595 if (WIFEXITED(status)) 2596 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 2597 if (WIFSTOPPED(status)) 2598 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 2599#ifdef WIFCONTINUED 2600 if (WIFCONTINUED(status)) 2601 strcpy(buf, "WIFCONTINUED"); 2602#endif 2603 fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf); 2604 } 2605 2606 /* Look up 'pid' in our table. */ 2607 tcp = pid2tcb(pid); 2608 2609#ifdef LINUX 2610 /* Under Linux, execve changes pid to thread leader's pid, 2611 * and we see this changed pid on EVENT_EXEC and later, 2612 * execve sysexit. Leader "disappears" without exit 2613 * notification. Let user know that, drop leader's tcb, 2614 * and fix up pid in execve thread's tcb. 2615 * Effectively, execve thread's tcb replaces leader's tcb. 2616 * 2617 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 2618 * on exit syscall) in multithreaded programs exactly 2619 * in order to handle this case. 2620 * 2621 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 2622 * On 2.6 and earlier, it can return garbage. 2623 */ 2624 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') { 2625 long old_pid = 0; 2626 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 2627 && old_pid > 0 2628 && old_pid != pid 2629 ) { 2630 struct tcb *execve_thread = pid2tcb(old_pid); 2631 if (tcp) { 2632 outf = tcp->outf; 2633 curcol = tcp->curcol; 2634 if (!cflag) { 2635 if (printing_tcp) 2636 tprints(" <unfinished ...>\n"); 2637 printleader(tcp); 2638 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 2639 printing_tcp = NULL; 2640 fflush(outf); 2641 } 2642 if (execve_thread) { 2643 /* swap output FILEs (needed for -ff) */ 2644 tcp->outf = execve_thread->outf; 2645 execve_thread->outf = outf; 2646 } 2647 droptcb(tcp); 2648 } 2649 tcp = execve_thread; 2650 if (tcp) { 2651 tcp->pid = pid; 2652 tcp->flags |= TCB_REPRINT; 2653 } 2654 } 2655 } 2656#endif 2657 2658 if (tcp == NULL) { 2659#ifdef LINUX 2660 if (followfork) { 2661 /* This is needed to go with the CLONE_PTRACE 2662 changes in process.c/util.c: we might see 2663 the child's initial trap before we see the 2664 parent return from the clone syscall. 2665 Leave the child suspended until the parent 2666 returns from its system call. Only then 2667 will we have the association of parent and 2668 child so that we know how to do clearbpt 2669 in the child. */ 2670 tcp = alloctcb(pid); 2671 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 2672 if (!qflag) 2673 fprintf(stderr, "Process %d attached\n", 2674 pid); 2675 } 2676 else 2677 /* This can happen if a clone call used 2678 CLONE_PTRACE itself. */ 2679#endif 2680 { 2681 if (WIFSTOPPED(status)) 2682 ptrace(PTRACE_CONT, pid, (char *) 1, 0); 2683 error_msg_and_die("Unknown pid: %u", pid); 2684 } 2685 } 2686 /* set current output file */ 2687 outf = tcp->outf; 2688 curcol = tcp->curcol; 2689#ifdef LINUX 2690 if (cflag) { 2691 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 2692 tcp->stime = ru.ru_stime; 2693 } 2694#endif 2695 2696 if (WIFSIGNALED(status)) { 2697 if (pid == strace_child) 2698 exit_code = 0x100 | WTERMSIG(status); 2699 if (cflag != CFLAG_ONLY_STATS 2700 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 2701 printleader(tcp); 2702#ifdef WCOREDUMP 2703 tprintf("+++ killed by %s %s+++\n", 2704 signame(WTERMSIG(status)), 2705 WCOREDUMP(status) ? "(core dumped) " : ""); 2706#else 2707 tprintf("+++ killed by %s +++\n", 2708 signame(WTERMSIG(status))); 2709#endif 2710 printing_tcp = NULL; 2711 } 2712 fflush(tcp->outf); 2713 droptcb(tcp); 2714 continue; 2715 } 2716 if (WIFEXITED(status)) { 2717 if (pid == strace_child) 2718 exit_code = WEXITSTATUS(status); 2719 if (tcp == printing_tcp) { 2720 tprints(" <unfinished ...>\n"); 2721 printing_tcp = NULL; 2722 } 2723 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 2724 printleader(tcp); 2725 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 2726 printing_tcp = NULL; 2727 } 2728 fflush(tcp->outf); 2729 droptcb(tcp); 2730 continue; 2731 } 2732 if (!WIFSTOPPED(status)) { 2733 fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 2734 droptcb(tcp); 2735 continue; 2736 } 2737 2738 /* Is this the very first time we see this tracee stopped? */ 2739 if (tcp->flags & TCB_STARTUP) { 2740 if (debug) 2741 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 2742 tcp->flags &= ~TCB_STARTUP; 2743 if (tcp->flags & TCB_BPTSET) { 2744 /* 2745 * One example is a breakpoint inherited from 2746 * parent through fork(). 2747 */ 2748 if (clearbpt(tcp) < 0) { 2749 /* Pretty fatal */ 2750 droptcb(tcp); 2751 cleanup(); 2752 return -1; 2753 } 2754 } 2755#ifdef LINUX 2756 if (ptrace_setoptions) { 2757 if (debug) 2758 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 2759 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 2760 if (errno != ESRCH) { 2761 /* Should never happen, really */ 2762 perror_msg_and_die("PTRACE_SETOPTIONS"); 2763 } 2764 } 2765 } 2766#endif 2767 } 2768 2769 sig = WSTOPSIG(status); 2770 2771 if (event != 0) { 2772 /* Ptrace event */ 2773#ifdef USE_SEIZE 2774 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 2775 /* 2776 * PTRACE_INTERRUPT-stop or group-stop. 2777 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 2778 */ 2779 if (sig == SIGSTOP 2780 || sig == SIGTSTP 2781 || sig == SIGTTIN 2782 || sig == SIGTTOU 2783 ) { 2784 stopped = 1; 2785 goto show_stopsig; 2786 } 2787 } 2788#endif 2789 goto restart_tracee_with_sig_0; 2790 } 2791 2792 /* Is this post-attach SIGSTOP? 2793 * Interestingly, the process may stop 2794 * with STOPSIG equal to some other signal 2795 * than SIGSTOP if we happend to attach 2796 * just before the process takes a signal. 2797 */ 2798 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2799 if (debug) 2800 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2801 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 2802 goto restart_tracee_with_sig_0; 2803 } 2804 2805 if (sig != syscall_trap_sig) { 2806 siginfo_t si; 2807 2808 /* Nonzero (true) if tracee is stopped by signal 2809 * (as opposed to "tracee received signal"). 2810 */ 2811 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 2812#ifdef USE_SEIZE 2813 show_stopsig: 2814#endif 2815 if (cflag != CFLAG_ONLY_STATS 2816 && (qual_flags[sig] & QUAL_SIGNAL)) { 2817#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 2818 long pc = 0; 2819 long psr = 0; 2820 2821 upeek(tcp, PT_CR_IPSR, &psr); 2822 upeek(tcp, PT_CR_IIP, &pc); 2823 2824# define PSR_RI 41 2825 pc += (psr >> PSR_RI) & 0x3; 2826# define PC_FORMAT_STR " @ %lx" 2827# define PC_FORMAT_ARG , pc 2828#else 2829# define PC_FORMAT_STR "" 2830# define PC_FORMAT_ARG /* nothing */ 2831#endif 2832 printleader(tcp); 2833 if (!stopped) { 2834 tprints("--- "); 2835 printsiginfo(&si, verbose(tcp)); 2836 tprintf(" (%s)" PC_FORMAT_STR " ---\n", 2837 strsignal(sig) 2838 PC_FORMAT_ARG); 2839 } else 2840 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n", 2841 strsignal(sig), 2842 signame(sig) 2843 PC_FORMAT_ARG); 2844 printing_tcp = NULL; 2845 fflush(tcp->outf); 2846 } 2847 2848 if (!stopped) 2849 /* It's signal-delivery-stop. Inject the signal */ 2850 goto restart_tracee; 2851 2852 /* It's group-stop */ 2853#ifdef USE_SEIZE 2854 if (use_seize) { 2855 /* 2856 * This ends ptrace-stop, but does *not* end group-stop. 2857 * This makes stopping signals work properly on straced process 2858 * (that is, process really stops. It used to continue to run). 2859 */ 2860 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 2861 cleanup(); 2862 return -1; 2863 } 2864 continue; 2865 } 2866 /* We don't have PTRACE_LISTEN support... */ 2867#endif 2868 goto restart_tracee; 2869 } 2870 2871 /* We handled quick cases, we are permitted to interrupt now. */ 2872 if (interrupted) 2873 return 0; 2874 2875 /* This should be syscall entry or exit. 2876 * (Or it still can be that pesky post-execve SIGTRAP!) 2877 * Handle it. 2878 */ 2879 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2880 /* ptrace() failed in trace_syscall() with ESRCH. 2881 * Likely a result of process disappearing mid-flight. 2882 * Observed case: exit_group() terminating 2883 * all processes in thread group. 2884 */ 2885 if (tcp->flags & TCB_ATTACHED) { 2886 if (printing_tcp) { 2887 /* Do we have dangling line "syscall(param, param"? 2888 * Finish the line then. 2889 */ 2890 printing_tcp->flags |= TCB_REPRINT; 2891 tprints(" <unfinished ...>\n"); 2892 printing_tcp = NULL; 2893 fflush(tcp->outf); 2894 } 2895 /* We assume that ptrace error was caused by process death. 2896 * We used to detach(tcp) here, but since we no longer 2897 * implement "detach before death" policy/hack, 2898 * we can let this process to report its death to us 2899 * normally, via WIFEXITED or WIFSIGNALED wait status. 2900 */ 2901 } else { 2902 /* It's our real child (and we also trace it) */ 2903 /* my_tkill(pid, SIGKILL); - why? */ 2904 /* droptcb(tcp); - why? */ 2905 } 2906 continue; 2907 } 2908 restart_tracee_with_sig_0: 2909 sig = 0; 2910 restart_tracee: 2911 /* Remember current print column before continuing. */ 2912 tcp->curcol = curcol; 2913 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 2914 cleanup(); 2915 return -1; 2916 } 2917 } 2918 return 0; 2919} 2920 2921#endif /* !USE_PROCFS */ 2922 2923void 2924tprintf(const char *fmt, ...) 2925{ 2926 va_list args; 2927 2928 va_start(args, fmt); 2929 if (outf) { 2930 int n = vfprintf(outf, fmt, args); 2931 if (n < 0) { 2932 if (outf != stderr) 2933 perror(outfname == NULL 2934 ? "<writing to pipe>" : outfname); 2935 } else 2936 curcol += n; 2937 } 2938 va_end(args); 2939} 2940 2941void 2942tprints(const char *str) 2943{ 2944 if (outf) { 2945 int n = fputs(str, outf); 2946 if (n >= 0) { 2947 curcol += strlen(str); 2948 return; 2949 } 2950 if (outf != stderr) 2951 perror(outfname == NULL 2952 ? "<writing to pipe>" : outfname); 2953 } 2954} 2955 2956void 2957printleader(struct tcb *tcp) 2958{ 2959 if (printing_tcp) { 2960 if (printing_tcp->ptrace_errno) { 2961 if (printing_tcp->flags & TCB_INSYSCALL) { 2962 tprints(" <unavailable>) "); 2963 tabto(); 2964 } 2965 tprints("= ? <unavailable>\n"); 2966 printing_tcp->ptrace_errno = 0; 2967 } else if (!outfname || followfork < 2 || printing_tcp == tcp) { 2968 printing_tcp->flags |= TCB_REPRINT; 2969 tprints(" <unfinished ...>\n"); 2970 } 2971 } 2972 2973 printing_tcp = tcp; 2974 curcol = 0; 2975 if ((followfork == 1 || pflag_seen > 1) && outfname) 2976 tprintf("%-5d ", tcp->pid); 2977 else if (nprocs > 1 && !outfname) 2978 tprintf("[pid %5u] ", tcp->pid); 2979 if (tflag) { 2980 char str[sizeof("HH:MM:SS")]; 2981 struct timeval tv, dtv; 2982 static struct timeval otv; 2983 2984 gettimeofday(&tv, NULL); 2985 if (rflag) { 2986 if (otv.tv_sec == 0) 2987 otv = tv; 2988 tv_sub(&dtv, &tv, &otv); 2989 tprintf("%6ld.%06ld ", 2990 (long) dtv.tv_sec, (long) dtv.tv_usec); 2991 otv = tv; 2992 } 2993 else if (tflag > 2) { 2994 tprintf("%ld.%06ld ", 2995 (long) tv.tv_sec, (long) tv.tv_usec); 2996 } 2997 else { 2998 time_t local = tv.tv_sec; 2999 strftime(str, sizeof(str), "%T", localtime(&local)); 3000 if (tflag > 1) 3001 tprintf("%s.%06ld ", str, (long) tv.tv_usec); 3002 else 3003 tprintf("%s ", str); 3004 } 3005 } 3006 if (iflag) 3007 printcall(tcp); 3008} 3009 3010void 3011tabto(void) 3012{ 3013 if (curcol < acolumn) 3014 tprints(acolumn_spaces + curcol); 3015} 3016 3017#ifdef HAVE_MP_PROCFS 3018 3019int 3020mp_ioctl(int fd, int cmd, void *arg, int size) 3021{ 3022 struct iovec iov[2]; 3023 int n = 1; 3024 3025 iov[0].iov_base = &cmd; 3026 iov[0].iov_len = sizeof cmd; 3027 if (arg) { 3028 ++n; 3029 iov[1].iov_base = arg; 3030 iov[1].iov_len = size; 3031 } 3032 3033 return writev(fd, iov, n); 3034} 3035 3036#endif 3037