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 setreuid(run_uid, run_uid);
1091 if (!daemonized_tracer) {
1093 * Induce a ptrace stop. Tracer (our parent)
1094 * will resume us with PTRACE_SYSCALL and display
1095 * the immediately following execve syscall.
1096 * Can't do this on NOMMU systems, we are after
1097 * vfork: parent is blocked, stopping would deadlock.
1099 if (!strace_vforked)
1103 /* we depend on SIGCHLD set to SIG_DFL by init code */
1104 /* if it happens to be SIG_IGN'ed, wait won't block */
1109 execv(pathname, argv);
1110 perror_msg_and_die("exec");
1113 /* We are the tracer */
1115 if (!daemonized_tracer) {
1117 /* child did PTRACE_TRACEME, nothing to do in parent */
1119 if (!strace_vforked) {
1120 /* Wait until child stopped itself */
1122 while (waitpid(pid, &status, WSTOPPED) < 0) {
1125 perror_msg_and_die("waitpid");
1127 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
1128 kill_save_errno(pid, SIGKILL);
1129 perror_msg_and_die("Unexpected wait status %x", status);
1132 /* Else: vforked case, we have no way to sync.
1133 * Just attach to it as soon as possible.
1134 * This means that we may miss a few first syscalls...
1137 if (ptrace_attach_or_seize(pid)) {
1138 kill_save_errno(pid, SIGKILL);
1139 perror_msg_and_die("Can't attach to %d", pid);
1141 if (!strace_vforked)
1144 tcp = alloctcb(pid);
1145 if (!strace_vforked)
1146 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
1148 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
1152 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1153 strace_tracer_pid = getpid();
1154 /* The tracee is our parent: */
1157 /* attaching will be done later, by startup_attach */
1158 /* note: we don't do newoutf(tcp) here either! */
1163 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
1164 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
1165 * and then see which options are supported by the kernel.
1168 test_ptrace_setoptions_followfork(void)
1170 int pid, expected_grandchild = 0, found_grandchild = 0;
1171 const unsigned int test_options = PTRACE_O_TRACECLONE |
1172 PTRACE_O_TRACEFORK |
1173 PTRACE_O_TRACEVFORK;
1177 perror_msg_and_die("fork");
1180 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1181 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1183 kill_save_errno(pid, SIGSTOP);
1185 perror_msg_and_die("fork");
1190 int status, tracee_pid;
1193 tracee_pid = wait(&status);
1194 if (tracee_pid <= 0) {
1197 if (errno == ECHILD)
1199 kill_save_errno(pid, SIGKILL);
1200 perror_msg_and_die("%s: unexpected wait result %d",
1201 __func__, tracee_pid);
1203 if (WIFEXITED(status)) {
1204 if (WEXITSTATUS(status)) {
1205 if (tracee_pid != pid)
1206 kill_save_errno(pid, SIGKILL);
1207 error_msg_and_die("%s: unexpected exit status %u",
1208 __func__, WEXITSTATUS(status));
1212 if (WIFSIGNALED(status)) {
1213 if (tracee_pid != pid)
1214 kill_save_errno(pid, SIGKILL);
1215 error_msg_and_die("%s: unexpected signal %u",
1216 __func__, WTERMSIG(status));
1218 if (!WIFSTOPPED(status)) {
1219 if (tracee_pid != pid)
1220 kill_save_errno(tracee_pid, SIGKILL);
1221 kill_save_errno(pid, SIGKILL);
1222 error_msg_and_die("%s: unexpected wait status %x",
1225 if (tracee_pid != pid) {
1226 found_grandchild = tracee_pid;
1227 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1228 kill_save_errno(tracee_pid, SIGKILL);
1229 kill_save_errno(pid, SIGKILL);
1230 perror_msg_and_die("PTRACE_CONT doesn't work");
1234 switch (WSTOPSIG(status)) {
1236 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1237 && errno != EINVAL && errno != EIO)
1238 perror_msg("PTRACE_SETOPTIONS");
1241 if (status >> 16 == PTRACE_EVENT_FORK) {
1244 if (ptrace(PTRACE_GETEVENTMSG, pid,
1245 NULL, (long) &msg) == 0)
1246 expected_grandchild = msg;
1250 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1251 kill_save_errno(pid, SIGKILL);
1252 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1255 if (expected_grandchild && expected_grandchild == found_grandchild) {
1256 ptrace_setoptions |= test_options;
1258 fprintf(stderr, "ptrace_setoptions = %#x\n",
1262 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1263 "giving up using this feature.");
1267 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1268 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1269 * and then see whether it will stop with (SIGTRAP | 0x80).
1271 * Use of this option enables correct handling of user-generated SIGTRAPs,
1272 * and SIGTRAPs generated by special instructions such as int3 on x86:
1273 * _start: .globl _start
1278 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1281 test_ptrace_setoptions_for_all(void)
1283 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1288 /* this fork test doesn't work on no-mmu systems */
1294 perror_msg_and_die("fork");
1298 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1299 /* Note: exits with exitcode 1 */
1300 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1303 _exit(0); /* parent should see entry into this syscall */
1307 int status, tracee_pid;
1310 tracee_pid = wait(&status);
1311 if (tracee_pid <= 0) {
1314 kill_save_errno(pid, SIGKILL);
1315 perror_msg_and_die("%s: unexpected wait result %d",
1316 __func__, tracee_pid);
1318 if (WIFEXITED(status)) {
1319 if (WEXITSTATUS(status) == 0)
1321 error_msg_and_die("%s: unexpected exit status %u",
1322 __func__, WEXITSTATUS(status));
1324 if (WIFSIGNALED(status)) {
1325 error_msg_and_die("%s: unexpected signal %u",
1326 __func__, WTERMSIG(status));
1328 if (!WIFSTOPPED(status)) {
1330 error_msg_and_die("%s: unexpected wait status %x",
1333 if (WSTOPSIG(status) == SIGSTOP) {
1335 * We don't check "options aren't accepted" error.
1336 * If it happens, we'll never get (SIGTRAP | 0x80),
1337 * and thus will decide to not use the option.
1338 * IOW: the outcome of the test will be correct.
1340 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1341 && errno != EINVAL && errno != EIO)
1342 perror_msg("PTRACE_SETOPTIONS");
1344 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1347 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1348 kill_save_errno(pid, SIGKILL);
1349 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1354 syscall_trap_sig = (SIGTRAP | 0x80);
1355 ptrace_setoptions |= test_options;
1357 fprintf(stderr, "ptrace_setoptions = %#x\n",
1362 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1363 "giving up using this feature.");
1368 test_ptrace_seize(void)
1374 perror_msg_and_die("fork");
1381 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1382 * attaching tracee continues to run unless a trap condition occurs.
1383 * PTRACE_SEIZE doesn't affect signal or group stop state.
1385 if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
1386 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1387 } else if (debug_flag) {
1388 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1394 int status, tracee_pid;
1397 tracee_pid = waitpid(pid, &status, 0);
1398 if (tracee_pid <= 0) {
1401 perror_msg_and_die("%s: unexpected wait result %d",
1402 __func__, tracee_pid);
1404 if (WIFSIGNALED(status)) {
1407 error_msg_and_die("%s: unexpected wait status %x",
1411 # else /* !USE_SEIZE */
1412 # define test_ptrace_seize() ((void)0)
1416 get_os_release(void)
1422 perror_msg_and_die("uname");
1423 /* u.release has this form: "3.2.9[-some-garbage]" */
1427 if (!(*p >= '0' && *p <= '9'))
1428 error_msg_and_die("Bad OS release string: '%s'", u.release);
1429 /* Note: this open-codes KERNEL_VERSION(): */
1430 rel = (rel << 8) | atoi(p);
1431 if (rel >= KERNEL_VERSION(1,0,0))
1433 while (*p >= '0' && *p <= '9')
1436 if (rel >= KERNEL_VERSION(0,1,0)) {
1437 /* "X.Y-something" means "X.Y.0" */
1441 error_msg_and_die("Bad OS release string: '%s'", u.release);
1449 * Initialization part of main() was eating much stack (~0.5k),
1450 * which was unused after init.
1451 * We can reuse it if we move init code into a separate function.
1453 * Don't want main() to inline us and defeat the reason
1454 * we have a separate function.
1456 static void __attribute__ ((noinline))
1457 init(int argc, char *argv[])
1462 struct sigaction sa;
1464 progname = argv[0] ? argv[0] : "strace";
1466 /* Make sure SIGCHLD has the default action so that waitpid
1467 definitely works without losing track of children. The user
1468 should not have given us a bogus state to inherit, but he might
1469 have. Arguably we should detect SIG_IGN here and pass it on
1470 to children, but probably noone really needs that. */
1471 signal(SIGCHLD, SIG_DFL);
1473 strace_tracer_pid = getpid();
1475 os_release = get_os_release();
1477 /* Allocate the initial tcbtab. */
1478 tcbtabsize = argc; /* Surely enough for all -p args. */
1479 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1481 die_out_of_memory();
1482 tcp = calloc(tcbtabsize, sizeof(*tcp));
1484 die_out_of_memory();
1485 for (c = 0; c < tcbtabsize; c++)
1488 shared_log = stderr;
1489 set_sortby(DEFAULT_SORTBY);
1490 set_personality(DEFAULT_PERSONALITY);
1491 qualify("trace=all");
1492 qualify("abbrev=all");
1493 qualify("verbose=all");
1494 qualify("signal=all");
1495 while ((c = getopt(argc, argv,
1496 "+bcCdfFhiqrtTvVxyz"
1498 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1501 detach_on_execve = 1;
1504 if (cflag == CFLAG_BOTH) {
1505 error_msg_and_die("-c and -C are mutually exclusive");
1507 cflag = CFLAG_ONLY_STATS;
1510 if (cflag == CFLAG_ONLY_STATS) {
1511 error_msg_and_die("-c and -C are mutually exclusive");
1519 daemonized_tracer = 1;
1538 /* fall through to tflag++ */
1552 qualify("abbrev=none");
1555 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1559 not_failing_only = 1;
1562 acolumn = string_to_uint(optarg);
1564 error_opt_arg(c, optarg);
1570 outfname = strdup(optarg);
1573 i = string_to_uint(optarg);
1575 error_opt_arg(c, optarg);
1579 process_opt_p_list(optarg);
1583 if (pathtrace_select(optarg)) {
1584 error_msg_and_die("Failed to select path '%s'", optarg);
1588 i = string_to_uint(optarg);
1590 error_opt_arg(c, optarg);
1597 username = strdup(optarg);
1600 if (putenv(optarg) < 0)
1601 die_out_of_memory();
1604 opt_intr = string_to_uint(optarg);
1605 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1606 error_opt_arg(c, optarg);
1614 /* argc -= optind; - no need, argc is not used below */
1616 acolumn_spaces = malloc(acolumn + 1);
1617 if (!acolumn_spaces)
1618 die_out_of_memory();
1619 memset(acolumn_spaces, ' ', acolumn);
1620 acolumn_spaces[acolumn] = '\0';
1622 /* Must have PROG [ARGS], or -p PID. Not both. */
1623 if (!argv[0] == !nprocs)
1626 if (nprocs != 0 && daemonized_tracer) {
1627 error_msg_and_die("-D and -p are mutually exclusive");
1633 if (followfork >= 2 && cflag) {
1634 error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
1637 /* See if they want to run as another user. */
1638 if (username != NULL) {
1639 struct passwd *pent;
1641 if (getuid() != 0 || geteuid() != 0) {
1642 error_msg_and_die("You must be root to use the -u option");
1644 pent = getpwnam(username);
1646 error_msg_and_die("Cannot find user '%s'", username);
1648 run_uid = pent->pw_uid;
1649 run_gid = pent->pw_gid;
1657 test_ptrace_setoptions_followfork();
1658 test_ptrace_setoptions_for_all();
1659 test_ptrace_seize();
1661 /* Check if they want to redirect the output. */
1663 /* See if they want to pipe the output. */
1664 if (outfname[0] == '|' || outfname[0] == '!') {
1666 * We can't do the <outfname>.PID funny business
1667 * when using popen, so prohibit it.
1669 if (followfork >= 2)
1670 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1671 shared_log = strace_popen(outfname + 1);
1673 else if (followfork < 2)
1674 shared_log = strace_fopen(outfname);
1676 /* -ff without -o FILE is the same as single -f */
1677 if (followfork >= 2)
1681 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1682 char *buf = malloc(BUFSIZ);
1684 die_out_of_memory();
1685 setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
1687 if (outfname && argv[0]) {
1689 opt_intr = INTR_NEVER;
1693 opt_intr = INTR_WHILE_WAIT;
1695 /* argv[0] -pPID -oFILE Default interactive setting
1696 * yes 0 0 INTR_WHILE_WAIT
1697 * no 1 0 INTR_WHILE_WAIT
1698 * yes 0 1 INTR_NEVER
1699 * no 1 1 INTR_WHILE_WAIT
1702 /* STARTUP_CHILD must be called before the signal handlers get
1703 installed below as they are inherited into the spawned process.
1704 Also we do not need to be protected by them as during interruption
1705 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1707 skip_startup_execve = 1;
1708 startup_child(argv);
1711 sigemptyset(&empty_set);
1712 sigemptyset(&blocked_set);
1713 sa.sa_handler = SIG_IGN;
1714 sigemptyset(&sa.sa_mask);
1716 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1717 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1718 if (opt_intr != INTR_ANYWHERE) {
1719 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1720 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1722 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1723 * fatal signals are blocked while syscall stop is processed,
1724 * and acted on in between, when waiting for new syscall stops.
1725 * In non-interactive mode, signals are ignored.
1727 if (opt_intr == INTR_WHILE_WAIT) {
1728 sigaddset(&blocked_set, SIGHUP);
1729 sigaddset(&blocked_set, SIGINT);
1730 sigaddset(&blocked_set, SIGQUIT);
1731 sigaddset(&blocked_set, SIGPIPE);
1732 sigaddset(&blocked_set, SIGTERM);
1733 sa.sa_handler = interrupt;
1735 /* SIG_IGN, or set handler for these */
1736 sigaction(SIGHUP, &sa, NULL);
1737 sigaction(SIGINT, &sa, NULL);
1738 sigaction(SIGQUIT, &sa, NULL);
1739 sigaction(SIGPIPE, &sa, NULL);
1740 sigaction(SIGTERM, &sa, NULL);
1742 if (nprocs != 0 || daemonized_tracer)
1745 /* Do we want pids printed in our -o OUTFILE?
1746 * -ff: no (every pid has its own file); or
1747 * -f: yes (there can be more pids in the future); or
1748 * -p PID1,PID2: yes (there are already more than one pid)
1750 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1761 for (i = 0; i < tcbtabsize; i++) {
1762 struct tcb *tcp = tcbtab[i];
1763 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1777 /* 'interrupted' is a volatile object, fetch it only once */
1778 fatal_sig = interrupted;
1780 fatal_sig = SIGTERM;
1782 for (i = 0; i < tcbtabsize; i++) {
1784 if (!(tcp->flags & TCB_INUSE))
1788 "cleanup: looking at pid %u\n", tcp->pid);
1789 if (tcp->flags & TCB_STRACE_CHILD) {
1790 kill(tcp->pid, SIGCONT);
1791 kill(tcp->pid, fatal_sig);
1796 call_summary(shared_log);
1809 struct rusage *rup = cflag ? &ru : NULL;
1811 static int wait4_options = __WALL;
1814 while (nprocs != 0) {
1825 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1827 pid = wait4(-1, &status, wait4_options, rup);
1828 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1829 /* this kernel does not support __WALL */
1830 wait4_options &= ~__WALL;
1831 pid = wait4(-1, &status, wait4_options, rup);
1833 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1834 /* most likely a "cloned" process */
1835 pid = wait4(-1, &status, __WCLONE, rup);
1837 perror_msg("wait4(__WCLONE) failed");
1841 pid = wait4(-1, &status, 0, rup);
1842 # endif /* __WALL */
1845 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1848 switch (wait_errno) {
1853 * We would like to verify this case
1854 * but sometimes a race in Solbourne's
1855 * version of SunOS sometimes reports
1856 * ECHILD before sending us SIGCHILD.
1865 if (pid == popen_pid) {
1866 if (WIFEXITED(status) || WIFSIGNALED(status))
1871 event = ((unsigned)status >> 16);
1873 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1874 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1876 if (WIFSIGNALED(status))
1878 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1879 WCOREDUMP(status) ? "core," : "",
1880 signame(WTERMSIG(status)));
1882 sprintf(buf, "WIFSIGNALED,sig=%s",
1883 signame(WTERMSIG(status)));
1885 if (WIFEXITED(status))
1886 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1887 if (WIFSTOPPED(status))
1888 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1890 if (WIFCONTINUED(status))
1891 strcpy(buf, "WIFCONTINUED");
1895 static const char *const event_names[] = {
1896 [PTRACE_EVENT_CLONE] = "CLONE",
1897 [PTRACE_EVENT_FORK] = "FORK",
1898 [PTRACE_EVENT_VFORK] = "VFORK",
1899 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1900 [PTRACE_EVENT_EXEC] = "EXEC",
1901 [PTRACE_EVENT_EXIT] = "EXIT",
1904 if (event < ARRAY_SIZE(event_names))
1905 e = event_names[event];
1907 sprintf(buf, "?? (%u)", event);
1910 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1912 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1915 /* Look up 'pid' in our table. */
1920 tcp = alloctcb(pid);
1921 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1924 fprintf(stderr, "Process %d attached\n",
1927 /* This can happen if a clone call used
1928 CLONE_PTRACE itself. */
1929 if (WIFSTOPPED(status))
1930 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1931 error_msg_and_die("Unknown pid: %u", pid);
1935 /* Under Linux, execve changes pid to thread leader's pid,
1936 * and we see this changed pid on EVENT_EXEC and later,
1937 * execve sysexit. Leader "disappears" without exit
1938 * notification. Let user know that, drop leader's tcb,
1939 * and fix up pid in execve thread's tcb.
1940 * Effectively, execve thread's tcb replaces leader's tcb.
1942 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1943 * on exit syscall) in multithreaded programs exactly
1944 * in order to handle this case.
1946 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1947 * On 2.6 and earlier, it can return garbage.
1949 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
1951 struct tcb *execve_thread;
1954 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1955 goto dont_switch_tcbs;
1956 if (old_pid <= 0 || old_pid == pid)
1957 goto dont_switch_tcbs;
1958 execve_thread = pid2tcb(old_pid);
1959 /* It should be !NULL, but I feel paranoid */
1961 goto dont_switch_tcbs;
1963 if (execve_thread->curcol != 0) {
1965 * One case we are here is -ff:
1966 * try "strace -oLOG -ff test/threaded_execve"
1968 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1969 /*execve_thread->curcol = 0; - no need, see code below */
1971 /* Swap output FILEs (needed for -ff) */
1972 fp = execve_thread->outf;
1973 execve_thread->outf = tcp->outf;
1975 /* And their column positions */
1976 execve_thread->curcol = tcp->curcol;
1978 /* Drop leader, but close execve'd thread outfile (if -ff) */
1980 /* Switch to the thread, reusing leader's outfile and pid */
1981 tcp = execve_thread;
1983 if (cflag != CFLAG_ONLY_STATS) {
1985 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1987 tcp->flags |= TCB_REPRINT;
1992 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1993 if (!skip_startup_execve)
1995 /* This was initial execve for "strace PROG". Skip. */
1996 skip_startup_execve = 0;
1999 /* Set current output file */
2003 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2004 tcp->stime = ru.ru_stime;
2007 if (WIFSIGNALED(status)) {
2008 if (pid == strace_child)
2009 exit_code = 0x100 | WTERMSIG(status);
2010 if (cflag != CFLAG_ONLY_STATS
2011 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2014 tprintf("+++ killed by %s %s+++\n",
2015 signame(WTERMSIG(status)),
2016 WCOREDUMP(status) ? "(core dumped) " : "");
2018 tprintf("+++ killed by %s +++\n",
2019 signame(WTERMSIG(status)));
2026 if (WIFEXITED(status)) {
2027 if (pid == strace_child)
2028 exit_code = WEXITSTATUS(status);
2029 if (cflag != CFLAG_ONLY_STATS) {
2031 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
2037 if (!WIFSTOPPED(status)) {
2038 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2043 /* Is this the very first time we see this tracee stopped? */
2044 if (tcp->flags & TCB_STARTUP) {
2046 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2047 tcp->flags &= ~TCB_STARTUP;
2048 if (tcp->flags & TCB_BPTSET) {
2050 * One example is a breakpoint inherited from
2051 * parent through fork().
2053 if (clearbpt(tcp) < 0) {
2060 if (ptrace_setoptions) {
2062 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2063 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2064 if (errno != ESRCH) {
2065 /* Should never happen, really */
2066 perror_msg_and_die("PTRACE_SETOPTIONS");
2072 sig = WSTOPSIG(status);
2077 if (event == PTRACE_EVENT_STOP) {
2079 * PTRACE_INTERRUPT-stop or group-stop.
2080 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2092 goto restart_tracee_with_sig_0;
2095 /* Is this post-attach SIGSTOP?
2096 * Interestingly, the process may stop
2097 * with STOPSIG equal to some other signal
2098 * than SIGSTOP if we happend to attach
2099 * just before the process takes a signal.
2101 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2103 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2104 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2105 goto restart_tracee_with_sig_0;
2108 if (sig != syscall_trap_sig) {
2111 /* Nonzero (true) if tracee is stopped by signal
2112 * (as opposed to "tracee received signal").
2113 * TODO: shouldn't we check for errno == EINVAL too?
2114 * We can get ESRCH instead, you know...
2116 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2120 if (cflag != CFLAG_ONLY_STATS
2121 && (qual_flags[sig] & QUAL_SIGNAL)) {
2122 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2126 upeek(tcp, PT_CR_IPSR, &psr);
2127 upeek(tcp, PT_CR_IIP, &pc);
2130 pc += (psr >> PSR_RI) & 0x3;
2131 # define PC_FORMAT_STR " @ %lx"
2132 # define PC_FORMAT_ARG , pc
2134 # define PC_FORMAT_STR ""
2135 # define PC_FORMAT_ARG /* nothing */
2139 tprintf("--- %s ", signame(sig));
2140 printsiginfo(&si, verbose(tcp));
2141 tprintf(PC_FORMAT_STR " ---\n"
2144 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
2151 /* It's signal-delivery-stop. Inject the signal */
2152 goto restart_tracee;
2154 /* It's group-stop */
2158 * This ends ptrace-stop, but does *not* end group-stop.
2159 * This makes stopping signals work properly on straced process
2160 * (that is, process really stops. It used to continue to run).
2162 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2168 /* We don't have PTRACE_LISTEN support... */
2170 goto restart_tracee;
2173 /* We handled quick cases, we are permitted to interrupt now. */
2177 /* This should be syscall entry or exit.
2178 * (Or it still can be that pesky post-execve SIGTRAP!)
2181 if (trace_syscall(tcp) < 0) {
2182 /* ptrace() failed in trace_syscall().
2183 * Likely a result of process disappearing mid-flight.
2184 * Observed case: exit_group() or SIGKILL terminating
2185 * all processes in thread group.
2186 * We assume that ptrace error was caused by process death.
2187 * We used to detach(tcp) here, but since we no longer
2188 * implement "detach before death" policy/hack,
2189 * we can let this process to report its death to us
2190 * normally, via WIFEXITED or WIFSIGNALED wait status.
2194 restart_tracee_with_sig_0:
2197 /* Remember current print column before continuing. */
2198 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2207 main(int argc, char *argv[])
2211 /* Run main tracing loop */
2217 if (exit_code > 0xff) {
2218 /* Avoid potential core file clobbering. */
2219 struct rlimit rlim = {0, 0};
2220 setrlimit(RLIMIT_CORE, &rlim);
2222 /* Child was killed by a signal, mimic that. */
2224 signal(exit_code, SIG_DFL);
2226 /* Paranoia - what if this signal is not fatal?
2227 Exit with 128 + signo then. */