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 unsigned int acolumn = DEFAULT_ACOLUMN;
135 static char *acolumn_spaces;
136 static char *outfname = NULL;
138 struct tcb *printing_tcp = NULL;
139 static unsigned int curcol;
140 static struct tcb **tcbtab;
141 static unsigned int nprocs, tcbtabsize;
142 static const char *progname;
144 static unsigned os_release; /* generated from uname()'s u.release */
146 static int detach(struct tcb *tcp);
147 static int trace(void);
148 static void cleanup(void);
149 static void interrupt(int sig);
150 static sigset_t empty_set, blocked_set;
152 #ifdef HAVE_SIG_ATOMIC_T
153 static volatile sig_atomic_t interrupted;
155 static volatile int interrupted;
158 #ifndef HAVE_STRERROR
160 #if !HAVE_DECL_SYS_ERRLIST
162 extern char *sys_errlist[];
168 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
170 if (err_no < 1 || err_no >= sys_nerr) {
171 sprintf(buf, "Unknown error %d", err_no);
174 return sys_errlist[err_no];
177 #endif /* HAVE_STERRROR */
180 usage(FILE *ofp, int exitval)
183 usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
184 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
185 [-P path] [PROG [ARGS]]\n\
186 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
188 -c -- count time, calls, and errors for each syscall and report summary\n\
189 -C -- like -c but also print regular output while processes are running\n\
190 -d -- enable debug output to stderr\n\
191 -D -- run tracer process as a detached grandchild, not as parent\n\
192 -f -- follow forks, -ff -- with output into separate files\n\
193 -F -- attempt to follow vforks (deprecated, use -f)\n\
194 -i -- print instruction pointer at time of syscall\n\
196 1: no signals are blocked\n\
197 2: fatal signals are blocked while decoding syscall (default)\n\
198 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
199 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
200 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
201 -q -- suppress messages about attaching, detaching, etc.\n\
202 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
203 -T -- print time spent in each syscall\n\
204 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
205 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
206 -y -- print paths associated with file descriptor arguments\n\
207 -h -- print help message\n\
208 -V -- print version\n\
209 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
210 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
211 options: trace, abbrev, verbose, raw, signal, read, or write\n\
212 -o file -- send trace output to FILE instead of stderr\n\
213 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
214 -p pid -- trace process with process id PID, may be repeated\n\
215 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
216 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
217 -u username -- run command as username handling setuid and/or setgid\n\
218 -E var=val -- put var=val in the environment for command\n\
219 -E var -- remove var from the environment for command\n\
220 -P path -- trace accesses to path\n\
222 /* this is broken, so don't document it
223 -z -- print only succeeding syscalls\n\
225 /* experimental, don't document it yet (option letter may change in the future!)
226 -b -- detach on successful execve\n\
228 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
232 static void die(void) __attribute__ ((noreturn));
233 static void die(void)
235 if (strace_tracer_pid == getpid()) {
242 static void verror_msg(int err_no, const char *fmt, va_list p)
248 /* We want to print entire message with single fprintf to ensure
249 * message integrity if stderr is shared with other programs.
250 * Thus we use vasprintf + single fprintf.
253 if (vasprintf(&msg, fmt, p) >= 0) {
255 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
257 fprintf(stderr, "%s: %s\n", progname, msg);
260 /* malloc in vasprintf failed, try it without malloc */
261 fprintf(stderr, "%s: ", progname);
262 vfprintf(stderr, fmt, p);
264 fprintf(stderr, ": %s\n", strerror(err_no));
268 /* We don't switch stderr to buffered, thus fprintf(stderr)
269 * always flushes its output and this is not necessary: */
270 /* fflush(stderr); */
273 void error_msg(const char *fmt, ...)
277 verror_msg(0, fmt, p);
281 void error_msg_and_die(const char *fmt, ...)
285 verror_msg(0, fmt, p);
289 void perror_msg(const char *fmt, ...)
293 verror_msg(errno, fmt, p);
297 void perror_msg_and_die(const char *fmt, ...)
301 verror_msg(errno, fmt, p);
305 void die_out_of_memory(void)
307 static bool recursed = 0;
311 error_msg_and_die("Out of memory");
314 /* Glue for systems without a MMU that cannot provide fork() */
316 # define strace_vforked 0
318 # define strace_vforked 1
319 # define fork() vfork()
324 ptrace_attach_or_seize(int pid)
328 return ptrace(PTRACE_ATTACH, pid, 0, 0);
329 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
332 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
336 # define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
340 * Used when we want to unblock stopped traced process.
341 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
342 * Returns 0 on success or if error was ESRCH
343 * (presumably process was killed while we talk to it).
344 * Otherwise prints error message and returns -1.
347 ptrace_restart(int op, struct tcb *tcp, int sig)
353 ptrace(op, tcp->pid, (void *) 0, (long) sig);
359 if (op == PTRACE_CONT)
361 if (op == PTRACE_DETACH)
364 if (op == PTRACE_LISTEN)
368 * Why curcol != 0? Otherwise sometimes we get this:
370 * 10252 kill(10253, SIGKILL) = 0
371 * <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
373 * 10252 died after we retrieved syscall exit data,
374 * but before we tried to restart it. Log looks ugly.
377 tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
383 perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
388 set_cloexec_flag(int fd)
392 flags = fcntl(fd, F_GETFD);
394 /* Can happen only if fd is bad.
395 * Should never happen: if it does, we have a bug
396 * in the caller. Therefore we just abort
397 * instead of propagating the error.
399 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
402 newflags = flags | FD_CLOEXEC;
403 if (flags == newflags)
406 fcntl(fd, F_SETFD, newflags); /* never fails */
409 static void kill_save_errno(pid_t pid, int sig)
411 int saved_errno = errno;
413 (void) kill(pid, sig);
418 * When strace is setuid executable, we have to swap uids
419 * before and after filesystem and process management operations.
424 int euid = geteuid(), uid = getuid();
426 if (euid != uid && setreuid(euid, uid) < 0) {
427 perror_msg_and_die("setreuid");
432 # define fopen_for_output fopen64
434 # define fopen_for_output fopen
438 strace_fopen(const char *path)
443 fp = fopen_for_output(path, "w");
445 perror_msg_and_die("Can't fopen '%s'", path);
447 set_cloexec_flag(fileno(fp));
451 static int popen_pid = 0;
454 # define _PATH_BSHELL "/bin/sh"
458 * We cannot use standard popen(3) here because we have to distinguish
459 * popen child process from other processes we trace, and standard popen(3)
460 * does not export its child's pid.
463 strace_popen(const char *command)
470 perror_msg_and_die("pipe");
472 set_cloexec_flag(fds[1]); /* never fails */
476 perror_msg_and_die("vfork");
478 if (popen_pid == 0) {
483 perror_msg_and_die("dup2");
486 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
487 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
493 fp = fdopen(fds[1], "w");
500 tprintf(const char *fmt, ...)
506 int n = vfprintf(outf, fmt, args);
509 perror(outfname == NULL
510 ? "<writing to pipe>" : outfname);
518 tprints(const char *str)
521 int n = fputs(str, outf);
523 curcol += strlen(str);
527 perror(outfname == NULL
528 ? "<writing to pipe>" : outfname);
539 printing_tcp->curcol = 0;
544 printleader(struct tcb *tcp)
546 /* If -ff, "previous tcb we printed" is always the same as current,
547 * because we have per-tcb output files.
553 outf = printing_tcp->outf;
554 curcol = printing_tcp->curcol;
555 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
557 * case 1: we have a shared log (i.e. not -ff), and last line
558 * wasn't finished (same or different tcb, doesn't matter).
559 * case 2: split log, we are the same tcb, but our last line
560 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
562 tprints(" <unfinished ...>\n");
563 printing_tcp->flags |= TCB_REPRINT;
564 printing_tcp->curcol = 0;
573 tprintf("%-5d ", tcp->pid);
574 else if (nprocs > 1 && !outfname)
575 tprintf("[pid %5u] ", tcp->pid);
578 char str[sizeof("HH:MM:SS")];
579 struct timeval tv, dtv;
580 static struct timeval otv;
582 gettimeofday(&tv, NULL);
586 tv_sub(&dtv, &tv, &otv);
587 tprintf("%6ld.%06ld ",
588 (long) dtv.tv_sec, (long) dtv.tv_usec);
591 else if (tflag > 2) {
592 tprintf("%ld.%06ld ",
593 (long) tv.tv_sec, (long) tv.tv_usec);
596 time_t local = tv.tv_sec;
597 strftime(str, sizeof(str), "%T", localtime(&local));
599 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
611 if (curcol < acolumn)
612 tprints(acolumn_spaces + curcol);
615 /* Should be only called directly *after successful attach* to a tracee.
616 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
617 * may create bogus empty FILE.<nonexistant_pid>, and then die.
620 newoutf(struct tcb *tcp)
622 tcp->outf = outf; /* if not -ff mode, the same file is for all */
623 if (followfork >= 2) {
624 char name[520 + sizeof(int) * 3];
625 sprintf(name, "%.512s.%u", outfname, tcp->pid);
626 tcp->outf = strace_fopen(name);
633 /* Allocate some more TCBs and expand the table.
634 We don't want to relocate the TCBs because our
635 callers have pointers and it would be a pain.
636 So tcbtab is a table of pointers. Since we never
637 free the TCBs, we allocate a single chunk of many. */
639 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
640 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
641 if (!newtab || !newtcbs)
645 while (i < tcbtabsize)
646 tcbtab[i++] = newtcbs++;
655 if (nprocs == tcbtabsize)
658 for (i = 0; i < tcbtabsize; i++) {
660 if ((tcp->flags & TCB_INUSE) == 0) {
661 memset(tcp, 0, sizeof(*tcp));
663 tcp->flags = TCB_INUSE;
664 /* tcp->outf = outf; - not needed? */
665 #if SUPPORTED_PERSONALITIES > 1
666 tcp->currpers = current_personality;
670 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
674 error_msg_and_die("bug in alloctcb");
678 droptcb(struct tcb *tcp)
685 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
688 if (outfname && followfork >= 2) {
689 if (tcp->curcol != 0)
690 fprintf(tcp->outf, " <detached ...>\n");
692 if (outf == tcp->outf)
695 if (printing_tcp == tcp && tcp->curcol != 0)
696 fprintf(tcp->outf, " <detached ...>\n");
701 if (printing_tcp == tcp)
704 memset(tcp, 0, sizeof(*tcp));
707 /* detach traced process; continue with sig
708 * Never call DETACH twice on the same process as both unattached and
709 * attached-unstopped processes give the same ESRCH. For unattached process we
710 * would SIGSTOP it and wait for its SIGSTOP notification forever.
713 detach(struct tcb *tcp)
716 int status, sigstop_expected;
718 if (tcp->flags & TCB_BPTSET)
722 * Linux wrongly insists the child be stopped
723 * before detaching. Arghh. We go through hoops
724 * to make a clean break of things.
728 #define PTRACE_DETACH PTRACE_SUNDETACH
732 sigstop_expected = 0;
733 if (tcp->flags & TCB_ATTACHED) {
735 * We attached but possibly didn't see the expected SIGSTOP.
736 * We must catch exactly one as otherwise the detached process
737 * would be left stopped (process state T).
739 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
740 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
742 /* On a clear day, you can see forever. */
744 else if (errno != ESRCH) {
745 /* Shouldn't happen. */
746 perror("detach: ptrace(PTRACE_DETACH, ...)");
748 else if (my_tkill(tcp->pid, 0) < 0) {
750 perror("detach: checking sanity");
752 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
754 perror("detach: stopping child");
757 sigstop_expected = 1;
760 if (sigstop_expected) {
763 if (waitpid(tcp->pid, &status, __WALL) < 0) {
764 if (errno == ECHILD) /* Already gone. */
766 if (errno != EINVAL) {
767 perror("detach: waiting");
771 /* No __WALL here. */
772 if (waitpid(tcp->pid, &status, 0) < 0) {
773 if (errno != ECHILD) {
774 perror("detach: waiting");
778 /* If no processes, try clones. */
779 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
781 perror("detach: waiting");
784 #endif /* __WCLONE */
789 if (!WIFSTOPPED(status)) {
790 /* Au revoir, mon ami. */
793 if (WSTOPSIG(status) == SIGSTOP) {
794 ptrace_restart(PTRACE_DETACH, tcp, 0);
797 error = ptrace_restart(PTRACE_CONT, tcp,
798 WSTOPSIG(status) == syscall_trap_sig ? 0
805 if (!qflag && (tcp->flags & TCB_ATTACHED))
806 fprintf(stderr, "Process %u detached\n", tcp->pid);
814 process_opt_p_list(char *opt)
818 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
819 * pidof uses space as delim, pgrep uses newline. :(
822 char *delim = opt + strcspn(opt, ", \n\t");
826 pid = atoi(opt); /* TODO: stricter parsing of the number? */
828 error_msg("Invalid process id: '%s'", opt);
832 if (pid == strace_tracer_pid) {
833 error_msg("I'm sorry, I can't let you do that, Dave.");
852 * Block user interruptions as we would leave the traced
853 * process stopped (process state T) if we would terminate in
854 * between PTRACE_ATTACH and wait4() on SIGSTOP.
855 * We rely on cleanup() from this point on.
858 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
860 if (daemonized_tracer) {
863 perror_msg_and_die("fork");
865 if (pid) { /* parent */
867 * Wait for grandchild to attach to straced process
868 * (grandparent). Grandchild SIGKILLs us after it attached.
869 * Grandparent's wait() is unblocked by our death,
870 * it proceeds to exec the straced program.
873 _exit(0); /* paranoia */
876 /* We will be the tracer process. Remember our new pid: */
877 strace_tracer_pid = getpid();
880 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
883 if (!(tcp->flags & TCB_INUSE))
886 /* Is this a process we should attach to, but not yet attached? */
887 if (tcp->flags & TCB_ATTACHED)
888 continue; /* no, we already attached it */
890 if (followfork && !daemonized_tracer) {
891 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
894 sprintf(procdir, "/proc/%d/task", tcp->pid);
895 dir = opendir(procdir);
897 unsigned int ntid = 0, nerr = 0;
900 while ((de = readdir(dir)) != NULL) {
904 if (de->d_fileno == 0)
906 tid = atoi(de->d_name);
910 if (ptrace_attach_or_seize(tid) < 0) {
913 fprintf(stderr, "attach to pid %d failed\n", tid);
917 fprintf(stderr, "attach to pid %d succeeded\n", tid);
920 cur_tcp = alloctcb(tid);
921 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
926 sigprocmask(SIG_SETMASK, &empty_set, NULL);
929 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
933 perror("attach: ptrace(PTRACE_ATTACH, ...)");
938 fprintf(stderr, ntid > 1
939 ? "Process %u attached with %u threads\n"
940 : "Process %u attached\n",
943 if (!(tcp->flags & TCB_ATTACHED)) {
944 /* -p PID, we failed to attach to PID itself
945 * but did attach to some of its sibling threads.
951 } /* if (opendir worked) */
953 if (ptrace_attach_or_seize(tcp->pid) < 0) {
954 perror("attach: ptrace(PTRACE_ATTACH, ...)");
958 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
961 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
963 if (daemonized_tracer) {
965 * Make parent go away.
966 * Also makes grandparent's wait() unblock.
968 kill(getppid(), SIGKILL);
973 "Process %u attached\n",
975 } /* for each tcbtab[] */
979 sigprocmask(SIG_SETMASK, &empty_set, NULL);
983 startup_child(char **argv)
986 const char *filename;
987 char pathname[MAXPATHLEN];
992 if (strchr(filename, '/')) {
993 if (strlen(filename) > sizeof pathname - 1) {
994 errno = ENAMETOOLONG;
995 perror_msg_and_die("exec");
997 strcpy(pathname, filename);
999 #ifdef USE_DEBUGGING_EXEC
1001 * Debuggers customarily check the current directory
1002 * first regardless of the path but doing that gives
1003 * security geeks a panic attack.
1005 else if (stat(filename, &statbuf) == 0)
1006 strcpy(pathname, filename);
1007 #endif /* USE_DEBUGGING_EXEC */
1012 for (path = getenv("PATH"); path && *path; path += m) {
1013 const char *colon = strchr(path, ':');
1019 m = n = strlen(path);
1021 if (!getcwd(pathname, MAXPATHLEN))
1023 len = strlen(pathname);
1025 else if (n > sizeof pathname - 1)
1028 strncpy(pathname, path, n);
1031 if (len && pathname[len - 1] != '/')
1032 pathname[len++] = '/';
1033 strcpy(pathname + len, filename);
1034 if (stat(pathname, &statbuf) == 0 &&
1035 /* Accept only regular files
1036 with some execute bits set.
1037 XXX not perfect, might still fail */
1038 S_ISREG(statbuf.st_mode) &&
1039 (statbuf.st_mode & 0111))
1043 if (stat(pathname, &statbuf) < 0) {
1044 perror_msg_and_die("Can't stat '%s'", filename);
1046 strace_child = pid = fork();
1048 perror_msg_and_die("fork");
1050 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1051 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
1055 close(fileno(outf));
1056 if (!daemonized_tracer && !use_seize) {
1057 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
1058 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
1062 if (username != NULL) {
1063 uid_t run_euid = run_uid;
1064 gid_t run_egid = run_gid;
1066 if (statbuf.st_mode & S_ISUID)
1067 run_euid = statbuf.st_uid;
1068 if (statbuf.st_mode & S_ISGID)
1069 run_egid = statbuf.st_gid;
1071 * It is important to set groups before we
1072 * lose privileges on setuid.
1074 if (initgroups(username, run_gid) < 0) {
1075 perror_msg_and_die("initgroups");
1077 if (setregid(run_gid, run_egid) < 0) {
1078 perror_msg_and_die("setregid");
1080 if (setreuid(run_uid, run_euid) < 0) {
1081 perror_msg_and_die("setreuid");
1084 else if (geteuid() != 0)
1085 setreuid(run_uid, run_uid);
1087 if (!daemonized_tracer) {
1089 * Induce a ptrace stop. Tracer (our parent)
1090 * will resume us with PTRACE_SYSCALL and display
1091 * the immediately following execve syscall.
1092 * Can't do this on NOMMU systems, we are after
1093 * vfork: parent is blocked, stopping would deadlock.
1095 if (!strace_vforked)
1099 /* we depend on SIGCHLD set to SIG_DFL by init code */
1100 /* if it happens to be SIG_IGN'ed, wait won't block */
1105 execv(pathname, argv);
1106 perror_msg_and_die("exec");
1109 /* We are the tracer */
1111 if (!daemonized_tracer) {
1113 /* child did PTRACE_TRACEME, nothing to do in parent */
1115 if (!strace_vforked) {
1116 /* Wait until child stopped itself */
1118 while (waitpid(pid, &status, WSTOPPED) < 0) {
1121 perror_msg_and_die("waitpid");
1123 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
1124 kill_save_errno(pid, SIGKILL);
1125 perror_msg_and_die("Unexpected wait status %x", status);
1128 /* Else: vforked case, we have no way to sync.
1129 * Just attach to it as soon as possible.
1130 * This means that we may miss a few first syscalls...
1133 if (ptrace_attach_or_seize(pid)) {
1134 kill_save_errno(pid, SIGKILL);
1135 perror_msg_and_die("Can't attach to %d", pid);
1137 if (!strace_vforked)
1140 tcp = alloctcb(pid);
1141 if (!strace_vforked)
1142 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
1144 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
1148 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1149 strace_tracer_pid = getpid();
1150 /* The tracee is our parent: */
1153 /* attaching will be done later, by startup_attach */
1154 /* note: we don't do newoutf(tcp) here either! */
1159 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
1160 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
1161 * and then see which options are supported by the kernel.
1164 test_ptrace_setoptions_followfork(void)
1166 int pid, expected_grandchild = 0, found_grandchild = 0;
1167 const unsigned int test_options = PTRACE_O_TRACECLONE |
1168 PTRACE_O_TRACEFORK |
1169 PTRACE_O_TRACEVFORK;
1173 perror_msg_and_die("fork");
1176 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1177 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1179 kill_save_errno(pid, SIGSTOP);
1181 perror_msg_and_die("fork");
1186 int status, tracee_pid;
1189 tracee_pid = wait(&status);
1190 if (tracee_pid <= 0) {
1193 if (errno == ECHILD)
1195 kill_save_errno(pid, SIGKILL);
1196 perror_msg_and_die("%s: unexpected wait result %d",
1197 __func__, tracee_pid);
1199 if (WIFEXITED(status)) {
1200 if (WEXITSTATUS(status)) {
1201 if (tracee_pid != pid)
1202 kill_save_errno(pid, SIGKILL);
1203 error_msg_and_die("%s: unexpected exit status %u",
1204 __func__, WEXITSTATUS(status));
1208 if (WIFSIGNALED(status)) {
1209 if (tracee_pid != pid)
1210 kill_save_errno(pid, SIGKILL);
1211 error_msg_and_die("%s: unexpected signal %u",
1212 __func__, WTERMSIG(status));
1214 if (!WIFSTOPPED(status)) {
1215 if (tracee_pid != pid)
1216 kill_save_errno(tracee_pid, SIGKILL);
1217 kill_save_errno(pid, SIGKILL);
1218 error_msg_and_die("%s: unexpected wait status %x",
1221 if (tracee_pid != pid) {
1222 found_grandchild = tracee_pid;
1223 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1224 kill_save_errno(tracee_pid, SIGKILL);
1225 kill_save_errno(pid, SIGKILL);
1226 perror_msg_and_die("PTRACE_CONT doesn't work");
1230 switch (WSTOPSIG(status)) {
1232 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1233 && errno != EINVAL && errno != EIO)
1234 perror_msg("PTRACE_SETOPTIONS");
1237 if (status >> 16 == PTRACE_EVENT_FORK) {
1240 if (ptrace(PTRACE_GETEVENTMSG, pid,
1241 NULL, (long) &msg) == 0)
1242 expected_grandchild = msg;
1246 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1247 kill_save_errno(pid, SIGKILL);
1248 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1251 if (expected_grandchild && expected_grandchild == found_grandchild) {
1252 ptrace_setoptions |= test_options;
1254 fprintf(stderr, "ptrace_setoptions = %#x\n",
1258 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1259 "giving up using this feature.");
1263 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1264 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1265 * and then see whether it will stop with (SIGTRAP | 0x80).
1267 * Use of this option enables correct handling of user-generated SIGTRAPs,
1268 * and SIGTRAPs generated by special instructions such as int3 on x86:
1269 * _start: .globl _start
1274 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1277 test_ptrace_setoptions_for_all(void)
1279 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1286 perror_msg_and_die("fork");
1290 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1291 /* Note: exits with exitcode 1 */
1292 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1295 _exit(0); /* parent should see entry into this syscall */
1299 int status, tracee_pid;
1302 tracee_pid = wait(&status);
1303 if (tracee_pid <= 0) {
1306 kill_save_errno(pid, SIGKILL);
1307 perror_msg_and_die("%s: unexpected wait result %d",
1308 __func__, tracee_pid);
1310 if (WIFEXITED(status)) {
1311 if (WEXITSTATUS(status) == 0)
1313 error_msg_and_die("%s: unexpected exit status %u",
1314 __func__, WEXITSTATUS(status));
1316 if (WIFSIGNALED(status)) {
1317 error_msg_and_die("%s: unexpected signal %u",
1318 __func__, WTERMSIG(status));
1320 if (!WIFSTOPPED(status)) {
1322 error_msg_and_die("%s: unexpected wait status %x",
1325 if (WSTOPSIG(status) == SIGSTOP) {
1327 * We don't check "options aren't accepted" error.
1328 * If it happens, we'll never get (SIGTRAP | 0x80),
1329 * and thus will decide to not use the option.
1330 * IOW: the outcome of the test will be correct.
1332 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1333 && errno != EINVAL && errno != EIO)
1334 perror_msg("PTRACE_SETOPTIONS");
1336 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1339 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1340 kill_save_errno(pid, SIGKILL);
1341 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1346 syscall_trap_sig = (SIGTRAP | 0x80);
1347 ptrace_setoptions |= test_options;
1349 fprintf(stderr, "ptrace_setoptions = %#x\n",
1354 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1355 "giving up using this feature.");
1360 test_ptrace_seize(void)
1366 perror_msg_and_die("fork");
1373 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1374 * attaching tracee continues to run unless a trap condition occurs.
1375 * PTRACE_SEIZE doesn't affect signal or group stop state.
1377 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1378 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1379 } else if (debug_flag) {
1380 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1386 int status, tracee_pid;
1389 tracee_pid = waitpid(pid, &status, 0);
1390 if (tracee_pid <= 0) {
1393 perror_msg_and_die("%s: unexpected wait result %d",
1394 __func__, tracee_pid);
1396 if (WIFSIGNALED(status)) {
1399 error_msg_and_die("%s: unexpected wait status %x",
1403 # else /* !USE_SEIZE */
1404 # define test_ptrace_seize() ((void)0)
1408 get_os_release(void)
1414 perror_msg_and_die("uname");
1415 /* u.release has this form: "3.2.9[-some-garbage]" */
1419 if (!(*p >= '0' && *p <= '9'))
1420 error_msg_and_die("Bad OS release string: '%s'", u.release);
1421 /* Note: this open-codes KERNEL_VERSION(): */
1422 rel = (rel << 8) | atoi(p);
1423 if (rel >= KERNEL_VERSION(1,0,0))
1425 while (*p >= '0' && *p <= '9')
1428 error_msg_and_die("Bad OS release string: '%s'", u.release);
1435 * Initialization part of main() was eating much stack (~0.5k),
1436 * which was unused after init.
1437 * We can reuse it if we move init code into a separate function.
1439 * Don't want main() to inline us and defeat the reason
1440 * we have a separate function.
1442 static void __attribute__ ((noinline))
1443 init(int argc, char *argv[])
1448 struct sigaction sa;
1450 progname = argv[0] ? argv[0] : "strace";
1452 /* Make sure SIGCHLD has the default action so that waitpid
1453 definitely works without losing track of children. The user
1454 should not have given us a bogus state to inherit, but he might
1455 have. Arguably we should detect SIG_IGN here and pass it on
1456 to children, but probably noone really needs that. */
1457 signal(SIGCHLD, SIG_DFL);
1459 strace_tracer_pid = getpid();
1461 os_release = get_os_release();
1463 /* Allocate the initial tcbtab. */
1464 tcbtabsize = argc; /* Surely enough for all -p args. */
1465 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1467 die_out_of_memory();
1468 tcp = calloc(tcbtabsize, sizeof(*tcp));
1470 die_out_of_memory();
1471 for (c = 0; c < tcbtabsize; c++)
1475 set_sortby(DEFAULT_SORTBY);
1476 set_personality(DEFAULT_PERSONALITY);
1477 qualify("trace=all");
1478 qualify("abbrev=all");
1479 qualify("verbose=all");
1480 qualify("signal=all");
1481 while ((c = getopt(argc, argv,
1482 "+bcCdfFhiqrtTvVxyz"
1484 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1487 detach_on_execve = 1;
1490 if (cflag == CFLAG_BOTH) {
1491 error_msg_and_die("-c and -C are mutually exclusive options");
1493 cflag = CFLAG_ONLY_STATS;
1496 if (cflag == CFLAG_ONLY_STATS) {
1497 error_msg_and_die("-c and -C are mutually exclusive options");
1505 daemonized_tracer = 1;
1524 /* fall through to tflag++ */
1538 qualify("abbrev=none");
1541 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1545 not_failing_only = 1;
1548 acolumn = atoi(optarg);
1550 error_msg_and_die("Bad column width '%s'", optarg);
1556 outfname = strdup(optarg);
1559 set_overhead(atoi(optarg));
1562 process_opt_p_list(optarg);
1566 if (pathtrace_select(optarg)) {
1567 error_msg_and_die("Failed to select path '%s'", optarg);
1571 max_strlen = atoi(optarg);
1572 if (max_strlen < 0) {
1573 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1580 username = strdup(optarg);
1583 if (putenv(optarg) < 0)
1584 die_out_of_memory();
1587 opt_intr = atoi(optarg);
1588 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1589 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1598 /* argc -= optind; - no need, argc is not used below */
1600 acolumn_spaces = malloc(acolumn + 1);
1601 if (!acolumn_spaces)
1602 die_out_of_memory();
1603 memset(acolumn_spaces, ' ', acolumn);
1604 acolumn_spaces[acolumn] = '\0';
1606 /* Must have PROG [ARGS], or -p PID. Not both. */
1607 if (!argv[0] == !nprocs)
1610 if (nprocs != 0 && daemonized_tracer) {
1611 error_msg_and_die("-D and -p are mutually exclusive options");
1617 if (followfork >= 2 && cflag) {
1618 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
1621 /* See if they want to run as another user. */
1622 if (username != NULL) {
1623 struct passwd *pent;
1625 if (getuid() != 0 || geteuid() != 0) {
1626 error_msg_and_die("You must be root to use the -u option");
1628 pent = getpwnam(username);
1630 error_msg_and_die("Cannot find user '%s'", username);
1632 run_uid = pent->pw_uid;
1633 run_gid = pent->pw_gid;
1641 test_ptrace_setoptions_followfork();
1642 test_ptrace_setoptions_for_all();
1643 test_ptrace_seize();
1645 /* Check if they want to redirect the output. */
1647 /* See if they want to pipe the output. */
1648 if (outfname[0] == '|' || outfname[0] == '!') {
1650 * We can't do the <outfname>.PID funny business
1651 * when using popen, so prohibit it.
1653 if (followfork >= 2)
1654 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1655 outf = strace_popen(outfname + 1);
1657 else if (followfork < 2)
1658 outf = strace_fopen(outfname);
1660 /* -ff without -o FILE is the same as single -f */
1661 if (followfork >= 2)
1665 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1666 char *buf = malloc(BUFSIZ);
1668 die_out_of_memory();
1669 setvbuf(outf, buf, _IOLBF, BUFSIZ);
1671 if (outfname && argv[0]) {
1673 opt_intr = INTR_NEVER;
1677 opt_intr = INTR_WHILE_WAIT;
1679 /* argv[0] -pPID -oFILE Default interactive setting
1680 * yes 0 0 INTR_WHILE_WAIT
1681 * no 1 0 INTR_WHILE_WAIT
1682 * yes 0 1 INTR_NEVER
1683 * no 1 1 INTR_WHILE_WAIT
1686 /* STARTUP_CHILD must be called before the signal handlers get
1687 installed below as they are inherited into the spawned process.
1688 Also we do not need to be protected by them as during interruption
1689 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1691 skip_startup_execve = 1;
1692 startup_child(argv);
1695 sigemptyset(&empty_set);
1696 sigemptyset(&blocked_set);
1697 sa.sa_handler = SIG_IGN;
1698 sigemptyset(&sa.sa_mask);
1700 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1701 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1702 if (opt_intr != INTR_ANYWHERE) {
1703 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1704 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1706 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1707 * fatal signals are blocked while syscall stop is processed,
1708 * and acted on in between, when waiting for new syscall stops.
1709 * In non-interactive mode, signals are ignored.
1711 if (opt_intr == INTR_WHILE_WAIT) {
1712 sigaddset(&blocked_set, SIGHUP);
1713 sigaddset(&blocked_set, SIGINT);
1714 sigaddset(&blocked_set, SIGQUIT);
1715 sigaddset(&blocked_set, SIGPIPE);
1716 sigaddset(&blocked_set, SIGTERM);
1717 sa.sa_handler = interrupt;
1719 /* SIG_IGN, or set handler for these */
1720 sigaction(SIGHUP, &sa, NULL);
1721 sigaction(SIGINT, &sa, NULL);
1722 sigaction(SIGQUIT, &sa, NULL);
1723 sigaction(SIGPIPE, &sa, NULL);
1724 sigaction(SIGTERM, &sa, NULL);
1726 if (nprocs != 0 || daemonized_tracer)
1729 /* Do we want pids printed in our -o OUTFILE?
1730 * -ff: no (every pid has its own file); or
1731 * -f: yes (there can be more pids in the future); or
1732 * -p PID1,PID2: yes (there are already more than one pid)
1734 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1745 for (i = 0; i < tcbtabsize; i++) {
1746 struct tcb *tcp = tcbtab[i];
1747 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1761 /* 'interrupted' is a volatile object, fetch it only once */
1762 fatal_sig = interrupted;
1764 fatal_sig = SIGTERM;
1766 for (i = 0; i < tcbtabsize; i++) {
1768 if (!(tcp->flags & TCB_INUSE))
1772 "cleanup: looking at pid %u\n", tcp->pid);
1773 if (tcp->flags & TCB_STRACE_CHILD) {
1774 kill(tcp->pid, SIGCONT);
1775 kill(tcp->pid, fatal_sig);
1793 struct rusage *rup = cflag ? &ru : NULL;
1795 static int wait4_options = __WALL;
1798 while (nprocs != 0) {
1809 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1811 pid = wait4(-1, &status, wait4_options, rup);
1812 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1813 /* this kernel does not support __WALL */
1814 wait4_options &= ~__WALL;
1815 pid = wait4(-1, &status, wait4_options, rup);
1817 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1818 /* most likely a "cloned" process */
1819 pid = wait4(-1, &status, __WCLONE, rup);
1821 perror_msg("wait4(__WCLONE) failed");
1825 pid = wait4(-1, &status, 0, rup);
1826 # endif /* __WALL */
1829 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1832 switch (wait_errno) {
1837 * We would like to verify this case
1838 * but sometimes a race in Solbourne's
1839 * version of SunOS sometimes reports
1840 * ECHILD before sending us SIGCHILD.
1849 if (pid == popen_pid) {
1850 if (WIFEXITED(status) || WIFSIGNALED(status))
1855 event = ((unsigned)status >> 16);
1857 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1858 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1860 if (WIFSIGNALED(status))
1862 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1863 WCOREDUMP(status) ? "core," : "",
1864 signame(WTERMSIG(status)));
1866 sprintf(buf, "WIFSIGNALED,sig=%s",
1867 signame(WTERMSIG(status)));
1869 if (WIFEXITED(status))
1870 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1871 if (WIFSTOPPED(status))
1872 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1874 if (WIFCONTINUED(status))
1875 strcpy(buf, "WIFCONTINUED");
1879 static const char *const event_names[] = {
1880 [PTRACE_EVENT_CLONE] = "CLONE",
1881 [PTRACE_EVENT_FORK] = "FORK",
1882 [PTRACE_EVENT_VFORK] = "VFORK",
1883 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1884 [PTRACE_EVENT_EXEC] = "EXEC",
1885 [PTRACE_EVENT_EXIT] = "EXIT",
1888 if (event < ARRAY_SIZE(event_names))
1889 e = event_names[event];
1891 sprintf(buf, "?? (%u)", event);
1894 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1896 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1899 /* Look up 'pid' in our table. */
1902 /* Under Linux, execve changes pid to thread leader's pid,
1903 * and we see this changed pid on EVENT_EXEC and later,
1904 * execve sysexit. Leader "disappears" without exit
1905 * notification. Let user know that, drop leader's tcb,
1906 * and fix up pid in execve thread's tcb.
1907 * Effectively, execve thread's tcb replaces leader's tcb.
1909 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1910 * on exit syscall) in multithreaded programs exactly
1911 * in order to handle this case.
1913 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1914 * On 2.6 and earlier, it can return garbage.
1916 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
1918 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1922 struct tcb *execve_thread = pid2tcb(old_pid);
1925 curcol = tcp->curcol;
1926 if (execve_thread) {
1927 if (execve_thread->curcol != 0) {
1929 * One case we are here is -ff:
1930 * try "strace -oLOG -ff test/threaded_execve"
1932 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1933 execve_thread->curcol = 0;
1935 /* swap output FILEs (needed for -ff) */
1936 tcp->outf = execve_thread->outf;
1937 tcp->curcol = execve_thread->curcol;
1938 execve_thread->outf = outf;
1939 execve_thread->curcol = curcol;
1943 tcp = execve_thread;
1946 tcp->flags |= TCB_REPRINT;
1949 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1956 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1957 if (!skip_startup_execve)
1959 /* This was initial execve for "strace PROG". Skip. */
1960 skip_startup_execve = 0;
1965 /* This is needed to go with the CLONE_PTRACE
1966 changes in process.c/util.c: we might see
1967 the child's initial trap before we see the
1968 parent return from the clone syscall.
1969 Leave the child suspended until the parent
1970 returns from its system call. Only then
1971 will we have the association of parent and
1972 child so that we know how to do clearbpt
1974 tcp = alloctcb(pid);
1975 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1978 fprintf(stderr, "Process %d attached\n",
1982 /* This can happen if a clone call used
1983 CLONE_PTRACE itself. */
1985 if (WIFSTOPPED(status))
1986 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1987 error_msg_and_die("Unknown pid: %u", pid);
1991 /* Set current output file */
1993 curcol = tcp->curcol;
1996 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1997 tcp->stime = ru.ru_stime;
2000 if (WIFSIGNALED(status)) {
2001 if (pid == strace_child)
2002 exit_code = 0x100 | WTERMSIG(status);
2003 if (cflag != CFLAG_ONLY_STATS
2004 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2007 tprintf("+++ killed by %s %s+++\n",
2008 signame(WTERMSIG(status)),
2009 WCOREDUMP(status) ? "(core dumped) " : "");
2011 tprintf("+++ killed by %s +++\n",
2012 signame(WTERMSIG(status)));
2019 if (WIFEXITED(status)) {
2020 if (pid == strace_child)
2021 exit_code = WEXITSTATUS(status);
2022 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
2024 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
2030 if (!WIFSTOPPED(status)) {
2031 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2036 /* Is this the very first time we see this tracee stopped? */
2037 if (tcp->flags & TCB_STARTUP) {
2039 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2040 tcp->flags &= ~TCB_STARTUP;
2041 if (tcp->flags & TCB_BPTSET) {
2043 * One example is a breakpoint inherited from
2044 * parent through fork().
2046 if (clearbpt(tcp) < 0) {
2053 if (ptrace_setoptions) {
2055 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2056 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2057 if (errno != ESRCH) {
2058 /* Should never happen, really */
2059 perror_msg_and_die("PTRACE_SETOPTIONS");
2065 sig = WSTOPSIG(status);
2070 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
2072 * PTRACE_INTERRUPT-stop or group-stop.
2073 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2085 goto restart_tracee_with_sig_0;
2088 /* Is this post-attach SIGSTOP?
2089 * Interestingly, the process may stop
2090 * with STOPSIG equal to some other signal
2091 * than SIGSTOP if we happend to attach
2092 * just before the process takes a signal.
2094 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2096 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2097 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2098 goto restart_tracee_with_sig_0;
2101 if (sig != syscall_trap_sig) {
2104 /* Nonzero (true) if tracee is stopped by signal
2105 * (as opposed to "tracee received signal").
2107 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2111 if (cflag != CFLAG_ONLY_STATS
2112 && (qual_flags[sig] & QUAL_SIGNAL)) {
2113 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2117 upeek(tcp, PT_CR_IPSR, &psr);
2118 upeek(tcp, PT_CR_IIP, &pc);
2121 pc += (psr >> PSR_RI) & 0x3;
2122 # define PC_FORMAT_STR " @ %lx"
2123 # define PC_FORMAT_ARG , pc
2125 # define PC_FORMAT_STR ""
2126 # define PC_FORMAT_ARG /* nothing */
2130 tprintf("--- %s ", signame(sig));
2131 printsiginfo(&si, verbose(tcp));
2132 tprintf(PC_FORMAT_STR " ---\n"
2135 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
2142 /* It's signal-delivery-stop. Inject the signal */
2143 goto restart_tracee;
2145 /* It's group-stop */
2149 * This ends ptrace-stop, but does *not* end group-stop.
2150 * This makes stopping signals work properly on straced process
2151 * (that is, process really stops. It used to continue to run).
2153 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2157 tcp->curcol = curcol;
2160 /* We don't have PTRACE_LISTEN support... */
2162 goto restart_tracee;
2165 /* We handled quick cases, we are permitted to interrupt now. */
2169 /* This should be syscall entry or exit.
2170 * (Or it still can be that pesky post-execve SIGTRAP!)
2173 if (trace_syscall(tcp) < 0) {
2174 /* ptrace() failed in trace_syscall().
2175 * Likely a result of process disappearing mid-flight.
2176 * Observed case: exit_group() or SIGKILL terminating
2177 * all processes in thread group.
2178 * We assume that ptrace error was caused by process death.
2179 * We used to detach(tcp) here, but since we no longer
2180 * implement "detach before death" policy/hack,
2181 * we can let this process to report its death to us
2182 * normally, via WIFEXITED or WIFSIGNALED wait status.
2184 tcp->curcol = curcol;
2187 restart_tracee_with_sig_0:
2190 /* Remember current print column before continuing. */
2191 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2192 tcp->curcol = curcol;
2196 tcp->curcol = curcol;
2202 main(int argc, char *argv[])
2206 /* Run main tracing loop */
2212 if (exit_code > 0xff) {
2213 /* Avoid potential core file clobbering. */
2214 struct rlimit rlim = {0, 0};
2215 setrlimit(RLIMIT_CORE, &rlim);
2217 /* Child was killed by a signal, mimic that. */
2219 signal(exit_code, SIG_DFL);
2221 /* Paranoia - what if this signal is not fatal?
2222 Exit with 128 + signo then. */