2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/param.h>
38 #include <sys/resource.h>
44 #include <sys/utsname.h>
46 # include <asm/ptrace_offsets.h>
48 /* In some libc, these aren't declared. Do it ourself: */
49 extern char **environ;
54 #if defined __NR_tkill
55 # define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
57 /* kill() may choose arbitrarily the target task of the process group
58 while we later wait on a that specific TID. PID process waits become
59 TID task specific waits for a process under ptrace(2). */
60 # warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
61 # define my_tkill(tid, sig) kill((tid), (sig))
65 #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
67 cflag_t cflag = CFLAG_NONE;
68 unsigned int followfork = 0;
69 unsigned int ptrace_setoptions = 0;
70 unsigned int xflag = 0;
74 /* Which WSTOPSIG(status) value marks syscall traps? */
75 static unsigned int syscall_trap_sig = SIGTRAP;
76 static unsigned int tflag = 0;
77 static bool iflag = 0;
78 static bool rflag = 0;
79 static bool print_pid_pfx = 0;
84 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
85 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
86 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
87 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
91 /* We play with signal mask only if this mode is active: */
92 #define interactive (opt_intr == INTR_WHILE_WAIT)
95 * daemonized_tracer supports -D option.
96 * With this option, strace forks twice.
97 * Unlike normal case, with -D *grandparent* process exec's,
98 * becoming a traced process. Child exits (this prevents traced process
99 * from having children it doesn't expect to have), and grandchild
100 * attaches to grandparent similarly to strace -p PID.
101 * This allows for more transparent interaction in cases
102 * when process and its parent are communicating via signals,
103 * wait() etc. Without -D, strace process gets lodged in between,
104 * disrupting parent<->child link.
106 static bool daemonized_tracer = 0;
109 static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
110 # define use_seize (post_attach_sigstop == 0)
112 # define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
116 /* Sometimes we want to print only succeeding syscalls. */
117 bool not_failing_only = 0;
119 /* Show path associated with fd arguments */
120 bool show_fd_path = 0;
122 /* are we filtering traces based on paths? */
123 bool tracing_paths = 0;
125 static bool detach_on_execve = 0;
126 static bool skip_startup_execve = 0;
128 static int exit_code = 0;
129 static int strace_child = 0;
130 static int strace_tracer_pid = 0;
132 static char *username = NULL;
133 static uid_t run_uid;
134 static gid_t run_gid;
136 unsigned int max_strlen = DEFAULT_STRLEN;
137 static unsigned int acolumn = DEFAULT_ACOLUMN;
138 static char *acolumn_spaces;
139 static char *outfname = NULL;
141 struct tcb *printing_tcp = NULL;
142 static unsigned int curcol;
143 static struct tcb **tcbtab;
144 static unsigned int nprocs, tcbtabsize;
145 static const char *progname;
147 static unsigned os_release; /* generated from uname()'s u.release */
149 static int detach(struct tcb *tcp);
150 static int trace(void);
151 static void cleanup(void);
152 static void interrupt(int sig);
153 static sigset_t empty_set, blocked_set;
155 #ifdef HAVE_SIG_ATOMIC_T
156 static volatile sig_atomic_t interrupted;
158 static volatile int interrupted;
161 #ifndef HAVE_STRERROR
163 #if !HAVE_DECL_SYS_ERRLIST
165 extern char *sys_errlist[];
166 #endif /* HAVE_DECL_SYS_ERRLIST */
171 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
173 if (err_no < 1 || err_no >= sys_nerr) {
174 sprintf(buf, "Unknown error %d", err_no);
177 return sys_errlist[err_no];
180 #endif /* HAVE_STERRROR */
183 usage(FILE *ofp, int exitval)
186 usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
187 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
188 [-P path] [PROG [ARGS]]\n\
189 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
191 -c -- count time, calls, and errors for each syscall and report summary\n\
192 -C -- like -c but also print regular output while processes are running\n\
193 -d -- enable debug output to stderr\n\
194 -D -- run tracer process as a detached grandchild, not as parent\n\
195 -f -- follow forks, -ff -- with output into separate files\n\
196 -F -- attempt to follow vforks (deprecated, use -f)\n\
197 -i -- print instruction pointer at time of syscall\n\
199 1: no signals are blocked\n\
200 2: fatal signals are blocked while decoding syscall (default)\n\
201 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
202 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
203 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
204 -q -- suppress messages about attaching, detaching, etc.\n\
205 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
206 -T -- print time spent in each syscall\n\
207 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
208 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
209 -y -- print paths associated with file descriptor arguments\n\
210 -h -- print help message\n\
211 -V -- print version\n\
212 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
213 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
214 options: trace, abbrev, verbose, raw, signal, read, or write\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");
317 /* Glue for systems without a MMU that cannot provide fork() */
319 # define strace_vforked 0
321 # define strace_vforked 1
322 # define fork() vfork()
327 ptrace_attach_or_seize(int pid)
331 return ptrace(PTRACE_ATTACH, pid, 0, 0);
332 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
335 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
339 # define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
343 set_cloexec_flag(int fd)
347 flags = fcntl(fd, F_GETFD);
349 /* Can happen only if fd is bad.
350 * Should never happen: if it does, we have a bug
351 * in the caller. Therefore we just abort
352 * instead of propagating the error.
354 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
357 newflags = flags | FD_CLOEXEC;
358 if (flags == newflags)
361 fcntl(fd, F_SETFD, newflags); /* never fails */
364 static void kill_save_errno(pid_t pid, int sig)
366 int saved_errno = errno;
368 (void) kill(pid, sig);
373 tprintf(const char *fmt, ...)
379 int n = vfprintf(outf, fmt, args);
382 perror(outfname == NULL
383 ? "<writing to pipe>" : outfname);
391 tprints(const char *str)
394 int n = fputs(str, outf);
396 curcol += strlen(str);
400 perror(outfname == NULL
401 ? "<writing to pipe>" : outfname);
412 printing_tcp->curcol = 0;
417 printleader(struct tcb *tcp)
419 /* If -ff, "previous tcb we printed" is always the same as current,
420 * because we have per-tcb output files.
426 outf = printing_tcp->outf;
427 curcol = printing_tcp->curcol;
428 if (printing_tcp->ptrace_errno) {
429 if (printing_tcp->flags & TCB_INSYSCALL) {
430 tprints(" <unavailable>) ");
433 tprints("= ? <unavailable>\n");
434 printing_tcp->ptrace_errno = 0;
435 printing_tcp->curcol = 0;
437 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
439 * case 1: we have a shared log (i.e. not -ff), and last line
440 * wasn't finished (same or different tcb, doesn't matter).
441 * case 2: split log, we are the same tcb, but our last line
442 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
444 tprints(" <unfinished ...>\n");
445 printing_tcp->flags |= TCB_REPRINT;
446 printing_tcp->curcol = 0;
455 tprintf("%-5d ", tcp->pid);
456 else if (nprocs > 1 && !outfname)
457 tprintf("[pid %5u] ", tcp->pid);
460 char str[sizeof("HH:MM:SS")];
461 struct timeval tv, dtv;
462 static struct timeval otv;
464 gettimeofday(&tv, NULL);
468 tv_sub(&dtv, &tv, &otv);
469 tprintf("%6ld.%06ld ",
470 (long) dtv.tv_sec, (long) dtv.tv_usec);
473 else if (tflag > 2) {
474 tprintf("%ld.%06ld ",
475 (long) tv.tv_sec, (long) tv.tv_usec);
478 time_t local = tv.tv_sec;
479 strftime(str, sizeof(str), "%T", localtime(&local));
481 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
493 if (curcol < acolumn)
494 tprints(acolumn_spaces + curcol);
498 * When strace is setuid executable, we have to swap uids
499 * before and after filesystem and process management operations.
504 int euid = geteuid(), uid = getuid();
506 if (euid != uid && setreuid(euid, uid) < 0) {
507 perror_msg_and_die("setreuid");
512 # define fopen_for_output fopen64
514 # define fopen_for_output fopen
518 strace_fopen(const char *path)
523 fp = fopen_for_output(path, "w");
525 perror_msg_and_die("Can't fopen '%s'", path);
527 set_cloexec_flag(fileno(fp));
531 static int popen_pid = 0;
534 # define _PATH_BSHELL "/bin/sh"
538 * We cannot use standard popen(3) here because we have to distinguish
539 * popen child process from other processes we trace, and standard popen(3)
540 * does not export its child's pid.
543 strace_popen(const char *command)
550 perror_msg_and_die("pipe");
552 set_cloexec_flag(fds[1]); /* never fails */
556 perror_msg_and_die("vfork");
558 if (popen_pid == 0) {
563 perror_msg_and_die("dup2");
566 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
567 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
573 fp = fdopen(fds[1], "w");
580 newoutf(struct tcb *tcp)
582 if (outfname && followfork >= 2) {
583 char name[520 + sizeof(int) * 3];
584 sprintf(name, "%.512s.%u", outfname, tcp->pid);
585 tcp->outf = strace_fopen(name);
590 process_opt_p_list(char *opt)
594 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
595 * pidof uses space as delim, pgrep uses newline. :(
598 char *delim = opt + strcspn(opt, ", \n\t");
602 pid = atoi(opt); /* TODO: stricter parsing of the number? */
604 error_msg("Invalid process id: '%s'", opt);
608 if (pid == strace_tracer_pid) {
609 error_msg("I'm sorry, I can't let you do that, Dave.");
628 * Block user interruptions as we would leave the traced
629 * process stopped (process state T) if we would terminate in
630 * between PTRACE_ATTACH and wait4() on SIGSTOP.
631 * We rely on cleanup() from this point on.
634 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
636 if (daemonized_tracer) {
639 perror_msg_and_die("fork");
641 if (pid) { /* parent */
643 * Wait for grandchild to attach to straced process
644 * (grandparent). Grandchild SIGKILLs us after it attached.
645 * Grandparent's wait() is unblocked by our death,
646 * it proceeds to exec the straced program.
649 _exit(0); /* paranoia */
652 /* We will be the tracer process. Remember our new pid: */
653 strace_tracer_pid = getpid();
656 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
659 if (!(tcp->flags & TCB_INUSE))
662 /* Is this a process we should attach to, but not yet attached? */
663 if (tcp->flags & TCB_ATTACHED)
664 continue; /* no, we already attached it */
666 /* Reinitialize the output since it may have changed */
670 if (followfork && !daemonized_tracer) {
671 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
674 sprintf(procdir, "/proc/%d/task", tcp->pid);
675 dir = opendir(procdir);
677 unsigned int ntid = 0, nerr = 0;
680 while ((de = readdir(dir)) != NULL) {
684 if (de->d_fileno == 0)
686 tid = atoi(de->d_name);
690 if (ptrace_attach_or_seize(tid) < 0) {
693 fprintf(stderr, "attach to pid %d failed\n", tid);
697 fprintf(stderr, "attach to pid %d succeeded\n", tid);
700 cur_tcp = alloctcb(tid);
701 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
705 sigprocmask(SIG_SETMASK, &empty_set, NULL);
708 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
712 perror("attach: ptrace(PTRACE_ATTACH, ...)");
717 fprintf(stderr, ntid > 1
718 ? "Process %u attached with %u threads - interrupt to quit\n"
719 : "Process %u attached - interrupt to quit\n",
722 if (!(tcp->flags & TCB_ATTACHED)) {
723 /* -p PID, we failed to attach to PID itself
724 * but did attach to some of its sibling threads.
730 } /* if (opendir worked) */
732 if (ptrace_attach_or_seize(tcp->pid) < 0) {
733 perror("attach: ptrace(PTRACE_ATTACH, ...)");
737 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
739 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
741 if (daemonized_tracer) {
743 * Make parent go away.
744 * Also makes grandparent's wait() unblock.
746 kill(getppid(), SIGKILL);
751 "Process %u attached - interrupt to quit\n",
753 } /* for each tcbtab[] */
757 sigprocmask(SIG_SETMASK, &empty_set, NULL);
761 startup_child(char **argv)
764 const char *filename;
765 char pathname[MAXPATHLEN];
770 if (strchr(filename, '/')) {
771 if (strlen(filename) > sizeof pathname - 1) {
772 errno = ENAMETOOLONG;
773 perror_msg_and_die("exec");
775 strcpy(pathname, filename);
777 #ifdef USE_DEBUGGING_EXEC
779 * Debuggers customarily check the current directory
780 * first regardless of the path but doing that gives
781 * security geeks a panic attack.
783 else if (stat(filename, &statbuf) == 0)
784 strcpy(pathname, filename);
785 #endif /* USE_DEBUGGING_EXEC */
790 for (path = getenv("PATH"); path && *path; path += m) {
791 const char *colon = strchr(path, ':');
797 m = n = strlen(path);
799 if (!getcwd(pathname, MAXPATHLEN))
801 len = strlen(pathname);
803 else if (n > sizeof pathname - 1)
806 strncpy(pathname, path, n);
809 if (len && pathname[len - 1] != '/')
810 pathname[len++] = '/';
811 strcpy(pathname + len, filename);
812 if (stat(pathname, &statbuf) == 0 &&
813 /* Accept only regular files
814 with some execute bits set.
815 XXX not perfect, might still fail */
816 S_ISREG(statbuf.st_mode) &&
817 (statbuf.st_mode & 0111))
821 if (stat(pathname, &statbuf) < 0) {
822 perror_msg_and_die("Can't stat '%s'", filename);
824 strace_child = pid = fork();
826 perror_msg_and_die("fork");
828 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
829 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
834 if (!daemonized_tracer && !use_seize) {
835 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
836 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
840 if (username != NULL) {
841 uid_t run_euid = run_uid;
842 gid_t run_egid = run_gid;
844 if (statbuf.st_mode & S_ISUID)
845 run_euid = statbuf.st_uid;
846 if (statbuf.st_mode & S_ISGID)
847 run_egid = statbuf.st_gid;
849 * It is important to set groups before we
850 * lose privileges on setuid.
852 if (initgroups(username, run_gid) < 0) {
853 perror_msg_and_die("initgroups");
855 if (setregid(run_gid, run_egid) < 0) {
856 perror_msg_and_die("setregid");
858 if (setreuid(run_uid, run_euid) < 0) {
859 perror_msg_and_die("setreuid");
862 else if (geteuid() != 0)
863 setreuid(run_uid, run_uid);
865 if (!daemonized_tracer) {
867 * Induce a ptrace stop. Tracer (our parent)
868 * will resume us with PTRACE_SYSCALL and display
869 * the immediately following execve syscall.
870 * Can't do this on NOMMU systems, we are after
871 * vfork: parent is blocked, stopping would deadlock.
877 /* we depend on SIGCHLD set to SIG_DFL by init code */
878 /* if it happens to be SIG_IGN'ed, wait won't block */
883 execv(pathname, argv);
884 perror_msg_and_die("exec");
887 /* We are the tracer */
889 if (!daemonized_tracer) {
891 /* child did PTRACE_TRACEME, nothing to do in parent */
893 if (!strace_vforked) {
894 /* Wait until child stopped itself */
896 while (waitpid(pid, &status, WSTOPPED) < 0) {
899 perror_msg_and_die("waitpid");
901 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
902 kill_save_errno(pid, SIGKILL);
903 perror_msg_and_die("Unexpected wait status %x", status);
906 /* Else: vforked case, we have no way to sync.
907 * Just attach to it as soon as possible.
908 * This means that we may miss a few first syscalls...
911 if (ptrace_attach_or_seize(pid)) {
912 kill_save_errno(pid, SIGKILL);
913 perror_msg_and_die("Can't attach to %d", pid);
920 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
922 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
925 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
926 strace_tracer_pid = getpid();
927 /* The tracee is our parent: */
930 /* attaching will be done later, by startup_attach */
935 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
936 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
937 * and then see which options are supported by the kernel.
940 test_ptrace_setoptions_followfork(void)
942 int pid, expected_grandchild = 0, found_grandchild = 0;
943 const unsigned int test_options = PTRACE_O_TRACECLONE |
949 perror_msg_and_die("fork");
952 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
953 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
955 kill_save_errno(pid, SIGSTOP);
957 perror_msg_and_die("fork");
962 int status, tracee_pid;
965 tracee_pid = wait(&status);
966 if (tracee_pid <= 0) {
971 kill_save_errno(pid, SIGKILL);
972 perror_msg_and_die("%s: unexpected wait result %d",
973 __func__, tracee_pid);
975 if (WIFEXITED(status)) {
976 if (WEXITSTATUS(status)) {
977 if (tracee_pid != pid)
978 kill_save_errno(pid, SIGKILL);
979 error_msg_and_die("%s: unexpected exit status %u",
980 __func__, WEXITSTATUS(status));
984 if (WIFSIGNALED(status)) {
985 if (tracee_pid != pid)
986 kill_save_errno(pid, SIGKILL);
987 error_msg_and_die("%s: unexpected signal %u",
988 __func__, WTERMSIG(status));
990 if (!WIFSTOPPED(status)) {
991 if (tracee_pid != pid)
992 kill_save_errno(tracee_pid, SIGKILL);
993 kill_save_errno(pid, SIGKILL);
994 error_msg_and_die("%s: unexpected wait status %x",
997 if (tracee_pid != pid) {
998 found_grandchild = tracee_pid;
999 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1000 kill_save_errno(tracee_pid, SIGKILL);
1001 kill_save_errno(pid, SIGKILL);
1002 perror_msg_and_die("PTRACE_CONT doesn't work");
1006 switch (WSTOPSIG(status)) {
1008 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1009 && errno != EINVAL && errno != EIO)
1010 perror_msg("PTRACE_SETOPTIONS");
1013 if (status >> 16 == PTRACE_EVENT_FORK) {
1016 if (ptrace(PTRACE_GETEVENTMSG, pid,
1017 NULL, (long) &msg) == 0)
1018 expected_grandchild = msg;
1022 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1023 kill_save_errno(pid, SIGKILL);
1024 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1027 if (expected_grandchild && expected_grandchild == found_grandchild) {
1028 ptrace_setoptions |= test_options;
1030 fprintf(stderr, "ptrace_setoptions = %#x\n",
1034 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1035 "giving up using this feature.");
1039 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1040 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1041 * and then see whether it will stop with (SIGTRAP | 0x80).
1043 * Use of this option enables correct handling of user-generated SIGTRAPs,
1044 * and SIGTRAPs generated by special instructions such as int3 on x86:
1045 * _start: .globl _start
1050 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1053 test_ptrace_setoptions_for_all(void)
1055 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1062 perror_msg_and_die("fork");
1066 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
1067 /* Note: exits with exitcode 1 */
1068 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1071 _exit(0); /* parent should see entry into this syscall */
1075 int status, tracee_pid;
1078 tracee_pid = wait(&status);
1079 if (tracee_pid <= 0) {
1082 kill_save_errno(pid, SIGKILL);
1083 perror_msg_and_die("%s: unexpected wait result %d",
1084 __func__, tracee_pid);
1086 if (WIFEXITED(status)) {
1087 if (WEXITSTATUS(status) == 0)
1089 error_msg_and_die("%s: unexpected exit status %u",
1090 __func__, WEXITSTATUS(status));
1092 if (WIFSIGNALED(status)) {
1093 error_msg_and_die("%s: unexpected signal %u",
1094 __func__, WTERMSIG(status));
1096 if (!WIFSTOPPED(status)) {
1098 error_msg_and_die("%s: unexpected wait status %x",
1101 if (WSTOPSIG(status) == SIGSTOP) {
1103 * We don't check "options aren't accepted" error.
1104 * If it happens, we'll never get (SIGTRAP | 0x80),
1105 * and thus will decide to not use the option.
1106 * IOW: the outcome of the test will be correct.
1108 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1109 && errno != EINVAL && errno != EIO)
1110 perror_msg("PTRACE_SETOPTIONS");
1112 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1115 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
1116 kill_save_errno(pid, SIGKILL);
1117 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1122 syscall_trap_sig = (SIGTRAP | 0x80);
1123 ptrace_setoptions |= test_options;
1125 fprintf(stderr, "ptrace_setoptions = %#x\n",
1130 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1131 "giving up using this feature.");
1136 test_ptrace_seize(void)
1142 perror_msg_and_die("fork");
1149 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1150 * attaching tracee continues to run unless a trap condition occurs.
1151 * PTRACE_SEIZE doesn't affect signal or group stop state.
1153 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1154 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1155 } else if (debug_flag) {
1156 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1162 int status, tracee_pid;
1165 tracee_pid = waitpid(pid, &status, 0);
1166 if (tracee_pid <= 0) {
1169 perror_msg_and_die("%s: unexpected wait result %d",
1170 __func__, tracee_pid);
1172 if (WIFSIGNALED(status)) {
1175 error_msg_and_die("%s: unexpected wait status %x",
1179 # else /* !USE_SEIZE */
1180 # define test_ptrace_seize() ((void)0)
1184 get_os_release(void)
1190 perror_msg_and_die("uname");
1191 /* u.release has this form: "3.2.9[-some-garbage]" */
1195 if (!(*p >= '0' && *p <= '9'))
1196 error_msg_and_die("Bad OS release string: '%s'", u.release);
1197 /* Note: this open-codes KERNEL_VERSION(): */
1198 rel = (rel << 8) | atoi(p);
1199 if (rel >= KERNEL_VERSION(1,0,0))
1201 while (*p >= '0' && *p <= '9')
1204 error_msg_and_die("Bad OS release string: '%s'", u.release);
1211 * Initialization part of main() was eating much stack (~0.5k),
1212 * which was unused after init.
1213 * We can reuse it if we move init code into a separate function.
1215 * Don't want main() to inline us and defeat the reason
1216 * we have a separate function.
1218 static void __attribute__ ((noinline))
1219 init(int argc, char *argv[])
1224 struct sigaction sa;
1226 progname = argv[0] ? argv[0] : "strace";
1228 /* Make sure SIGCHLD has the default action so that waitpid
1229 definitely works without losing track of children. The user
1230 should not have given us a bogus state to inherit, but he might
1231 have. Arguably we should detect SIG_IGN here and pass it on
1232 to children, but probably noone really needs that. */
1233 signal(SIGCHLD, SIG_DFL);
1235 strace_tracer_pid = getpid();
1237 os_release = get_os_release();
1239 /* Allocate the initial tcbtab. */
1240 tcbtabsize = argc; /* Surely enough for all -p args. */
1241 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1243 die_out_of_memory();
1244 tcp = calloc(tcbtabsize, sizeof(*tcp));
1246 die_out_of_memory();
1247 for (c = 0; c < tcbtabsize; c++)
1251 set_sortby(DEFAULT_SORTBY);
1252 set_personality(DEFAULT_PERSONALITY);
1253 qualify("trace=all");
1254 qualify("abbrev=all");
1255 qualify("verbose=all");
1256 qualify("signal=all");
1257 while ((c = getopt(argc, argv,
1258 "+bcCdfFhiqrtTvVxyz"
1260 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1263 detach_on_execve = 1;
1266 if (cflag == CFLAG_BOTH) {
1267 error_msg_and_die("-c and -C are mutually exclusive options");
1269 cflag = CFLAG_ONLY_STATS;
1272 if (cflag == CFLAG_ONLY_STATS) {
1273 error_msg_and_die("-c and -C are mutually exclusive options");
1281 daemonized_tracer = 1;
1300 /* fall through to tflag++ */
1314 qualify("abbrev=none");
1317 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1321 not_failing_only = 1;
1324 acolumn = atoi(optarg);
1326 error_msg_and_die("Bad column width '%s'", optarg);
1332 outfname = strdup(optarg);
1335 set_overhead(atoi(optarg));
1338 process_opt_p_list(optarg);
1342 if (pathtrace_select(optarg)) {
1343 error_msg_and_die("Failed to select path '%s'", optarg);
1347 max_strlen = atoi(optarg);
1348 if (max_strlen < 0) {
1349 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1356 username = strdup(optarg);
1359 if (putenv(optarg) < 0)
1360 die_out_of_memory();
1363 opt_intr = atoi(optarg);
1364 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1365 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1374 /* argc -= optind; - no need, argc is not used below */
1376 acolumn_spaces = malloc(acolumn + 1);
1377 if (!acolumn_spaces)
1378 die_out_of_memory();
1379 memset(acolumn_spaces, ' ', acolumn);
1380 acolumn_spaces[acolumn] = '\0';
1382 /* Must have PROG [ARGS], or -p PID. Not both. */
1383 if (!argv[0] == !nprocs)
1386 if (nprocs != 0 && daemonized_tracer) {
1387 error_msg_and_die("-D and -p are mutually exclusive options");
1393 if (followfork > 1 && cflag) {
1394 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
1397 /* See if they want to run as another user. */
1398 if (username != NULL) {
1399 struct passwd *pent;
1401 if (getuid() != 0 || geteuid() != 0) {
1402 error_msg_and_die("You must be root to use the -u option");
1404 pent = getpwnam(username);
1406 error_msg_and_die("Cannot find user '%s'", username);
1408 run_uid = pent->pw_uid;
1409 run_gid = pent->pw_gid;
1417 test_ptrace_setoptions_followfork();
1418 test_ptrace_setoptions_for_all();
1419 test_ptrace_seize();
1421 /* Check if they want to redirect the output. */
1423 /* See if they want to pipe the output. */
1424 if (outfname[0] == '|' || outfname[0] == '!') {
1426 * We can't do the <outfname>.PID funny business
1427 * when using popen, so prohibit it.
1430 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1431 outf = strace_popen(outfname + 1);
1433 else if (followfork <= 1)
1434 outf = strace_fopen(outfname);
1436 /* -ff without -o FILE is the same as single -f */
1441 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1442 char *buf = malloc(BUFSIZ);
1444 die_out_of_memory();
1445 setvbuf(outf, buf, _IOLBF, BUFSIZ);
1447 if (outfname && argv[0]) {
1449 opt_intr = INTR_NEVER;
1453 opt_intr = INTR_WHILE_WAIT;
1455 /* argv[0] -pPID -oFILE Default interactive setting
1456 * yes 0 0 INTR_WHILE_WAIT
1457 * no 1 0 INTR_WHILE_WAIT
1458 * yes 0 1 INTR_NEVER
1459 * no 1 1 INTR_WHILE_WAIT
1462 /* STARTUP_CHILD must be called before the signal handlers get
1463 installed below as they are inherited into the spawned process.
1464 Also we do not need to be protected by them as during interruption
1465 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1467 skip_startup_execve = 1;
1468 startup_child(argv);
1471 sigemptyset(&empty_set);
1472 sigemptyset(&blocked_set);
1473 sa.sa_handler = SIG_IGN;
1474 sigemptyset(&sa.sa_mask);
1476 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1477 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1478 if (opt_intr != INTR_ANYWHERE) {
1479 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1480 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1482 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1483 * fatal signals are blocked while syscall stop is processed,
1484 * and acted on in between, when waiting for new syscall stops.
1485 * In non-interactive mode, signals are ignored.
1487 if (opt_intr == INTR_WHILE_WAIT) {
1488 sigaddset(&blocked_set, SIGHUP);
1489 sigaddset(&blocked_set, SIGINT);
1490 sigaddset(&blocked_set, SIGQUIT);
1491 sigaddset(&blocked_set, SIGPIPE);
1492 sigaddset(&blocked_set, SIGTERM);
1493 sa.sa_handler = interrupt;
1495 /* SIG_IGN, or set handler for these */
1496 sigaction(SIGHUP, &sa, NULL);
1497 sigaction(SIGINT, &sa, NULL);
1498 sigaction(SIGQUIT, &sa, NULL);
1499 sigaction(SIGPIPE, &sa, NULL);
1500 sigaction(SIGTERM, &sa, NULL);
1502 if (nprocs != 0 || daemonized_tracer)
1505 /* Do we want pids printed in our -o OUTFILE?
1506 * -ff: no (every pid has its own file); or
1507 * -f: yes (there can be more pids in the future); or
1508 * -p PID1,PID2: yes (there are already more than one pid)
1510 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1516 /* Allocate some more TCBs and expand the table.
1517 We don't want to relocate the TCBs because our
1518 callers have pointers and it would be a pain.
1519 So tcbtab is a table of pointers. Since we never
1520 free the TCBs, we allocate a single chunk of many. */
1522 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1523 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
1524 if (!newtab || !newtcbs)
1525 die_out_of_memory();
1528 while (i < tcbtabsize)
1529 tcbtab[i++] = newtcbs++;
1533 alloc_tcb(int pid, int command_options_parsed)
1538 if (nprocs == tcbtabsize)
1541 for (i = 0; i < tcbtabsize; i++) {
1543 if ((tcp->flags & TCB_INUSE) == 0) {
1544 memset(tcp, 0, sizeof(*tcp));
1546 tcp->flags = TCB_INUSE;
1547 tcp->outf = outf; /* Initialise to current out file */
1548 #if SUPPORTED_PERSONALITIES > 1
1549 tcp->currpers = current_personality;
1553 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
1554 if (command_options_parsed)
1559 error_msg_and_die("bug in alloc_tcb");
1570 for (i = 0; i < tcbtabsize; i++) {
1571 struct tcb *tcp = tcbtab[i];
1572 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1580 droptcb(struct tcb *tcp)
1587 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
1590 if (outfname && followfork >= 2) {
1591 if (tcp->curcol != 0)
1592 fprintf(tcp->outf, " <detached ...>\n");
1594 if (outf == tcp->outf)
1597 if (printing_tcp == tcp && tcp->curcol != 0)
1598 fprintf(tcp->outf, " <detached ...>\n");
1603 if (printing_tcp == tcp)
1604 printing_tcp = NULL;
1606 memset(tcp, 0, sizeof(*tcp));
1609 /* detach traced process; continue with sig
1610 * Never call DETACH twice on the same process as both unattached and
1611 * attached-unstopped processes give the same ESRCH. For unattached process we
1612 * would SIGSTOP it and wait for its SIGSTOP notification forever.
1615 detach(struct tcb *tcp)
1618 int status, sigstop_expected;
1620 if (tcp->flags & TCB_BPTSET)
1624 * Linux wrongly insists the child be stopped
1625 * before detaching. Arghh. We go through hoops
1626 * to make a clean break of things.
1629 #undef PTRACE_DETACH
1630 #define PTRACE_DETACH PTRACE_SUNDETACH
1634 sigstop_expected = 0;
1635 if (tcp->flags & TCB_ATTACHED) {
1637 * We attached but possibly didn't see the expected SIGSTOP.
1638 * We must catch exactly one as otherwise the detached process
1639 * would be left stopped (process state T).
1641 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1642 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1644 /* On a clear day, you can see forever. */
1646 else if (errno != ESRCH) {
1647 /* Shouldn't happen. */
1648 perror("detach: ptrace(PTRACE_DETACH, ...)");
1650 else if (my_tkill(tcp->pid, 0) < 0) {
1652 perror("detach: checking sanity");
1654 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
1656 perror("detach: stopping child");
1659 sigstop_expected = 1;
1662 if (sigstop_expected) {
1665 if (waitpid(tcp->pid, &status, __WALL) < 0) {
1666 if (errno == ECHILD) /* Already gone. */
1668 if (errno != EINVAL) {
1669 perror("detach: waiting");
1673 /* No __WALL here. */
1674 if (waitpid(tcp->pid, &status, 0) < 0) {
1675 if (errno != ECHILD) {
1676 perror("detach: waiting");
1680 /* If no processes, try clones. */
1681 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
1682 if (errno != ECHILD)
1683 perror("detach: waiting");
1686 #endif /* __WCLONE */
1691 if (!WIFSTOPPED(status)) {
1692 /* Au revoir, mon ami. */
1695 if (WSTOPSIG(status) == SIGSTOP) {
1696 ptrace_restart(PTRACE_DETACH, tcp, 0);
1699 error = ptrace_restart(PTRACE_CONT, tcp,
1700 WSTOPSIG(status) == syscall_trap_sig ? 0
1701 : WSTOPSIG(status));
1707 if (!qflag && (tcp->flags & TCB_ATTACHED))
1708 fprintf(stderr, "Process %u detached\n", tcp->pid);
1722 /* 'interrupted' is a volatile object, fetch it only once */
1723 fatal_sig = interrupted;
1725 fatal_sig = SIGTERM;
1727 for (i = 0; i < tcbtabsize; i++) {
1729 if (!(tcp->flags & TCB_INUSE))
1733 "cleanup: looking at pid %u\n", tcp->pid);
1734 if (tcp->flags & TCB_STRACE_CHILD) {
1735 kill(tcp->pid, SIGCONT);
1736 kill(tcp->pid, fatal_sig);
1754 struct rusage *rup = cflag ? &ru : NULL;
1756 static int wait4_options = __WALL;
1759 while (nprocs != 0) {
1770 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1772 pid = wait4(-1, &status, wait4_options, rup);
1773 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1774 /* this kernel does not support __WALL */
1775 wait4_options &= ~__WALL;
1776 pid = wait4(-1, &status, wait4_options, rup);
1778 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1779 /* most likely a "cloned" process */
1780 pid = wait4(-1, &status, __WCLONE, rup);
1782 perror_msg("wait4(__WCLONE) failed");
1786 pid = wait4(-1, &status, 0, rup);
1787 # endif /* __WALL */
1790 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1793 switch (wait_errno) {
1798 * We would like to verify this case
1799 * but sometimes a race in Solbourne's
1800 * version of SunOS sometimes reports
1801 * ECHILD before sending us SIGCHILD.
1810 if (pid == popen_pid) {
1811 if (WIFEXITED(status) || WIFSIGNALED(status))
1816 event = ((unsigned)status >> 16);
1818 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1819 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
1821 if (WIFSIGNALED(status))
1823 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1824 WCOREDUMP(status) ? "core," : "",
1825 signame(WTERMSIG(status)));
1827 sprintf(buf, "WIFSIGNALED,sig=%s",
1828 signame(WTERMSIG(status)));
1830 if (WIFEXITED(status))
1831 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1832 if (WIFSTOPPED(status))
1833 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1835 if (WIFCONTINUED(status))
1836 strcpy(buf, "WIFCONTINUED");
1840 static const char *const event_names[] = {
1841 [PTRACE_EVENT_CLONE] = "CLONE",
1842 [PTRACE_EVENT_FORK] = "FORK",
1843 [PTRACE_EVENT_VFORK] = "VFORK",
1844 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1845 [PTRACE_EVENT_EXEC] = "EXEC",
1846 [PTRACE_EVENT_EXIT] = "EXIT",
1849 if (event < ARRAY_SIZE(event_names))
1850 e = event_names[event];
1852 sprintf(buf, "?? (%u)", event);
1855 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1857 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
1860 /* Look up 'pid' in our table. */
1863 /* Under Linux, execve changes pid to thread leader's pid,
1864 * and we see this changed pid on EVENT_EXEC and later,
1865 * execve sysexit. Leader "disappears" without exit
1866 * notification. Let user know that, drop leader's tcb,
1867 * and fix up pid in execve thread's tcb.
1868 * Effectively, execve thread's tcb replaces leader's tcb.
1870 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1871 * on exit syscall) in multithreaded programs exactly
1872 * in order to handle this case.
1874 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1875 * On 2.6 and earlier, it can return garbage.
1877 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
1879 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1883 struct tcb *execve_thread = pid2tcb(old_pid);
1886 curcol = tcp->curcol;
1887 if (execve_thread) {
1888 if (execve_thread->curcol != 0) {
1890 * One case we are here is -ff:
1891 * try "strace -oLOG -ff test/threaded_execve"
1893 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1894 execve_thread->curcol = 0;
1896 /* swap output FILEs (needed for -ff) */
1897 tcp->outf = execve_thread->outf;
1898 tcp->curcol = execve_thread->curcol;
1899 execve_thread->outf = outf;
1900 execve_thread->curcol = curcol;
1904 tcp = execve_thread;
1907 tcp->flags |= TCB_REPRINT;
1910 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1917 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1918 if (!skip_startup_execve)
1920 /* This was initial execve for "strace PROG". Skip. */
1921 skip_startup_execve = 0;
1926 /* This is needed to go with the CLONE_PTRACE
1927 changes in process.c/util.c: we might see
1928 the child's initial trap before we see the
1929 parent return from the clone syscall.
1930 Leave the child suspended until the parent
1931 returns from its system call. Only then
1932 will we have the association of parent and
1933 child so that we know how to do clearbpt
1935 tcp = alloctcb(pid);
1936 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1938 fprintf(stderr, "Process %d attached\n",
1942 /* This can happen if a clone call used
1943 CLONE_PTRACE itself. */
1945 if (WIFSTOPPED(status))
1946 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
1947 error_msg_and_die("Unknown pid: %u", pid);
1951 /* Set current output file */
1953 curcol = tcp->curcol;
1956 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1957 tcp->stime = ru.ru_stime;
1960 if (WIFSIGNALED(status)) {
1961 if (pid == strace_child)
1962 exit_code = 0x100 | WTERMSIG(status);
1963 if (cflag != CFLAG_ONLY_STATS
1964 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1967 tprintf("+++ killed by %s %s+++\n",
1968 signame(WTERMSIG(status)),
1969 WCOREDUMP(status) ? "(core dumped) " : "");
1971 tprintf("+++ killed by %s +++\n",
1972 signame(WTERMSIG(status)));
1979 if (WIFEXITED(status)) {
1980 if (pid == strace_child)
1981 exit_code = WEXITSTATUS(status);
1982 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1984 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
1990 if (!WIFSTOPPED(status)) {
1991 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1996 /* Is this the very first time we see this tracee stopped? */
1997 if (tcp->flags & TCB_STARTUP) {
1999 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
2000 tcp->flags &= ~TCB_STARTUP;
2001 if (tcp->flags & TCB_BPTSET) {
2003 * One example is a breakpoint inherited from
2004 * parent through fork().
2006 if (clearbpt(tcp) < 0) {
2013 if (ptrace_setoptions) {
2015 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2016 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2017 if (errno != ESRCH) {
2018 /* Should never happen, really */
2019 perror_msg_and_die("PTRACE_SETOPTIONS");
2025 sig = WSTOPSIG(status);
2030 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
2032 * PTRACE_INTERRUPT-stop or group-stop.
2033 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2045 goto restart_tracee_with_sig_0;
2048 /* Is this post-attach SIGSTOP?
2049 * Interestingly, the process may stop
2050 * with STOPSIG equal to some other signal
2051 * than SIGSTOP if we happend to attach
2052 * just before the process takes a signal.
2054 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2056 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2057 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
2058 goto restart_tracee_with_sig_0;
2061 if (sig != syscall_trap_sig) {
2064 /* Nonzero (true) if tracee is stopped by signal
2065 * (as opposed to "tracee received signal").
2067 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
2071 if (cflag != CFLAG_ONLY_STATS
2072 && (qual_flags[sig] & QUAL_SIGNAL)) {
2073 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
2077 upeek(tcp, PT_CR_IPSR, &psr);
2078 upeek(tcp, PT_CR_IIP, &pc);
2081 pc += (psr >> PSR_RI) & 0x3;
2082 # define PC_FORMAT_STR " @ %lx"
2083 # define PC_FORMAT_ARG , pc
2085 # define PC_FORMAT_STR ""
2086 # define PC_FORMAT_ARG /* nothing */
2090 tprintf("--- %s ", signame(sig));
2091 printsiginfo(&si, verbose(tcp));
2092 tprintf(PC_FORMAT_STR " ---\n"
2095 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
2102 /* It's signal-delivery-stop. Inject the signal */
2103 goto restart_tracee;
2105 /* It's group-stop */
2109 * This ends ptrace-stop, but does *not* end group-stop.
2110 * This makes stopping signals work properly on straced process
2111 * (that is, process really stops. It used to continue to run).
2113 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2117 tcp->curcol = curcol;
2120 /* We don't have PTRACE_LISTEN support... */
2122 goto restart_tracee;
2125 /* We handled quick cases, we are permitted to interrupt now. */
2129 /* This should be syscall entry or exit.
2130 * (Or it still can be that pesky post-execve SIGTRAP!)
2133 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2134 /* ptrace() failed in trace_syscall() with ESRCH.
2135 * Likely a result of process disappearing mid-flight.
2136 * Observed case: exit_group() terminating
2137 * all processes in thread group.
2138 * We assume that ptrace error was caused by process death.
2139 * We used to detach(tcp) here, but since we no longer
2140 * implement "detach before death" policy/hack,
2141 * we can let this process to report its death to us
2142 * normally, via WIFEXITED or WIFSIGNALED wait status.
2144 tcp->curcol = curcol;
2147 restart_tracee_with_sig_0:
2150 /* Remember current print column before continuing. */
2151 tcp->curcol = curcol;
2152 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2161 main(int argc, char *argv[])
2165 /* Run main tracing loop */
2171 if (exit_code > 0xff) {
2172 /* Avoid potential core file clobbering. */
2173 struct rlimit rlim = {0, 0};
2174 setrlimit(RLIMIT_CORE, &rlim);
2176 /* Child was killed by a signal, mimic that. */
2178 signal(exit_code, SIG_DFL);
2180 /* Paranoia - what if this signal is not fatal?
2181 Exit with 128 + signo then. */