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>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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.
36 #include <sys/param.h>
38 #include <sys/resource.h>
44 #include <sys/utsname.h>
46 # include <asm/ptrace_offsets.h>
48 /* In some libc, these aren't declared. Do it ourself: */
49 extern char **environ;
54 #if defined __NR_tkill
55 # define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
57 /* kill() may choose arbitrarily the target task of the process group
58 while we later wait on a that specific TID. PID process waits become
59 TID task specific waits for a process under ptrace(2). */
60 # warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
61 # define my_tkill(tid, sig) kill((tid), (sig))
65 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
67 cflag_t cflag = CFLAG_NONE;
68 unsigned int followfork = 0;
69 unsigned int ptrace_setoptions = 0;
70 unsigned int xflag = 0;
74 /* Which WSTOPSIG(status) value marks syscall traps? */
75 static unsigned int syscall_trap_sig = SIGTRAP;
76 static unsigned int tflag = 0;
77 static bool iflag = 0;
78 static bool rflag = 0;
79 static bool print_pid_pfx = 0;
84 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
85 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
86 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
87 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
91 /* We play with signal mask only if this mode is active: */
92 #define interactive (opt_intr == INTR_WHILE_WAIT)
95 * daemonized_tracer supports -D option.
96 * With this option, strace forks twice.
97 * Unlike normal case, with -D *grandparent* process exec's,
98 * becoming a traced process. Child exits (this prevents traced process
99 * from having children it doesn't expect to have), and grandchild
100 * attaches to grandparent similarly to strace -p PID.
101 * This allows for more transparent interaction in cases
102 * when process and its parent are communicating via signals,
103 * wait() etc. Without -D, strace process gets lodged in between,
104 * disrupting parent<->child link.
106 static bool daemonized_tracer = 0;
109 static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
110 # define use_seize (post_attach_sigstop == 0)
112 # define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
116 /* Sometimes we want to print only succeeding syscalls. */
117 bool not_failing_only = 0;
119 /* Show path associated with fd arguments */
120 bool show_fd_path = 0;
122 /* are we filtering traces based on paths? */
123 bool tracing_paths = 0;
125 static int exit_code = 0;
126 static int strace_child = 0;
127 static int strace_tracer_pid = 0;
129 static char *username = NULL;
130 static uid_t run_uid;
131 static gid_t run_gid;
133 unsigned int max_strlen = DEFAULT_STRLEN;
134 static unsigned int acolumn = DEFAULT_ACOLUMN;
135 static char *acolumn_spaces;
136 static char *outfname = NULL;
138 struct tcb *printing_tcp = NULL;
139 static unsigned int curcol;
140 static struct tcb **tcbtab;
141 static unsigned int nprocs, tcbtabsize;
142 static const char *progname;
144 static char *os_release; /* from uname() */
146 static int detach(struct tcb *tcp);
147 static int trace(void);
148 static void cleanup(void);
149 static void interrupt(int sig);
150 static sigset_t empty_set, blocked_set;
152 #ifdef HAVE_SIG_ATOMIC_T
153 static volatile sig_atomic_t interrupted;
155 static volatile int interrupted;
159 usage(FILE *ofp, int exitval)
162 usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
163 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
164 [-P path] [PROG [ARGS]]\n\
165 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
167 -c -- count time, calls, and errors for each syscall and report summary\n\
168 -C -- like -c but also print regular output while processes are running\n\
169 -d -- enable debug output to stderr\n\
170 -D -- run tracer process as a detached grandchild, not as parent\n\
171 -f -- follow forks, -ff -- with output into separate files\n\
172 -F -- attempt to follow vforks (deprecated, use -f)\n\
173 -i -- print instruction pointer at time of syscall\n\
175 1: no signals are blocked\n\
176 2: fatal signals are blocked while decoding syscall (default)\n\
177 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
178 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
179 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
180 -q -- suppress messages about attaching, detaching, etc.\n\
181 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
182 -T -- print time spent in each syscall\n\
183 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
184 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
185 -y -- print paths associated with file descriptor arguments\n\
186 -h -- print help message\n\
187 -V -- print version\n\
188 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
189 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
190 options: trace, abbrev, verbose, raw, signal, read, or write\n\
191 -o file -- send trace output to FILE instead of stderr\n\
192 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
193 -p pid -- trace process with process id PID, may be repeated\n\
194 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
195 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
196 -u username -- run command as username handling setuid and/or setgid\n\
197 -E var=val -- put var=val in the environment for command\n\
198 -E var -- remove var from the environment for command\n\
199 -P path -- trace accesses to path\n\
200 " /* this is broken, so don't document it
201 -z -- print only succeeding syscalls\n\
203 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
207 static void die(void) __attribute__ ((noreturn));
208 static void die(void)
210 if (strace_tracer_pid == getpid()) {
217 static void verror_msg(int err_no, const char *fmt, va_list p)
223 /* We want to print entire message with single fprintf to ensure
224 * message integrity if stderr is shared with other programs.
225 * Thus we use vasprintf + single fprintf.
228 if (vasprintf(&msg, fmt, p) >= 0) {
230 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
232 fprintf(stderr, "%s: %s\n", progname, msg);
235 /* malloc in vasprintf failed, try it without malloc */
236 fprintf(stderr, "%s: ", progname);
237 vfprintf(stderr, fmt, p);
239 fprintf(stderr, ": %s\n", strerror(err_no));
243 /* We don't switch stderr to buffered, thus fprintf(stderr)
244 * always flushes its output and this is not necessary: */
245 /* fflush(stderr); */
248 void error_msg(const char *fmt, ...)
252 verror_msg(0, fmt, p);
256 void error_msg_and_die(const char *fmt, ...)
260 verror_msg(0, fmt, p);
264 void perror_msg(const char *fmt, ...)
268 verror_msg(errno, fmt, p);
272 void perror_msg_and_die(const char *fmt, ...)
276 verror_msg(errno, fmt, p);
280 void die_out_of_memory(void)
282 static bool recursed = 0;
286 error_msg_and_die("Out of memory");
289 /* Glue for systems without a MMU that cannot provide fork() */
291 # define strace_vforked 0
293 # define strace_vforked 1
294 # define fork() vfork()
299 ptrace_attach_or_seize(int pid)
303 return ptrace(PTRACE_ATTACH, pid, 0, 0);
304 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
307 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
311 # define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
315 set_cloexec_flag(int fd)
319 flags = fcntl(fd, F_GETFD);
321 /* Can happen only if fd is bad.
322 * Should never happen: if it does, we have a bug
323 * in the caller. Therefore we just abort
324 * instead of propagating the error.
326 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
329 newflags = flags | FD_CLOEXEC;
330 if (flags == newflags)
333 fcntl(fd, F_SETFD, newflags); /* never fails */
336 static void kill_save_errno(pid_t pid, int sig)
338 int saved_errno = errno;
340 (void) kill(pid, sig);
345 tprintf(const char *fmt, ...)
351 int n = vfprintf(outf, fmt, args);
354 perror(outfname == NULL
355 ? "<writing to pipe>" : outfname);
363 tprints(const char *str)
366 int n = fputs(str, outf);
368 curcol += strlen(str);
372 perror(outfname == NULL
373 ? "<writing to pipe>" : outfname);
384 printing_tcp->curcol = 0;
389 printleader(struct tcb *tcp)
391 /* If -ff, "previous tcb we printed" is always the same as current,
392 * because we have per-tcb output files.
398 outf = printing_tcp->outf;
399 curcol = printing_tcp->curcol;
400 if (printing_tcp->ptrace_errno) {
401 if (printing_tcp->flags & TCB_INSYSCALL) {
402 tprints(" <unavailable>) ");
405 tprints("= ? <unavailable>\n");
406 printing_tcp->ptrace_errno = 0;
407 printing_tcp->curcol = 0;
409 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
411 * case 1: we have a shared log (i.e. not -ff), and last line
412 * wasn't finished (same or different tcb, doesn't matter).
413 * case 2: split log, we are the same tcb, but our last line
414 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
416 tprints(" <unfinished ...>\n");
417 printing_tcp->flags |= TCB_REPRINT;
418 printing_tcp->curcol = 0;
427 tprintf("%-5d ", tcp->pid);
428 else if (nprocs > 1 && !outfname)
429 tprintf("[pid %5u] ", tcp->pid);
432 char str[sizeof("HH:MM:SS")];
433 struct timeval tv, dtv;
434 static struct timeval otv;
436 gettimeofday(&tv, NULL);
440 tv_sub(&dtv, &tv, &otv);
441 tprintf("%6ld.%06ld ",
442 (long) dtv.tv_sec, (long) dtv.tv_usec);
445 else if (tflag > 2) {
446 tprintf("%ld.%06ld ",
447 (long) tv.tv_sec, (long) tv.tv_usec);
450 time_t local = tv.tv_sec;
451 strftime(str, sizeof(str), "%T", localtime(&local));
453 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
465 if (curcol < acolumn)
466 tprints(acolumn_spaces + curcol);
470 * When strace is setuid executable, we have to swap uids
471 * before and after filesystem and process management operations.
476 int euid = geteuid(), uid = getuid();
478 if (euid != uid && setreuid(euid, uid) < 0) {
479 perror_msg_and_die("setreuid");
484 # define fopen_for_output fopen64
486 # define fopen_for_output fopen
490 strace_fopen(const char *path)
495 fp = fopen_for_output(path, "w");
497 perror_msg_and_die("Can't fopen '%s'", path);
499 set_cloexec_flag(fileno(fp));
503 static int popen_pid = 0;
506 # define _PATH_BSHELL "/bin/sh"
510 * We cannot use standard popen(3) here because we have to distinguish
511 * popen child process from other processes we trace, and standard popen(3)
512 * does not export its child's pid.
515 strace_popen(const char *command)
522 perror_msg_and_die("pipe");
524 set_cloexec_flag(fds[1]); /* never fails */
528 perror_msg_and_die("vfork");
530 if (popen_pid == 0) {
535 perror_msg_and_die("dup2");
538 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
539 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
545 fp = fdopen(fds[1], "w");
552 newoutf(struct tcb *tcp)
554 if (outfname && followfork >= 2) {
555 char name[520 + sizeof(int) * 3];
556 sprintf(name, "%.512s.%u", outfname, tcp->pid);
557 tcp->outf = strace_fopen(name);
562 process_opt_p_list(char *opt)
566 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
567 * pidof uses space as delim, pgrep uses newline. :(
570 char *delim = opt + strcspn(opt, ", \n\t");
574 pid = atoi(opt); /* TODO: stricter parsing of the number? */
576 error_msg("Invalid process id: '%s'", opt);
580 if (pid == strace_tracer_pid) {
581 error_msg("I'm sorry, I can't let you do that, Dave.");
600 * Block user interruptions as we would leave the traced
601 * process stopped (process state T) if we would terminate in
602 * between PTRACE_ATTACH and wait4() on SIGSTOP.
603 * We rely on cleanup() from this point on.
606 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
608 if (daemonized_tracer) {
611 perror_msg_and_die("fork");
613 if (pid) { /* parent */
615 * Wait for grandchild to attach to straced process
616 * (grandparent). Grandchild SIGKILLs us after it attached.
617 * Grandparent's wait() is unblocked by our death,
618 * it proceeds to exec the straced program.
621 _exit(0); /* paranoia */
624 /* We will be the tracer process. Remember our new pid: */
625 strace_tracer_pid = getpid();
628 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
631 if (!(tcp->flags & TCB_INUSE))
634 /* Is this a process we should attach to, but not yet attached? */
635 if (tcp->flags & TCB_ATTACHED)
636 continue; /* no, we already attached it */
638 /* Reinitialize the output since it may have changed */
642 if (followfork && !daemonized_tracer) {
643 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
646 sprintf(procdir, "/proc/%d/task", tcp->pid);
647 dir = opendir(procdir);
649 unsigned int ntid = 0, nerr = 0;
652 while ((de = readdir(dir)) != NULL) {
656 if (de->d_fileno == 0)
658 tid = atoi(de->d_name);
662 if (ptrace_attach_or_seize(tid) < 0) {
665 fprintf(stderr, "attach to pid %d failed\n", tid);
669 fprintf(stderr, "attach to pid %d succeeded\n", tid);
672 cur_tcp = alloctcb(tid);
673 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
677 sigprocmask(SIG_SETMASK, &empty_set, NULL);
680 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
684 perror("attach: ptrace(PTRACE_ATTACH, ...)");
689 fprintf(stderr, ntid > 1
690 ? "Process %u attached with %u threads - interrupt to quit\n"
691 : "Process %u attached - interrupt to quit\n",
694 if (!(tcp->flags & TCB_ATTACHED)) {
695 /* -p PID, we failed to attach to PID itself
696 * but did attach to some of its sibling threads.
702 } /* if (opendir worked) */
704 if (ptrace_attach_or_seize(tcp->pid) < 0) {
705 perror("attach: ptrace(PTRACE_ATTACH, ...)");
709 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
711 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
713 if (daemonized_tracer) {
715 * Make parent go away.
716 * Also makes grandparent's wait() unblock.
718 kill(getppid(), SIGKILL);
723 "Process %u attached - interrupt to quit\n",
725 } /* for each tcbtab[] */
729 sigprocmask(SIG_SETMASK, &empty_set, NULL);
733 startup_child(char **argv)
736 const char *filename;
737 char pathname[MAXPATHLEN];
742 if (strchr(filename, '/')) {
743 if (strlen(filename) > sizeof pathname - 1) {
744 errno = ENAMETOOLONG;
745 perror_msg_and_die("exec");
747 strcpy(pathname, filename);
749 #ifdef USE_DEBUGGING_EXEC
751 * Debuggers customarily check the current directory
752 * first regardless of the path but doing that gives
753 * security geeks a panic attack.
755 else if (stat(filename, &statbuf) == 0)
756 strcpy(pathname, filename);
757 #endif /* USE_DEBUGGING_EXEC */
762 for (path = getenv("PATH"); path && *path; path += m) {
763 const char *colon = strchr(path, ':');
769 m = n = strlen(path);
771 if (!getcwd(pathname, MAXPATHLEN))
773 len = strlen(pathname);
775 else if (n > sizeof pathname - 1)
778 strncpy(pathname, path, n);
781 if (len && pathname[len - 1] != '/')
782 pathname[len++] = '/';
783 strcpy(pathname + len, filename);
784 if (stat(pathname, &statbuf) == 0 &&
785 /* Accept only regular files
786 with some execute bits set.
787 XXX not perfect, might still fail */
788 S_ISREG(statbuf.st_mode) &&
789 (statbuf.st_mode & 0111))
793 if (stat(pathname, &statbuf) < 0) {
794 perror_msg_and_die("Can't stat '%s'", filename);
796 strace_child = pid = fork();
798 perror_msg_and_die("fork");
800 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
801 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
806 if (!daemonized_tracer && !use_seize) {
807 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
808 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
812 if (username != NULL) {
813 uid_t run_euid = run_uid;
814 gid_t run_egid = run_gid;
816 if (statbuf.st_mode & S_ISUID)
817 run_euid = statbuf.st_uid;
818 if (statbuf.st_mode & S_ISGID)
819 run_egid = statbuf.st_gid;
821 * It is important to set groups before we
822 * lose privileges on setuid.
824 if (initgroups(username, run_gid) < 0) {
825 perror_msg_and_die("initgroups");
827 if (setregid(run_gid, run_egid) < 0) {
828 perror_msg_and_die("setregid");
830 if (setreuid(run_uid, run_euid) < 0) {
831 perror_msg_and_die("setreuid");
834 else if (geteuid() != 0)
835 setreuid(run_uid, run_uid);
837 if (!daemonized_tracer) {
839 * Induce a ptrace stop. Tracer (our parent)
840 * will resume us with PTRACE_SYSCALL and display
841 * the immediately following execve syscall.
842 * Can't do this on NOMMU systems, we are after
843 * vfork: parent is blocked, stopping would deadlock.
848 struct sigaction sv_sigchld;
849 sigaction(SIGCHLD, NULL, &sv_sigchld);
851 * Make sure it is not SIG_IGN, otherwise wait
854 signal(SIGCHLD, SIG_DFL);
856 * Wait for grandchild to attach to us.
857 * It kills child after that, and wait() unblocks.
862 sigaction(SIGCHLD, &sv_sigchld, NULL);
865 execv(pathname, argv);
866 perror_msg_and_die("exec");
869 /* We are the tracer */
871 if (!daemonized_tracer) {
873 /* child did PTRACE_TRACEME, nothing to do in parent */
875 if (!strace_vforked) {
876 /* Wait until child stopped itself */
878 while (waitpid(pid, &status, WSTOPPED) < 0) {
881 perror_msg_and_die("waitpid");
883 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
884 kill_save_errno(pid, SIGKILL);
885 perror_msg_and_die("Unexpected wait status %x", status);
888 /* Else: vforked case, we have no way to sync.
889 * Just attach to it as soon as possible.
890 * This means that we may miss a few first syscalls...
893 if (ptrace_attach_or_seize(pid)) {
894 kill_save_errno(pid, SIGKILL);
895 perror_msg_and_die("Can't attach to %d", pid);
902 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
904 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
907 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
908 strace_tracer_pid = getpid();
909 /* The tracee is our parent: */
912 /* attaching will be done later, by startup_attach */
917 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
918 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
919 * and then see which options are supported by the kernel.
922 test_ptrace_setoptions_followfork(void)
924 int pid, expected_grandchild = 0, found_grandchild = 0;
925 const unsigned int test_options = PTRACE_O_TRACECLONE |
931 perror_msg_and_die("fork");
934 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
935 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
937 kill_save_errno(pid, SIGSTOP);
939 perror_msg_and_die("fork");
944 int status, tracee_pid;
947 tracee_pid = wait(&status);
948 if (tracee_pid <= 0) {
953 kill_save_errno(pid, SIGKILL);
954 perror_msg_and_die("%s: unexpected wait result %d",
955 __func__, tracee_pid);
957 if (WIFEXITED(status)) {
958 if (WEXITSTATUS(status)) {
959 if (tracee_pid != pid)
960 kill_save_errno(pid, SIGKILL);
961 error_msg_and_die("%s: unexpected exit status %u",
962 __func__, WEXITSTATUS(status));
966 if (WIFSIGNALED(status)) {
967 if (tracee_pid != pid)
968 kill_save_errno(pid, SIGKILL);
969 error_msg_and_die("%s: unexpected signal %u",
970 __func__, WTERMSIG(status));
972 if (!WIFSTOPPED(status)) {
973 if (tracee_pid != pid)
974 kill_save_errno(tracee_pid, SIGKILL);
975 kill_save_errno(pid, SIGKILL);
976 error_msg_and_die("%s: unexpected wait status %x",
979 if (tracee_pid != pid) {
980 found_grandchild = tracee_pid;
981 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
982 kill_save_errno(tracee_pid, SIGKILL);
983 kill_save_errno(pid, SIGKILL);
984 perror_msg_and_die("PTRACE_CONT doesn't work");
988 switch (WSTOPSIG(status)) {
990 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
991 && errno != EINVAL && errno != EIO)
992 perror_msg("PTRACE_SETOPTIONS");
995 if (status >> 16 == PTRACE_EVENT_FORK) {
998 if (ptrace(PTRACE_GETEVENTMSG, pid,
999 NULL, (long) &msg) == 0)
1000 expected_grandchild = msg;
1004 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1005 kill_save_errno(pid, SIGKILL);
1006 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1009 if (expected_grandchild && expected_grandchild == found_grandchild) {
1010 ptrace_setoptions |= test_options;
1012 fprintf(stderr, "ptrace_setoptions = %#x\n",
1016 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1017 "giving up using this feature.");
1021 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1022 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1023 * and then see whether it will stop with (SIGTRAP | 0x80).
1025 * Use of this option enables correct handling of user-generated SIGTRAPs,
1026 * and SIGTRAPs generated by special instructions such as int3 on x86:
1027 * _start: .globl _start
1032 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1035 test_ptrace_setoptions_for_all(void)
1037 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1044 perror_msg_and_die("fork");
1048 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1049 /* Note: exits with exitcode 1 */
1050 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1053 _exit(0); /* parent should see entry into this syscall */
1057 int status, tracee_pid;
1060 tracee_pid = wait(&status);
1061 if (tracee_pid <= 0) {
1064 kill_save_errno(pid, SIGKILL);
1065 perror_msg_and_die("%s: unexpected wait result %d",
1066 __func__, tracee_pid);
1068 if (WIFEXITED(status)) {
1069 if (WEXITSTATUS(status) == 0)
1071 error_msg_and_die("%s: unexpected exit status %u",
1072 __func__, WEXITSTATUS(status));
1074 if (WIFSIGNALED(status)) {
1075 error_msg_and_die("%s: unexpected signal %u",
1076 __func__, WTERMSIG(status));
1078 if (!WIFSTOPPED(status)) {
1080 error_msg_and_die("%s: unexpected wait status %x",
1083 if (WSTOPSIG(status) == SIGSTOP) {
1085 * We don't check "options aren't accepted" error.
1086 * If it happens, we'll never get (SIGTRAP | 0x80),
1087 * and thus will decide to not use the option.
1088 * IOW: the outcome of the test will be correct.
1090 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1091 && errno != EINVAL && errno != EIO)
1092 perror_msg("PTRACE_SETOPTIONS");
1094 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1097 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1098 kill_save_errno(pid, SIGKILL);
1099 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1104 syscall_trap_sig = (SIGTRAP | 0x80);
1105 ptrace_setoptions |= test_options;
1107 fprintf(stderr, "ptrace_setoptions = %#x\n",
1112 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1113 "giving up using this feature.");
1118 test_ptrace_seize(void)
1124 perror_msg_and_die("fork");
1131 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1132 * attaching tracee continues to run unless a trap condition occurs.
1133 * PTRACE_SEIZE doesn't affect signal or group stop state.
1135 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1136 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1137 } else if (debug_flag) {
1138 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1144 int status, tracee_pid;
1147 tracee_pid = waitpid(pid, &status, 0);
1148 if (tracee_pid <= 0) {
1151 perror_msg_and_die("%s: unexpected wait result %d",
1152 __func__, tracee_pid);
1154 if (WIFSIGNALED(status)) {
1157 error_msg_and_die("%s: unexpected wait status %x",
1161 # else /* !USE_SEIZE */
1162 # define test_ptrace_seize() ((void)0)
1166 get_os_release(void)
1170 perror_msg_and_die("uname");
1171 os_release = strdup(u.release);
1173 die_out_of_memory();
1177 * Initialization part of main() was eating much stack (~0.5k),
1178 * which was unused after init.
1179 * We can reuse it if we move init code into a separate function.
1181 * Don't want main() to inline us and defeat the reason
1182 * we have a separate function.
1184 static void __attribute__ ((noinline))
1185 init(int argc, char *argv[])
1190 struct sigaction sa;
1192 progname = argv[0] ? argv[0] : "strace";
1194 strace_tracer_pid = getpid();
1198 /* Allocate the initial tcbtab. */
1199 tcbtabsize = argc; /* Surely enough for all -p args. */
1200 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1202 die_out_of_memory();
1203 tcp = calloc(tcbtabsize, sizeof(*tcp));
1205 die_out_of_memory();
1206 for (c = 0; c < tcbtabsize; c++)
1210 set_sortby(DEFAULT_SORTBY);
1211 set_personality(DEFAULT_PERSONALITY);
1212 qualify("trace=all");
1213 qualify("abbrev=all");
1214 qualify("verbose=all");
1215 qualify("signal=all");
1216 while ((c = getopt(argc, argv,
1219 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1222 if (cflag == CFLAG_BOTH) {
1223 error_msg_and_die("-c and -C are mutually exclusive options");
1225 cflag = CFLAG_ONLY_STATS;
1228 if (cflag == CFLAG_ONLY_STATS) {
1229 error_msg_and_die("-c and -C are mutually exclusive options");
1237 daemonized_tracer = 1;
1256 /* fall through to tflag++ */
1270 qualify("abbrev=none");
1273 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1277 not_failing_only = 1;
1280 acolumn = atoi(optarg);
1282 error_msg_and_die("Bad column width '%s'", optarg);
1288 outfname = strdup(optarg);
1291 set_overhead(atoi(optarg));
1294 process_opt_p_list(optarg);
1298 if (pathtrace_select(optarg)) {
1299 error_msg_and_die("Failed to select path '%s'", optarg);
1303 max_strlen = atoi(optarg);
1304 if (max_strlen < 0) {
1305 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1312 username = strdup(optarg);
1315 if (putenv(optarg) < 0)
1316 die_out_of_memory();
1319 opt_intr = atoi(optarg);
1320 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1321 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1330 /* argc -= optind; - no need, argc is not used below */
1332 acolumn_spaces = malloc(acolumn + 1);
1333 if (!acolumn_spaces)
1334 die_out_of_memory();
1335 memset(acolumn_spaces, ' ', acolumn);
1336 acolumn_spaces[acolumn] = '\0';
1338 /* Must have PROG [ARGS], or -p PID. Not both. */
1339 if (!argv[0] == !nprocs)
1342 if (nprocs != 0 && daemonized_tracer) {
1343 error_msg_and_die("-D and -p are mutually exclusive options");
1349 if (followfork > 1 && cflag) {
1350 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
1353 /* See if they want to run as another user. */
1354 if (username != NULL) {
1355 struct passwd *pent;
1357 if (getuid() != 0 || geteuid() != 0) {
1358 error_msg_and_die("You must be root to use the -u option");
1360 pent = getpwnam(username);
1362 error_msg_and_die("Cannot find user '%s'", username);
1364 run_uid = pent->pw_uid;
1365 run_gid = pent->pw_gid;
1373 test_ptrace_setoptions_followfork();
1374 test_ptrace_setoptions_for_all();
1375 test_ptrace_seize();
1377 /* Check if they want to redirect the output. */
1379 /* See if they want to pipe the output. */
1380 if (outfname[0] == '|' || outfname[0] == '!') {
1382 * We can't do the <outfname>.PID funny business
1383 * when using popen, so prohibit it.
1386 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1387 outf = strace_popen(outfname + 1);
1389 else if (followfork <= 1)
1390 outf = strace_fopen(outfname);
1392 /* -ff without -o FILE is the same as single -f */
1397 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1398 char *buf = malloc(BUFSIZ);
1400 die_out_of_memory();
1401 setvbuf(outf, buf, _IOLBF, BUFSIZ);
1403 if (outfname && argv[0]) {
1405 opt_intr = INTR_NEVER;
1409 opt_intr = INTR_WHILE_WAIT;
1411 /* argv[0] -pPID -oFILE Default interactive setting
1412 * yes 0 0 INTR_WHILE_WAIT
1413 * no 1 0 INTR_WHILE_WAIT
1414 * yes 0 1 INTR_NEVER
1415 * no 1 1 INTR_WHILE_WAIT
1418 /* STARTUP_CHILD must be called before the signal handlers get
1419 installed below as they are inherited into the spawned process.
1420 Also we do not need to be protected by them as during interruption
1421 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1423 startup_child(argv);
1425 sigemptyset(&empty_set);
1426 sigemptyset(&blocked_set);
1427 sa.sa_handler = SIG_IGN;
1428 sigemptyset(&sa.sa_mask);
1430 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1431 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1432 if (opt_intr != INTR_ANYWHERE) {
1433 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1434 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1436 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1437 * fatal signals are blocked while syscall stop is processed,
1438 * and acted on in between, when waiting for new syscall stops.
1439 * In non-interactive mode, signals are ignored.
1441 if (opt_intr == INTR_WHILE_WAIT) {
1442 sigaddset(&blocked_set, SIGHUP);
1443 sigaddset(&blocked_set, SIGINT);
1444 sigaddset(&blocked_set, SIGQUIT);
1445 sigaddset(&blocked_set, SIGPIPE);
1446 sigaddset(&blocked_set, SIGTERM);
1447 sa.sa_handler = interrupt;
1449 /* SIG_IGN, or set handler for these */
1450 sigaction(SIGHUP, &sa, NULL);
1451 sigaction(SIGINT, &sa, NULL);
1452 sigaction(SIGQUIT, &sa, NULL);
1453 sigaction(SIGPIPE, &sa, NULL);
1454 sigaction(SIGTERM, &sa, NULL);
1456 /* Make sure SIGCHLD has the default action so that waitpid
1457 definitely works without losing track of children. The user
1458 should not have given us a bogus state to inherit, but he might
1459 have. Arguably we should detect SIG_IGN here and pass it on
1460 to children, but probably noone really needs that. */
1461 sa.sa_handler = SIG_DFL;
1462 sigaction(SIGCHLD, &sa, NULL);
1464 if (nprocs != 0 || daemonized_tracer)
1467 /* Do we want pids printed in our -o OUTFILE?
1468 * -ff: no (every pid has its own file); or
1469 * -f: yes (there can be more pids in the future); or
1470 * -p PID1,PID2: yes (there are already more than one pid)
1472 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1478 /* Allocate some more TCBs and expand the table.
1479 We don't want to relocate the TCBs because our
1480 callers have pointers and it would be a pain.
1481 So tcbtab is a table of pointers. Since we never
1482 free the TCBs, we allocate a single chunk of many. */
1484 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1485 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
1486 if (!newtab || !newtcbs)
1487 die_out_of_memory();
1490 while (i < tcbtabsize)
1491 tcbtab[i++] = newtcbs++;
1495 alloc_tcb(int pid, int command_options_parsed)
1500 if (nprocs == tcbtabsize)
1503 for (i = 0; i < tcbtabsize; i++) {
1505 if ((tcp->flags & TCB_INUSE) == 0) {
1506 memset(tcp, 0, sizeof(*tcp));
1508 tcp->flags = TCB_INUSE;
1509 tcp->outf = outf; /* Initialise to current out file */
1510 #if SUPPORTED_PERSONALITIES > 1
1511 tcp->currpers = current_personality;
1515 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
1516 if (command_options_parsed)
1521 error_msg_and_die("bug in alloc_tcb");
1532 for (i = 0; i < tcbtabsize; i++) {
1533 struct tcb *tcp = tcbtab[i];
1534 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1542 droptcb(struct tcb *tcp)
1549 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
1552 if (outfname && followfork >= 2) {
1553 if (tcp->curcol != 0)
1554 fprintf(tcp->outf, " <detached ...>\n");
1556 if (outf == tcp->outf)
1559 if (printing_tcp == tcp && tcp->curcol != 0)
1560 fprintf(tcp->outf, " <detached ...>\n");
1565 if (printing_tcp == tcp)
1566 printing_tcp = NULL;
1568 memset(tcp, 0, sizeof(*tcp));
1571 /* detach traced process; continue with sig
1572 * Never call DETACH twice on the same process as both unattached and
1573 * attached-unstopped processes give the same ESRCH. For unattached process we
1574 * would SIGSTOP it and wait for its SIGSTOP notification forever.
1577 detach(struct tcb *tcp)
1580 int status, sigstop_expected;
1582 if (tcp->flags & TCB_BPTSET)
1586 * Linux wrongly insists the child be stopped
1587 * before detaching. Arghh. We go through hoops
1588 * to make a clean break of things.
1591 #undef PTRACE_DETACH
1592 #define PTRACE_DETACH PTRACE_SUNDETACH
1596 sigstop_expected = 0;
1597 if (tcp->flags & TCB_ATTACHED) {
1599 * We attached but possibly didn't see the expected SIGSTOP.
1600 * We must catch exactly one as otherwise the detached process
1601 * would be left stopped (process state T).
1603 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1604 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1606 /* On a clear day, you can see forever. */
1608 else if (errno != ESRCH) {
1609 /* Shouldn't happen. */
1610 perror("detach: ptrace(PTRACE_DETACH, ...)");
1612 else if (my_tkill(tcp->pid, 0) < 0) {
1614 perror("detach: checking sanity");
1616 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
1618 perror("detach: stopping child");
1621 sigstop_expected = 1;
1624 if (sigstop_expected) {
1627 if (waitpid(tcp->pid, &status, __WALL) < 0) {
1628 if (errno == ECHILD) /* Already gone. */
1630 if (errno != EINVAL) {
1631 perror("detach: waiting");
1635 /* No __WALL here. */
1636 if (waitpid(tcp->pid, &status, 0) < 0) {
1637 if (errno != ECHILD) {
1638 perror("detach: waiting");
1642 /* If no processes, try clones. */
1643 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
1644 if (errno != ECHILD)
1645 perror("detach: waiting");
1648 #endif /* __WCLONE */
1653 if (!WIFSTOPPED(status)) {
1654 /* Au revoir, mon ami. */
1657 if (WSTOPSIG(status) == SIGSTOP) {
1658 ptrace_restart(PTRACE_DETACH, tcp, 0);
1661 error = ptrace_restart(PTRACE_CONT, tcp,
1662 WSTOPSIG(status) == syscall_trap_sig ? 0
1663 : WSTOPSIG(status));
1669 if (!qflag && (tcp->flags & TCB_ATTACHED))
1670 fprintf(stderr, "Process %u detached\n", tcp->pid);
1684 /* 'interrupted' is a volatile object, fetch it only once */
1685 fatal_sig = interrupted;
1687 fatal_sig = SIGTERM;
1689 for (i = 0; i < tcbtabsize; i++) {
1691 if (!(tcp->flags & TCB_INUSE))
1695 "cleanup: looking at pid %u\n", tcp->pid);
1696 if (tcp->flags & TCB_STRACE_CHILD) {
1697 kill(tcp->pid, SIGCONT);
1698 kill(tcp->pid, fatal_sig);
1712 #ifndef HAVE_STRERROR
1714 #if !HAVE_DECL_SYS_ERRLIST
1715 extern int sys_nerr;
1716 extern char *sys_errlist[];
1717 #endif /* HAVE_DECL_SYS_ERRLIST */
1720 strerror(int err_no)
1722 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
1724 if (err_no < 1 || err_no >= sys_nerr) {
1725 sprintf(buf, "Unknown error %d", err_no);
1728 return sys_errlist[err_no];
1731 #endif /* HAVE_STERRROR */
1733 #ifndef HAVE_STRSIGNAL
1735 #if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
1736 extern char *sys_siglist[];
1738 #if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1739 extern char *_sys_siglist[];
1745 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3];
1747 if (sig < 1 || sig >= NSIG) {
1748 sprintf(buf, "Unknown signal %d", sig);
1751 #ifdef HAVE__SYS_SIGLIST
1752 return _sys_siglist[sig];
1754 return sys_siglist[sig];
1758 #endif /* HAVE_STRSIGNAL */
1764 struct rusage *rup = cflag ? &ru : NULL;
1766 static int wait4_options = __WALL;
1769 while (nprocs != 0) {
1780 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1782 pid = wait4(-1, &status, wait4_options, rup);
1783 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1784 /* this kernel does not support __WALL */
1785 wait4_options &= ~__WALL;
1786 pid = wait4(-1, &status, wait4_options, rup);
1788 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1789 /* most likely a "cloned" process */
1790 pid = wait4(-1, &status, __WCLONE, rup);
1792 perror_msg("wait4(__WCLONE) failed");
1796 pid = wait4(-1, &status, 0, rup);
1797 # endif /* __WALL */
1800 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1803 switch (wait_errno) {
1808 * We would like to verify this case
1809 * but sometimes a race in Solbourne's
1810 * version of SunOS sometimes reports
1811 * ECHILD before sending us SIGCHILD.
1820 if (pid == popen_pid) {
1821 if (WIFEXITED(status) || WIFSIGNALED(status))
1826 event = ((unsigned)status >> 16);
1828 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1829 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1831 if (WIFSIGNALED(status))
1833 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1834 WCOREDUMP(status) ? "core," : "",
1835 signame(WTERMSIG(status)));
1837 sprintf(buf, "WIFSIGNALED,sig=%s",
1838 signame(WTERMSIG(status)));
1840 if (WIFEXITED(status))
1841 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1842 if (WIFSTOPPED(status))
1843 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1845 if (WIFCONTINUED(status))
1846 strcpy(buf, "WIFCONTINUED");
1850 static const char *const event_names[] = {
1851 [PTRACE_EVENT_CLONE] = "CLONE",
1852 [PTRACE_EVENT_FORK] = "FORK",
1853 [PTRACE_EVENT_VFORK] = "VFORK",
1854 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1855 [PTRACE_EVENT_EXEC] = "EXEC",
1856 [PTRACE_EVENT_EXIT] = "EXIT",
1859 if (event < ARRAY_SIZE(event_names))
1860 e = event_names[event];
1862 sprintf(buf, "?? (%u)", event);
1865 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1867 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1870 /* Look up 'pid' in our table. */
1873 /* Under Linux, execve changes pid to thread leader's pid,
1874 * and we see this changed pid on EVENT_EXEC and later,
1875 * execve sysexit. Leader "disappears" without exit
1876 * notification. Let user know that, drop leader's tcb,
1877 * and fix up pid in execve thread's tcb.
1878 * Effectively, execve thread's tcb replaces leader's tcb.
1880 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1881 * on exit syscall) in multithreaded programs exactly
1882 * in order to handle this case.
1884 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1885 * On 2.6 and earlier, it can return garbage.
1887 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') {
1889 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1893 struct tcb *execve_thread = pid2tcb(old_pid);
1896 curcol = tcp->curcol;
1897 if (execve_thread) {
1898 if (execve_thread->curcol != 0) {
1900 * One case we are here is -ff:
1901 * try "strace -oLOG -ff test/threaded_execve"
1903 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1904 execve_thread->curcol = 0;
1906 /* swap output FILEs (needed for -ff) */
1907 tcp->outf = execve_thread->outf;
1908 tcp->curcol = execve_thread->curcol;
1909 execve_thread->outf = outf;
1910 execve_thread->curcol = curcol;
1914 tcp = execve_thread;
1917 tcp->flags |= TCB_REPRINT;
1920 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1929 /* This is needed to go with the CLONE_PTRACE
1930 changes in process.c/util.c: we might see
1931 the child's initial trap before we see the
1932 parent return from the clone syscall.
1933 Leave the child suspended until the parent
1934 returns from its system call. Only then
1935 will we have the association of parent and
1936 child so that we know how to do clearbpt
1938 tcp = alloctcb(pid);
1939 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1941 fprintf(stderr, "Process %d attached\n",
1945 /* This can happen if a clone call used
1946 CLONE_PTRACE itself. */
1948 if (WIFSTOPPED(status))
1949 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1950 error_msg_and_die("Unknown pid: %u", pid);
1954 /* Set current output file */
1956 curcol = tcp->curcol;
1959 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1960 tcp->stime = ru.ru_stime;
1963 if (WIFSIGNALED(status)) {
1964 if (pid == strace_child)
1965 exit_code = 0x100 | WTERMSIG(status);
1966 if (cflag != CFLAG_ONLY_STATS
1967 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1970 tprintf("+++ killed by %s %s+++\n",
1971 signame(WTERMSIG(status)),
1972 WCOREDUMP(status) ? "(core dumped) " : "");
1974 tprintf("+++ killed by %s +++\n",
1975 signame(WTERMSIG(status)));
1982 if (WIFEXITED(status)) {
1983 if (pid == strace_child)
1984 exit_code = WEXITSTATUS(status);
1985 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1987 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
1993 if (!WIFSTOPPED(status)) {
1994 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1999 /* Is this the very first time we see this tracee stopped? */
2000 if (tcp->flags & TCB_STARTUP) {
2002 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2003 tcp->flags &= ~TCB_STARTUP;
2004 if (tcp->flags & TCB_BPTSET) {
2006 * One example is a breakpoint inherited from
2007 * parent through fork().
2009 if (clearbpt(tcp) < 0) {
2016 if (ptrace_setoptions) {
2018 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2019 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2020 if (errno != ESRCH) {
2021 /* Should never happen, really */
2022 perror_msg_and_die("PTRACE_SETOPTIONS");
2028 sig = WSTOPSIG(status);
2033 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
2035 * PTRACE_INTERRUPT-stop or group-stop.
2036 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2048 goto restart_tracee_with_sig_0;
2051 /* Is this post-attach SIGSTOP?
2052 * Interestingly, the process may stop
2053 * with STOPSIG equal to some other signal
2054 * than SIGSTOP if we happend to attach
2055 * just before the process takes a signal.
2057 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2059 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2060 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2061 goto restart_tracee_with_sig_0;
2064 if (sig != syscall_trap_sig) {
2067 /* Nonzero (true) if tracee is stopped by signal
2068 * (as opposed to "tracee received signal").
2070 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2074 if (cflag != CFLAG_ONLY_STATS
2075 && (qual_flags[sig] & QUAL_SIGNAL)) {
2076 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2080 upeek(tcp, PT_CR_IPSR, &psr);
2081 upeek(tcp, PT_CR_IIP, &pc);
2084 pc += (psr >> PSR_RI) & 0x3;
2085 # define PC_FORMAT_STR " @ %lx"
2086 # define PC_FORMAT_ARG , pc
2088 # define PC_FORMAT_STR ""
2089 # define PC_FORMAT_ARG /* nothing */
2094 printsiginfo(&si, verbose(tcp));
2095 tprintf(" (%s)" PC_FORMAT_STR " ---\n",
2099 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n",
2107 /* It's signal-delivery-stop. Inject the signal */
2108 goto restart_tracee;
2110 /* It's group-stop */
2114 * This ends ptrace-stop, but does *not* end group-stop.
2115 * This makes stopping signals work properly on straced process
2116 * (that is, process really stops. It used to continue to run).
2118 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2122 tcp->curcol = curcol;
2125 /* We don't have PTRACE_LISTEN support... */
2127 goto restart_tracee;
2130 /* We handled quick cases, we are permitted to interrupt now. */
2134 /* This should be syscall entry or exit.
2135 * (Or it still can be that pesky post-execve SIGTRAP!)
2138 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2139 /* ptrace() failed in trace_syscall() with ESRCH.
2140 * Likely a result of process disappearing mid-flight.
2141 * Observed case: exit_group() terminating
2142 * all processes in thread group.
2143 * We assume that ptrace error was caused by process death.
2144 * We used to detach(tcp) here, but since we no longer
2145 * implement "detach before death" policy/hack,
2146 * we can let this process to report its death to us
2147 * normally, via WIFEXITED or WIFSIGNALED wait status.
2149 tcp->curcol = curcol;
2152 restart_tracee_with_sig_0:
2155 /* Remember current print column before continuing. */
2156 tcp->curcol = curcol;
2157 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2166 main(int argc, char *argv[])
2170 /* Run main tracing loop */
2176 if (exit_code > 0xff) {
2177 /* Avoid potential core file clobbering. */
2178 struct rlimit rlim = {0, 0};
2179 setrlimit(RLIMIT_CORE, &rlim);
2181 /* Child was killed by a signal, mimic that. */
2183 signal(exit_code, SIG_DFL);
2185 /* Paranoia - what if this signal is not fatal?
2186 Exit with 128 + signo then. */