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.
33 #include <sys/param.h>
35 #include <sys/resource.h>
41 #include <sys/utsname.h>
43 # include <asm/ptrace_offsets.h>
45 /* In some libc, these aren't declared. Do it ourself: */
46 extern char **environ;
51 #if defined __NR_tkill
52 # define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
54 /* kill() may choose arbitrarily the target task of the process group
55 while we later wait on a that specific TID. PID process waits become
56 TID task specific waits for a process under ptrace(2). */
57 # warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
58 # define my_tkill(tid, sig) kill((tid), (sig))
62 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
64 cflag_t cflag = CFLAG_NONE;
65 unsigned int followfork = 0;
66 unsigned int ptrace_setoptions = 0;
67 unsigned int xflag = 0;
71 /* Which WSTOPSIG(status) value marks syscall traps? */
72 static unsigned int syscall_trap_sig = SIGTRAP;
73 static unsigned int tflag = 0;
74 static bool iflag = 0;
75 static bool rflag = 0;
76 static bool print_pid_pfx = 0;
81 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
82 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
83 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
84 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
88 /* We play with signal mask only if this mode is active: */
89 #define interactive (opt_intr == INTR_WHILE_WAIT)
92 * daemonized_tracer supports -D option.
93 * With this option, strace forks twice.
94 * Unlike normal case, with -D *grandparent* process exec's,
95 * becoming a traced process. Child exits (this prevents traced process
96 * from having children it doesn't expect to have), and grandchild
97 * attaches to grandparent similarly to strace -p PID.
98 * This allows for more transparent interaction in cases
99 * when process and its parent are communicating via signals,
100 * wait() etc. Without -D, strace process gets lodged in between,
101 * disrupting parent<->child link.
103 static bool daemonized_tracer = 0;
106 static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
107 # define use_seize (post_attach_sigstop == 0)
109 # define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
113 /* Sometimes we want to print only succeeding syscalls. */
114 bool not_failing_only = 0;
116 /* Show path associated with fd arguments */
117 bool show_fd_path = 0;
119 /* are we filtering traces based on paths? */
120 bool tracing_paths = 0;
122 static bool detach_on_execve = 0;
123 static bool skip_startup_execve = 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 int acolumn = DEFAULT_ACOLUMN;
135 static char *acolumn_spaces;
137 static char *outfname = NULL;
138 /* If -ff, points to stderr. Else, it's our common output log */
139 static FILE *shared_log;
141 struct tcb *printing_tcp = NULL;
142 static struct tcb *current_tcp;
144 static struct tcb **tcbtab;
145 static unsigned int nprocs, tcbtabsize;
146 static const char *progname;
148 static unsigned os_release; /* generated from uname()'s u.release */
150 static int detach(struct tcb *tcp);
151 static int trace(void);
152 static void cleanup(void);
153 static void interrupt(int sig);
154 static sigset_t empty_set, blocked_set;
156 #ifdef HAVE_SIG_ATOMIC_T
157 static volatile sig_atomic_t interrupted;
159 static volatile int interrupted;
162 #ifndef HAVE_STRERROR
164 #if !HAVE_DECL_SYS_ERRLIST
166 extern char *sys_errlist[];
172 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
174 if (err_no < 1 || err_no >= sys_nerr) {
175 sprintf(buf, "Unknown error %d", err_no);
178 return sys_errlist[err_no];
181 #endif /* HAVE_STERRROR */
184 usage(FILE *ofp, int exitval)
187 usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
188 [-a column] [-o file] [-s strsize] [-P path]...\n\
189 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
190 or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
191 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
192 -c -- count time, calls, and errors for each syscall and report summary\n\
193 -C -- like -c but also print regular output\n\
194 -d -- enable debug output to stderr\n\
195 -D -- run tracer process as a detached grandchild, not as parent\n\
196 -f -- follow forks, -ff -- with output into separate files\n\
197 -F -- attempt to follow vforks (deprecated, use -f)\n\
198 -i -- print instruction pointer at time of syscall\n\
199 -q -- suppress messages about attaching, detaching, etc.\n\
200 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
201 -T -- print time spent in each syscall\n\
202 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
203 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
204 -y -- print paths associated with file descriptor arguments\n\
205 -h -- print help message, -V -- print version\n\
206 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
207 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
208 options: trace, abbrev, verbose, raw, signal, read, or write\n\
209 -I interruptible --\n\
210 1: no signals are blocked\n\
211 2: fatal signals are blocked while decoding syscall (default)\n\
212 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
213 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
214 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
215 -o file -- send trace output to FILE instead of stderr\n\
216 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
217 -p pid -- trace process with process id PID, may be repeated\n\
218 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
219 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
220 -u username -- run command as username handling setuid and/or setgid\n\
221 -E var=val -- put var=val in the environment for command\n\
222 -E var -- remove var from the environment for command\n\
223 -P path -- trace accesses to path\n\
225 /* this is broken, so don't document it
226 -z -- print only succeeding syscalls\n\
228 /* experimental, don't document it yet (option letter may change in the future!)
229 -b -- detach on successful execve\n\
231 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
235 static void die(void) __attribute__ ((noreturn));
236 static void die(void)
238 if (strace_tracer_pid == getpid()) {
245 static void verror_msg(int err_no, const char *fmt, va_list p)
251 /* We want to print entire message with single fprintf to ensure
252 * message integrity if stderr is shared with other programs.
253 * Thus we use vasprintf + single fprintf.
256 if (vasprintf(&msg, fmt, p) >= 0) {
258 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
260 fprintf(stderr, "%s: %s\n", progname, msg);
263 /* malloc in vasprintf failed, try it without malloc */
264 fprintf(stderr, "%s: ", progname);
265 vfprintf(stderr, fmt, p);
267 fprintf(stderr, ": %s\n", strerror(err_no));
271 /* We don't switch stderr to buffered, thus fprintf(stderr)
272 * always flushes its output and this is not necessary: */
273 /* fflush(stderr); */
276 void error_msg(const char *fmt, ...)
280 verror_msg(0, fmt, p);
284 void error_msg_and_die(const char *fmt, ...)
288 verror_msg(0, fmt, p);
292 void perror_msg(const char *fmt, ...)
296 verror_msg(errno, fmt, p);
300 void perror_msg_and_die(const char *fmt, ...)
304 verror_msg(errno, fmt, p);
308 void die_out_of_memory(void)
310 static bool recursed = 0;
314 error_msg_and_die("Out of memory");
318 error_opt_arg(int opt, const char *arg)
320 error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
323 /* Glue for systems without a MMU that cannot provide fork() */
325 # define strace_vforked 0
327 # define strace_vforked 1
328 # define fork() vfork()
333 ptrace_attach_or_seize(int pid)
337 return ptrace(PTRACE_ATTACH, pid, 0, 0);
338 r = ptrace(PTRACE_SEIZE, pid, 0, 0);
341 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
345 # define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
349 * Used when we want to unblock stopped traced process.
350 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
351 * Returns 0 on success or if error was ESRCH
352 * (presumably process was killed while we talk to it).
353 * Otherwise prints error message and returns -1.
356 ptrace_restart(int op, struct tcb *tcp, int sig)
362 ptrace(op, tcp->pid, (void *) 0, (long) sig);
368 if (op == PTRACE_CONT)
370 if (op == PTRACE_DETACH)
373 if (op == PTRACE_LISTEN)
377 * Why curcol != 0? Otherwise sometimes we get this:
379 * 10252 kill(10253, SIGKILL) = 0
380 * <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
382 * 10252 died after we retrieved syscall exit data,
383 * but before we tried to restart it. Log looks ugly.
385 if (current_tcp && current_tcp->curcol != 0) {
386 tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
392 perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
397 set_cloexec_flag(int fd)
401 flags = fcntl(fd, F_GETFD);
403 /* Can happen only if fd is bad.
404 * Should never happen: if it does, we have a bug
405 * in the caller. Therefore we just abort
406 * instead of propagating the error.
408 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
411 newflags = flags | FD_CLOEXEC;
412 if (flags == newflags)
415 fcntl(fd, F_SETFD, newflags); /* never fails */
418 static void kill_save_errno(pid_t pid, int sig)
420 int saved_errno = errno;
422 (void) kill(pid, sig);
427 * When strace is setuid executable, we have to swap uids
428 * before and after filesystem and process management operations.
433 int euid = geteuid(), uid = getuid();
435 if (euid != uid && setreuid(euid, uid) < 0) {
436 perror_msg_and_die("setreuid");
441 # define fopen_for_output fopen64
443 # define fopen_for_output fopen
447 strace_fopen(const char *path)
452 fp = fopen_for_output(path, "w");
454 perror_msg_and_die("Can't fopen '%s'", path);
456 set_cloexec_flag(fileno(fp));
460 static int popen_pid = 0;
463 # define _PATH_BSHELL "/bin/sh"
467 * We cannot use standard popen(3) here because we have to distinguish
468 * popen child process from other processes we trace, and standard popen(3)
469 * does not export its child's pid.
472 strace_popen(const char *command)
479 perror_msg_and_die("pipe");
481 set_cloexec_flag(fds[1]); /* never fails */
485 perror_msg_and_die("vfork");
487 if (popen_pid == 0) {
492 perror_msg_and_die("dup2");
495 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
496 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
502 fp = fdopen(fds[1], "w");
509 tprintf(const char *fmt, ...)
515 int n = strace_vfprintf(current_tcp->outf, fmt, args);
517 if (current_tcp->outf != stderr)
518 perror(outfname == NULL
519 ? "<writing to pipe>" : outfname);
521 current_tcp->curcol += n;
527 tprints(const char *str)
530 int n = fputs_unlocked(str, current_tcp->outf);
532 current_tcp->curcol += strlen(str);
535 if (current_tcp->outf != stderr)
536 perror(!outfname ? "<writing to pipe>" : outfname);
544 current_tcp->curcol = 0;
545 fflush(current_tcp->outf);
548 printing_tcp->curcol = 0;
554 printleader(struct tcb *tcp)
556 /* If -ff, "previous tcb we printed" is always the same as current,
557 * because we have per-tcb output files.
563 current_tcp = printing_tcp;
564 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
566 * case 1: we have a shared log (i.e. not -ff), and last line
567 * wasn't finished (same or different tcb, doesn't matter).
568 * case 2: split log, we are the same tcb, but our last line
569 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
571 tprints(" <unfinished ...>\n");
572 printing_tcp->curcol = 0;
578 current_tcp->curcol = 0;
581 tprintf("%-5d ", tcp->pid);
582 else if (nprocs > 1 && !outfname)
583 tprintf("[pid %5u] ", tcp->pid);
586 char str[sizeof("HH:MM:SS")];
587 struct timeval tv, dtv;
588 static struct timeval otv;
590 gettimeofday(&tv, NULL);
594 tv_sub(&dtv, &tv, &otv);
595 tprintf("%6ld.%06ld ",
596 (long) dtv.tv_sec, (long) dtv.tv_usec);
599 else if (tflag > 2) {
600 tprintf("%ld.%06ld ",
601 (long) tv.tv_sec, (long) tv.tv_usec);
604 time_t local = tv.tv_sec;
605 strftime(str, sizeof(str), "%T", localtime(&local));
607 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
619 if (current_tcp->curcol < acolumn)
620 tprints(acolumn_spaces + current_tcp->curcol);
623 /* Should be only called directly *after successful attach* to a tracee.
624 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
625 * may create bogus empty FILE.<nonexistant_pid>, and then die.
628 newoutf(struct tcb *tcp)
630 tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
631 if (followfork >= 2) {
632 char name[520 + sizeof(int) * 3];
633 sprintf(name, "%.512s.%u", outfname, tcp->pid);
634 tcp->outf = strace_fopen(name);
641 /* Allocate some more TCBs and expand the table.
642 We don't want to relocate the TCBs because our
643 callers have pointers and it would be a pain.
644 So tcbtab is a table of pointers. Since we never
645 free the TCBs, we allocate a single chunk of many. */
647 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
648 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
649 if (!newtab || !newtcbs)
653 while (i < tcbtabsize)
654 tcbtab[i++] = newtcbs++;
663 if (nprocs == tcbtabsize)
666 for (i = 0; i < tcbtabsize; i++) {
668 if ((tcp->flags & TCB_INUSE) == 0) {
669 memset(tcp, 0, sizeof(*tcp));
671 tcp->flags = TCB_INUSE;
672 #if SUPPORTED_PERSONALITIES > 1
673 tcp->currpers = current_personality;
677 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
681 error_msg_and_die("bug in alloctcb");
685 droptcb(struct tcb *tcp)
692 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
695 if (followfork >= 2) {
696 if (tcp->curcol != 0)
697 fprintf(tcp->outf, " <detached ...>\n");
700 if (printing_tcp == tcp && tcp->curcol != 0)
701 fprintf(tcp->outf, " <detached ...>\n");
706 if (current_tcp == tcp)
708 if (printing_tcp == tcp)
711 memset(tcp, 0, sizeof(*tcp));
714 /* detach traced process; continue with sig
715 * Never call DETACH twice on the same process as both unattached and
716 * attached-unstopped processes give the same ESRCH. For unattached process we
717 * would SIGSTOP it and wait for its SIGSTOP notification forever.
720 detach(struct tcb *tcp)
723 int status, sigstop_expected;
725 if (tcp->flags & TCB_BPTSET)
729 * Linux wrongly insists the child be stopped
730 * before detaching. Arghh. We go through hoops
731 * to make a clean break of things.
735 #define PTRACE_DETACH PTRACE_SUNDETACH
739 sigstop_expected = 0;
740 if (tcp->flags & TCB_ATTACHED) {
742 * We attached but possibly didn't see the expected SIGSTOP.
743 * We must catch exactly one as otherwise the detached process
744 * would be left stopped (process state T).
746 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
747 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
749 /* On a clear day, you can see forever. */
751 else if (errno != ESRCH) {
752 /* Shouldn't happen. */
753 perror("detach: ptrace(PTRACE_DETACH, ...)");
755 else if (my_tkill(tcp->pid, 0) < 0) {
757 perror("detach: checking sanity");
759 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
761 perror("detach: stopping child");
764 sigstop_expected = 1;
767 if (sigstop_expected) {
770 if (waitpid(tcp->pid, &status, __WALL) < 0) {
771 if (errno == ECHILD) /* Already gone. */
773 if (errno != EINVAL) {
774 perror("detach: waiting");
778 /* No __WALL here. */
779 if (waitpid(tcp->pid, &status, 0) < 0) {
780 if (errno != ECHILD) {
781 perror("detach: waiting");
785 /* If no processes, try clones. */
786 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
788 perror("detach: waiting");
791 #endif /* __WCLONE */
796 if (!WIFSTOPPED(status)) {
797 /* Au revoir, mon ami. */
800 if (WSTOPSIG(status) == SIGSTOP) {
801 ptrace_restart(PTRACE_DETACH, tcp, 0);
804 error = ptrace_restart(PTRACE_CONT, tcp,
805 WSTOPSIG(status) == syscall_trap_sig ? 0
812 if (!qflag && (tcp->flags & TCB_ATTACHED))
813 fprintf(stderr, "Process %u detached\n", tcp->pid);
821 process_opt_p_list(char *opt)
825 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
826 * pidof uses space as delim, pgrep uses newline. :(
829 char *delim = opt + strcspn(opt, ", \n\t");
833 pid = string_to_uint(opt);
835 error_msg_and_die("Invalid process id: '%s'", opt);
837 if (pid == strace_tracer_pid) {
838 error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
855 * Block user interruptions as we would leave the traced
856 * process stopped (process state T) if we would terminate in
857 * between PTRACE_ATTACH and wait4() on SIGSTOP.
858 * We rely on cleanup() from this point on.
861 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
863 if (daemonized_tracer) {
866 perror_msg_and_die("fork");
868 if (pid) { /* parent */
870 * Wait for grandchild to attach to straced process
871 * (grandparent). Grandchild SIGKILLs us after it attached.
872 * Grandparent's wait() is unblocked by our death,
873 * it proceeds to exec the straced program.
876 _exit(0); /* paranoia */
879 /* We will be the tracer process. Remember our new pid: */
880 strace_tracer_pid = getpid();
883 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
886 if (!(tcp->flags & TCB_INUSE))
889 /* Is this a process we should attach to, but not yet attached? */
890 if (tcp->flags & TCB_ATTACHED)
891 continue; /* no, we already attached it */
893 if (followfork && !daemonized_tracer) {
894 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
897 sprintf(procdir, "/proc/%d/task", tcp->pid);
898 dir = opendir(procdir);
900 unsigned int ntid = 0, nerr = 0;
903 while ((de = readdir(dir)) != NULL) {
907 if (de->d_fileno == 0)
909 /* we trust /proc filesystem */
910 tid = atoi(de->d_name);
914 if (ptrace_attach_or_seize(tid) < 0) {
917 fprintf(stderr, "attach to pid %d failed\n", tid);
921 fprintf(stderr, "attach to pid %d succeeded\n", tid);
924 cur_tcp = alloctcb(tid);
925 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
930 sigprocmask(SIG_SETMASK, &empty_set, NULL);
933 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
937 perror("attach: ptrace(PTRACE_ATTACH, ...)");
942 fprintf(stderr, ntid > 1
943 ? "Process %u attached with %u threads\n"
944 : "Process %u attached\n",
947 if (!(tcp->flags & TCB_ATTACHED)) {
948 /* -p PID, we failed to attach to PID itself
949 * but did attach to some of its sibling threads.
955 } /* if (opendir worked) */
957 if (ptrace_attach_or_seize(tcp->pid) < 0) {
958 perror("attach: ptrace(PTRACE_ATTACH, ...)");
962 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
965 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
967 if (daemonized_tracer) {
969 * Make parent go away.
970 * Also makes grandparent's wait() unblock.
972 kill(getppid(), SIGKILL);
977 "Process %u attached\n",
979 } /* for each tcbtab[] */
983 sigprocmask(SIG_SETMASK, &empty_set, NULL);
987 startup_child(char **argv)
990 const char *filename;
991 char pathname[MAXPATHLEN];
996 if (strchr(filename, '/')) {
997 if (strlen(filename) > sizeof pathname - 1) {
998 errno = ENAMETOOLONG;
999 perror_msg_and_die("exec");
1001 strcpy(pathname, filename);
1003 #ifdef USE_DEBUGGING_EXEC
1005 * Debuggers customarily check the current directory
1006 * first regardless of the path but doing that gives
1007 * security geeks a panic attack.
1009 else if (stat(filename, &statbuf) == 0)
1010 strcpy(pathname, filename);
1011 #endif /* USE_DEBUGGING_EXEC */
1016 for (path = getenv("PATH"); path && *path; path += m) {
1017 const char *colon = strchr(path, ':');
1023 m = n = strlen(path);
1025 if (!getcwd(pathname, MAXPATHLEN))
1027 len = strlen(pathname);
1029 else if (n > sizeof pathname - 1)
1032 strncpy(pathname, path, n);
1035 if (len && pathname[len - 1] != '/')
1036 pathname[len++] = '/';
1037 strcpy(pathname + len, filename);
1038 if (stat(pathname, &statbuf) == 0 &&
1039 /* Accept only regular files
1040 with some execute bits set.
1041 XXX not perfect, might still fail */
1042 S_ISREG(statbuf.st_mode) &&
1043 (statbuf.st_mode & 0111))
1047 if (stat(pathname, &statbuf) < 0) {
1048 perror_msg_and_die("Can't stat '%s'", filename);
1050 strace_child = pid = fork();
1052 perror_msg_and_die("fork");
1054 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1055 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
1058 if (shared_log != stderr)
1059 close(fileno(shared_log));
1060 if (!daemonized_tracer && !use_seize) {
1061 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
1062 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
1066 if (username != NULL) {
1067 uid_t run_euid = run_uid;
1068 gid_t run_egid = run_gid;
1070 if (statbuf.st_mode & S_ISUID)
1071 run_euid = statbuf.st_uid;
1072 if (statbuf.st_mode & S_ISGID)
1073 run_egid = statbuf.st_gid;
1075 * It is important to set groups before we
1076 * lose privileges on setuid.
1078 if (initgroups(username, run_gid) < 0) {
1079 perror_msg_and_die("initgroups");
1081 if (setregid(run_gid, run_egid) < 0) {
1082 perror_msg_and_die("setregid");
1084 if (setreuid(run_uid, run_euid) < 0) {
1085 perror_msg_and_die("setreuid");
1088 else if (geteuid() != 0)
1089 if (setreuid(run_uid, run_uid) < 0) {
1090 perror_msg_and_die("setreuid");
1093 if (!daemonized_tracer) {
1095 * Induce a ptrace stop. Tracer (our parent)
1096 * will resume us with PTRACE_SYSCALL and display
1097 * the immediately following execve syscall.
1098 * Can't do this on NOMMU systems, we are after
1099 * vfork: parent is blocked, stopping would deadlock.
1101 if (!strace_vforked)
1105 /* we depend on SIGCHLD set to SIG_DFL by init code */
1106 /* if it happens to be SIG_IGN'ed, wait won't block */
1111 execv(pathname, argv);
1112 perror_msg_and_die("exec");
1115 /* We are the tracer */
1117 if (!daemonized_tracer) {
1119 /* child did PTRACE_TRACEME, nothing to do in parent */
1121 if (!strace_vforked) {
1122 /* Wait until child stopped itself */
1124 while (waitpid(pid, &status, WSTOPPED) < 0) {
1127 perror_msg_and_die("waitpid");
1129 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
1130 kill_save_errno(pid, SIGKILL);
1131 perror_msg_and_die("Unexpected wait status %x", status);
1134 /* Else: vforked case, we have no way to sync.
1135 * Just attach to it as soon as possible.
1136 * This means that we may miss a few first syscalls...
1139 if (ptrace_attach_or_seize(pid)) {
1140 kill_save_errno(pid, SIGKILL);
1141 perror_msg_and_die("Can't attach to %d", pid);
1143 if (!strace_vforked)
1146 tcp = alloctcb(pid);
1147 if (!strace_vforked)
1148 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
1150 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
1154 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1155 strace_tracer_pid = getpid();
1156 /* The tracee is our parent: */
1159 /* attaching will be done later, by startup_attach */
1160 /* note: we don't do newoutf(tcp) here either! */
1165 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
1166 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
1167 * and then see which options are supported by the kernel.
1170 test_ptrace_setoptions_followfork(void)
1172 int pid, expected_grandchild = 0, found_grandchild = 0;
1173 const unsigned int test_options = PTRACE_O_TRACECLONE |
1174 PTRACE_O_TRACEFORK |
1175 PTRACE_O_TRACEVFORK;
1179 perror_msg_and_die("fork");
1182 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1183 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1185 kill_save_errno(pid, SIGSTOP);
1187 perror_msg_and_die("fork");
1192 int status, tracee_pid;
1195 tracee_pid = wait(&status);
1196 if (tracee_pid <= 0) {
1199 if (errno == ECHILD)
1201 kill_save_errno(pid, SIGKILL);
1202 perror_msg_and_die("%s: unexpected wait result %d",
1203 __func__, tracee_pid);
1205 if (WIFEXITED(status)) {
1206 if (WEXITSTATUS(status)) {
1207 if (tracee_pid != pid)
1208 kill_save_errno(pid, SIGKILL);
1209 error_msg_and_die("%s: unexpected exit status %u",
1210 __func__, WEXITSTATUS(status));
1214 if (WIFSIGNALED(status)) {
1215 if (tracee_pid != pid)
1216 kill_save_errno(pid, SIGKILL);
1217 error_msg_and_die("%s: unexpected signal %u",
1218 __func__, WTERMSIG(status));
1220 if (!WIFSTOPPED(status)) {
1221 if (tracee_pid != pid)
1222 kill_save_errno(tracee_pid, SIGKILL);
1223 kill_save_errno(pid, SIGKILL);
1224 error_msg_and_die("%s: unexpected wait status %x",
1227 if (tracee_pid != pid) {
1228 found_grandchild = tracee_pid;
1229 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1230 kill_save_errno(tracee_pid, SIGKILL);
1231 kill_save_errno(pid, SIGKILL);
1232 perror_msg_and_die("PTRACE_CONT doesn't work");
1236 switch (WSTOPSIG(status)) {
1238 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1239 && errno != EINVAL && errno != EIO)
1240 perror_msg("PTRACE_SETOPTIONS");
1243 if (status >> 16 == PTRACE_EVENT_FORK) {
1246 if (ptrace(PTRACE_GETEVENTMSG, pid,
1247 NULL, (long) &msg) == 0)
1248 expected_grandchild = msg;
1252 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1253 kill_save_errno(pid, SIGKILL);
1254 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1257 if (expected_grandchild && expected_grandchild == found_grandchild) {
1258 ptrace_setoptions |= test_options;
1260 fprintf(stderr, "ptrace_setoptions = %#x\n",
1264 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1265 "giving up using this feature.");
1269 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1270 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1271 * and then see whether it will stop with (SIGTRAP | 0x80).
1273 * Use of this option enables correct handling of user-generated SIGTRAPs,
1274 * and SIGTRAPs generated by special instructions such as int3 on x86:
1275 * _start: .globl _start
1280 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1283 test_ptrace_setoptions_for_all(void)
1285 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1290 /* this fork test doesn't work on no-mmu systems */
1296 perror_msg_and_die("fork");
1300 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1301 /* Note: exits with exitcode 1 */
1302 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1305 _exit(0); /* parent should see entry into this syscall */
1309 int status, tracee_pid;
1312 tracee_pid = wait(&status);
1313 if (tracee_pid <= 0) {
1316 kill_save_errno(pid, SIGKILL);
1317 perror_msg_and_die("%s: unexpected wait result %d",
1318 __func__, tracee_pid);
1320 if (WIFEXITED(status)) {
1321 if (WEXITSTATUS(status) == 0)
1323 error_msg_and_die("%s: unexpected exit status %u",
1324 __func__, WEXITSTATUS(status));
1326 if (WIFSIGNALED(status)) {
1327 error_msg_and_die("%s: unexpected signal %u",
1328 __func__, WTERMSIG(status));
1330 if (!WIFSTOPPED(status)) {
1332 error_msg_and_die("%s: unexpected wait status %x",
1335 if (WSTOPSIG(status) == SIGSTOP) {
1337 * We don't check "options aren't accepted" error.
1338 * If it happens, we'll never get (SIGTRAP | 0x80),
1339 * and thus will decide to not use the option.
1340 * IOW: the outcome of the test will be correct.
1342 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1343 && errno != EINVAL && errno != EIO)
1344 perror_msg("PTRACE_SETOPTIONS");
1346 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1349 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1350 kill_save_errno(pid, SIGKILL);
1351 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1356 syscall_trap_sig = (SIGTRAP | 0x80);
1357 ptrace_setoptions |= test_options;
1359 fprintf(stderr, "ptrace_setoptions = %#x\n",
1364 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1365 "giving up using this feature.");
1370 test_ptrace_seize(void)
1376 perror_msg_and_die("fork");
1383 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1384 * attaching tracee continues to run unless a trap condition occurs.
1385 * PTRACE_SEIZE doesn't affect signal or group stop state.
1387 if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
1388 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1389 } else if (debug_flag) {
1390 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1396 int status, tracee_pid;
1399 tracee_pid = waitpid(pid, &status, 0);
1400 if (tracee_pid <= 0) {
1403 perror_msg_and_die("%s: unexpected wait result %d",
1404 __func__, tracee_pid);
1406 if (WIFSIGNALED(status)) {
1409 error_msg_and_die("%s: unexpected wait status %x",
1413 # else /* !USE_SEIZE */
1414 # define test_ptrace_seize() ((void)0)
1418 get_os_release(void)
1424 perror_msg_and_die("uname");
1425 /* u.release has this form: "3.2.9[-some-garbage]" */
1429 if (!(*p >= '0' && *p <= '9'))
1430 error_msg_and_die("Bad OS release string: '%s'", u.release);
1431 /* Note: this open-codes KERNEL_VERSION(): */
1432 rel = (rel << 8) | atoi(p);
1433 if (rel >= KERNEL_VERSION(1,0,0))
1435 while (*p >= '0' && *p <= '9')
1438 if (rel >= KERNEL_VERSION(0,1,0)) {
1439 /* "X.Y-something" means "X.Y.0" */
1443 error_msg_and_die("Bad OS release string: '%s'", u.release);
1451 * Initialization part of main() was eating much stack (~0.5k),
1452 * which was unused after init.
1453 * We can reuse it if we move init code into a separate function.
1455 * Don't want main() to inline us and defeat the reason
1456 * we have a separate function.
1458 static void __attribute__ ((noinline))
1459 init(int argc, char *argv[])
1464 struct sigaction sa;
1466 progname = argv[0] ? argv[0] : "strace";
1468 /* Make sure SIGCHLD has the default action so that waitpid
1469 definitely works without losing track of children. The user
1470 should not have given us a bogus state to inherit, but he might
1471 have. Arguably we should detect SIG_IGN here and pass it on
1472 to children, but probably noone really needs that. */
1473 signal(SIGCHLD, SIG_DFL);
1475 strace_tracer_pid = getpid();
1477 os_release = get_os_release();
1479 /* Allocate the initial tcbtab. */
1480 tcbtabsize = argc; /* Surely enough for all -p args. */
1481 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1483 die_out_of_memory();
1484 tcp = calloc(tcbtabsize, sizeof(*tcp));
1486 die_out_of_memory();
1487 for (c = 0; c < tcbtabsize; c++)
1490 shared_log = stderr;
1491 set_sortby(DEFAULT_SORTBY);
1492 set_personality(DEFAULT_PERSONALITY);
1493 qualify("trace=all");
1494 qualify("abbrev=all");
1495 qualify("verbose=all");
1496 qualify("signal=all");
1497 while ((c = getopt(argc, argv,
1498 "+bcCdfFhiqrtTvVxyz"
1500 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1503 detach_on_execve = 1;
1506 if (cflag == CFLAG_BOTH) {
1507 error_msg_and_die("-c and -C are mutually exclusive");
1509 cflag = CFLAG_ONLY_STATS;
1512 if (cflag == CFLAG_ONLY_STATS) {
1513 error_msg_and_die("-c and -C are mutually exclusive");
1521 daemonized_tracer = 1;
1540 /* fall through to tflag++ */
1554 qualify("abbrev=none");
1557 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1561 not_failing_only = 1;
1564 acolumn = string_to_uint(optarg);
1566 error_opt_arg(c, optarg);
1572 outfname = strdup(optarg);
1575 i = string_to_uint(optarg);
1577 error_opt_arg(c, optarg);
1581 process_opt_p_list(optarg);
1585 if (pathtrace_select(optarg)) {
1586 error_msg_and_die("Failed to select path '%s'", optarg);
1590 i = string_to_uint(optarg);
1592 error_opt_arg(c, optarg);
1599 username = strdup(optarg);
1602 if (putenv(optarg) < 0)
1603 die_out_of_memory();
1606 opt_intr = string_to_uint(optarg);
1607 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1608 error_opt_arg(c, optarg);
1616 /* argc -= optind; - no need, argc is not used below */
1618 acolumn_spaces = malloc(acolumn + 1);
1619 if (!acolumn_spaces)
1620 die_out_of_memory();
1621 memset(acolumn_spaces, ' ', acolumn);
1622 acolumn_spaces[acolumn] = '\0';
1624 /* Must have PROG [ARGS], or -p PID. Not both. */
1625 if (!argv[0] == !nprocs)
1628 if (nprocs != 0 && daemonized_tracer) {
1629 error_msg_and_die("-D and -p are mutually exclusive");
1635 if (followfork >= 2 && cflag) {
1636 error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
1639 /* See if they want to run as another user. */
1640 if (username != NULL) {
1641 struct passwd *pent;
1643 if (getuid() != 0 || geteuid() != 0) {
1644 error_msg_and_die("You must be root to use the -u option");
1646 pent = getpwnam(username);
1648 error_msg_and_die("Cannot find user '%s'", username);
1650 run_uid = pent->pw_uid;
1651 run_gid = pent->pw_gid;
1659 test_ptrace_setoptions_followfork();
1660 test_ptrace_setoptions_for_all();
1661 test_ptrace_seize();
1663 /* Check if they want to redirect the output. */
1665 /* See if they want to pipe the output. */
1666 if (outfname[0] == '|' || outfname[0] == '!') {
1668 * We can't do the <outfname>.PID funny business
1669 * when using popen, so prohibit it.
1671 if (followfork >= 2)
1672 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1673 shared_log = strace_popen(outfname + 1);
1675 else if (followfork < 2)
1676 shared_log = strace_fopen(outfname);
1678 /* -ff without -o FILE is the same as single -f */
1679 if (followfork >= 2)
1683 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1684 char *buf = malloc(BUFSIZ);
1686 die_out_of_memory();
1687 setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
1689 if (outfname && argv[0]) {
1691 opt_intr = INTR_NEVER;
1695 opt_intr = INTR_WHILE_WAIT;
1697 /* argv[0] -pPID -oFILE Default interactive setting
1698 * yes 0 0 INTR_WHILE_WAIT
1699 * no 1 0 INTR_WHILE_WAIT
1700 * yes 0 1 INTR_NEVER
1701 * no 1 1 INTR_WHILE_WAIT
1704 /* STARTUP_CHILD must be called before the signal handlers get
1705 installed below as they are inherited into the spawned process.
1706 Also we do not need to be protected by them as during interruption
1707 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1709 skip_startup_execve = 1;
1710 startup_child(argv);
1713 sigemptyset(&empty_set);
1714 sigemptyset(&blocked_set);
1715 sa.sa_handler = SIG_IGN;
1716 sigemptyset(&sa.sa_mask);
1718 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1719 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1720 if (opt_intr != INTR_ANYWHERE) {
1721 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1722 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1724 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1725 * fatal signals are blocked while syscall stop is processed,
1726 * and acted on in between, when waiting for new syscall stops.
1727 * In non-interactive mode, signals are ignored.
1729 if (opt_intr == INTR_WHILE_WAIT) {
1730 sigaddset(&blocked_set, SIGHUP);
1731 sigaddset(&blocked_set, SIGINT);
1732 sigaddset(&blocked_set, SIGQUIT);
1733 sigaddset(&blocked_set, SIGPIPE);
1734 sigaddset(&blocked_set, SIGTERM);
1735 sa.sa_handler = interrupt;
1737 /* SIG_IGN, or set handler for these */
1738 sigaction(SIGHUP, &sa, NULL);
1739 sigaction(SIGINT, &sa, NULL);
1740 sigaction(SIGQUIT, &sa, NULL);
1741 sigaction(SIGPIPE, &sa, NULL);
1742 sigaction(SIGTERM, &sa, NULL);
1744 if (nprocs != 0 || daemonized_tracer)
1747 /* Do we want pids printed in our -o OUTFILE?
1748 * -ff: no (every pid has its own file); or
1749 * -f: yes (there can be more pids in the future); or
1750 * -p PID1,PID2: yes (there are already more than one pid)
1752 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1763 for (i = 0; i < tcbtabsize; i++) {
1764 struct tcb *tcp = tcbtab[i];
1765 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1779 /* 'interrupted' is a volatile object, fetch it only once */
1780 fatal_sig = interrupted;
1782 fatal_sig = SIGTERM;
1784 for (i = 0; i < tcbtabsize; i++) {
1786 if (!(tcp->flags & TCB_INUSE))
1790 "cleanup: looking at pid %u\n", tcp->pid);
1791 if (tcp->flags & TCB_STRACE_CHILD) {
1792 kill(tcp->pid, SIGCONT);
1793 kill(tcp->pid, fatal_sig);
1798 call_summary(shared_log);
1811 struct rusage *rup = cflag ? &ru : NULL;
1813 static int wait4_options = __WALL;
1816 while (nprocs != 0) {
1827 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1829 pid = wait4(-1, &status, wait4_options, rup);
1830 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1831 /* this kernel does not support __WALL */
1832 wait4_options &= ~__WALL;
1833 pid = wait4(-1, &status, wait4_options, rup);
1835 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1836 /* most likely a "cloned" process */
1837 pid = wait4(-1, &status, __WCLONE, rup);
1839 perror_msg("wait4(__WCLONE) failed");
1843 pid = wait4(-1, &status, 0, rup);
1844 # endif /* __WALL */
1847 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1850 switch (wait_errno) {
1855 * We would like to verify this case
1856 * but sometimes a race in Solbourne's
1857 * version of SunOS sometimes reports
1858 * ECHILD before sending us SIGCHILD.
1867 if (pid == popen_pid) {
1868 if (WIFEXITED(status) || WIFSIGNALED(status))
1873 event = ((unsigned)status >> 16);
1875 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1876 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1878 if (WIFSIGNALED(status))
1880 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1881 WCOREDUMP(status) ? "core," : "",
1882 signame(WTERMSIG(status)));
1884 sprintf(buf, "WIFSIGNALED,sig=%s",
1885 signame(WTERMSIG(status)));
1887 if (WIFEXITED(status))
1888 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1889 if (WIFSTOPPED(status))
1890 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1892 if (WIFCONTINUED(status))
1893 strcpy(buf, "WIFCONTINUED");
1897 static const char *const event_names[] = {
1898 [PTRACE_EVENT_CLONE] = "CLONE",
1899 [PTRACE_EVENT_FORK] = "FORK",
1900 [PTRACE_EVENT_VFORK] = "VFORK",
1901 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1902 [PTRACE_EVENT_EXEC] = "EXEC",
1903 [PTRACE_EVENT_EXIT] = "EXIT",
1906 if (event < ARRAY_SIZE(event_names))
1907 e = event_names[event];
1909 sprintf(buf, "?? (%u)", event);
1912 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1914 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1917 /* Look up 'pid' in our table. */
1922 tcp = alloctcb(pid);
1923 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1926 fprintf(stderr, "Process %d attached\n",
1929 /* This can happen if a clone call used
1930 CLONE_PTRACE itself. */
1931 if (WIFSTOPPED(status))
1932 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1933 error_msg_and_die("Unknown pid: %u", pid);
1937 /* Under Linux, execve changes pid to thread leader's pid,
1938 * and we see this changed pid on EVENT_EXEC and later,
1939 * execve sysexit. Leader "disappears" without exit
1940 * notification. Let user know that, drop leader's tcb,
1941 * and fix up pid in execve thread's tcb.
1942 * Effectively, execve thread's tcb replaces leader's tcb.
1944 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1945 * on exit syscall) in multithreaded programs exactly
1946 * in order to handle this case.
1948 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1949 * On 2.6 and earlier, it can return garbage.
1951 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
1953 struct tcb *execve_thread;
1956 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1957 goto dont_switch_tcbs;
1958 if (old_pid <= 0 || old_pid == pid)
1959 goto dont_switch_tcbs;
1960 execve_thread = pid2tcb(old_pid);
1961 /* It should be !NULL, but I feel paranoid */
1963 goto dont_switch_tcbs;
1965 if (execve_thread->curcol != 0) {
1967 * One case we are here is -ff:
1968 * try "strace -oLOG -ff test/threaded_execve"
1970 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1971 /*execve_thread->curcol = 0; - no need, see code below */
1973 /* Swap output FILEs (needed for -ff) */
1974 fp = execve_thread->outf;
1975 execve_thread->outf = tcp->outf;
1977 /* And their column positions */
1978 execve_thread->curcol = tcp->curcol;
1980 /* Drop leader, but close execve'd thread outfile (if -ff) */
1982 /* Switch to the thread, reusing leader's outfile and pid */
1983 tcp = execve_thread;
1985 if (cflag != CFLAG_ONLY_STATS) {
1987 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1989 tcp->flags |= TCB_REPRINT;
1994 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1995 if (!skip_startup_execve)
1997 /* This was initial execve for "strace PROG". Skip. */
1998 skip_startup_execve = 0;
2001 /* Set current output file */
2005 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2006 tcp->stime = ru.ru_stime;
2009 if (WIFSIGNALED(status)) {
2010 if (pid == strace_child)
2011 exit_code = 0x100 | WTERMSIG(status);
2012 if (cflag != CFLAG_ONLY_STATS
2013 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2016 tprintf("+++ killed by %s %s+++\n",
2017 signame(WTERMSIG(status)),
2018 WCOREDUMP(status) ? "(core dumped) " : "");
2020 tprintf("+++ killed by %s +++\n",
2021 signame(WTERMSIG(status)));
2028 if (WIFEXITED(status)) {
2029 if (pid == strace_child)
2030 exit_code = WEXITSTATUS(status);
2031 if (cflag != CFLAG_ONLY_STATS) {
2033 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
2039 if (!WIFSTOPPED(status)) {
2040 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2045 /* Is this the very first time we see this tracee stopped? */
2046 if (tcp->flags & TCB_STARTUP) {
2048 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2049 tcp->flags &= ~TCB_STARTUP;
2050 if (tcp->flags & TCB_BPTSET) {
2052 * One example is a breakpoint inherited from
2053 * parent through fork().
2055 if (clearbpt(tcp) < 0) {
2062 if (ptrace_setoptions) {
2064 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2065 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2066 if (errno != ESRCH) {
2067 /* Should never happen, really */
2068 perror_msg_and_die("PTRACE_SETOPTIONS");
2074 sig = WSTOPSIG(status);
2079 if (event == PTRACE_EVENT_STOP) {
2081 * PTRACE_INTERRUPT-stop or group-stop.
2082 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2094 goto restart_tracee_with_sig_0;
2097 /* Is this post-attach SIGSTOP?
2098 * Interestingly, the process may stop
2099 * with STOPSIG equal to some other signal
2100 * than SIGSTOP if we happend to attach
2101 * just before the process takes a signal.
2103 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2105 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2106 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2107 goto restart_tracee_with_sig_0;
2110 if (sig != syscall_trap_sig) {
2113 /* Nonzero (true) if tracee is stopped by signal
2114 * (as opposed to "tracee received signal").
2115 * TODO: shouldn't we check for errno == EINVAL too?
2116 * We can get ESRCH instead, you know...
2118 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2122 if (cflag != CFLAG_ONLY_STATS
2123 && (qual_flags[sig] & QUAL_SIGNAL)) {
2124 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2128 upeek(tcp, PT_CR_IPSR, &psr);
2129 upeek(tcp, PT_CR_IIP, &pc);
2132 pc += (psr >> PSR_RI) & 0x3;
2133 # define PC_FORMAT_STR " @ %lx"
2134 # define PC_FORMAT_ARG , pc
2136 # define PC_FORMAT_STR ""
2137 # define PC_FORMAT_ARG /* nothing */
2141 tprintf("--- %s ", signame(sig));
2142 printsiginfo(&si, verbose(tcp));
2143 tprintf(PC_FORMAT_STR " ---\n"
2146 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
2153 /* It's signal-delivery-stop. Inject the signal */
2154 goto restart_tracee;
2156 /* It's group-stop */
2160 * This ends ptrace-stop, but does *not* end group-stop.
2161 * This makes stopping signals work properly on straced process
2162 * (that is, process really stops. It used to continue to run).
2164 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2170 /* We don't have PTRACE_LISTEN support... */
2172 goto restart_tracee;
2175 /* We handled quick cases, we are permitted to interrupt now. */
2179 /* This should be syscall entry or exit.
2180 * (Or it still can be that pesky post-execve SIGTRAP!)
2183 if (trace_syscall(tcp) < 0) {
2184 /* ptrace() failed in trace_syscall().
2185 * Likely a result of process disappearing mid-flight.
2186 * Observed case: exit_group() or SIGKILL terminating
2187 * all processes in thread group.
2188 * We assume that ptrace error was caused by process death.
2189 * We used to detach(tcp) here, but since we no longer
2190 * implement "detach before death" policy/hack,
2191 * we can let this process to report its death to us
2192 * normally, via WIFEXITED or WIFSIGNALED wait status.
2196 restart_tracee_with_sig_0:
2199 /* Remember current print column before continuing. */
2200 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2209 main(int argc, char *argv[])
2213 /* Run main tracing loop */
2219 if (shared_log != stderr)
2222 while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR)
2225 if (exit_code > 0xff) {
2226 /* Avoid potential core file clobbering. */
2227 struct rlimit rlim = {0, 0};
2228 setrlimit(RLIMIT_CORE, &rlim);
2230 /* Child was killed by a signal, mimic that. */
2232 signal(exit_code, SIG_DFL);
2234 /* Paranoia - what if this signal is not fatal?
2235 Exit with 128 + signo then. */