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.
35 #include <sys/types.h>
39 #include <sys/param.h>
41 #include <sys/resource.h>
48 #include <sys/utsname.h>
50 # include <asm/unistd.h>
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 # include <asm/ptrace_offsets.h>
65 extern char **environ;
69 int debug = 0, followfork = 0;
70 unsigned int ptrace_setoptions = 0;
71 /* Which WSTOPSIG(status) value marks syscall traps? */
72 static unsigned int syscall_trap_sig = SIGTRAP;
73 int dtime = 0, xflag = 0, qflag = 0;
74 cflag_t cflag = CFLAG_NONE;
75 static int iflag = 0, rflag = 0, tflag = 0;
76 static int 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 int not_failing_only = 0;
116 /* Show path associated with fd arguments */
117 int show_fd_path = 0;
119 /* are we filtering traces based on paths? */
120 int tracing_paths = 0;
122 static int exit_code = 0;
123 static int strace_child = 0;
124 static int strace_tracer_pid = 0;
126 static char *username = NULL;
127 static uid_t run_uid;
128 static gid_t run_gid;
130 int max_strlen = DEFAULT_STRLEN;
131 static int acolumn = DEFAULT_ACOLUMN;
132 static char *acolumn_spaces;
133 static char *outfname = NULL;
135 struct tcb *printing_tcp = NULL;
137 static struct tcb **tcbtab;
138 static unsigned int nprocs, tcbtabsize;
139 static const char *progname;
141 static char *os_release; /* from uname() */
143 static int detach(struct tcb *tcp);
144 static int trace(void);
145 static void cleanup(void);
146 static void interrupt(int sig);
147 static sigset_t empty_set, blocked_set;
149 #ifdef HAVE_SIG_ATOMIC_T
150 static volatile sig_atomic_t interrupted;
152 static volatile int interrupted;
156 usage(FILE *ofp, int exitval)
159 usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
160 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
161 [-P path] [PROG [ARGS]]\n\
162 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
164 -c -- count time, calls, and errors for each syscall and report summary\n\
165 -C -- like -c but also print regular output while processes are running\n\
166 -D -- run tracer process as a detached grandchild, not as parent\n\
167 -f -- follow forks, -ff -- with output into separate files\n\
168 -F -- attempt to follow vforks\n\
169 -i -- print instruction pointer at time of syscall\n\
171 1: no signals are blocked\n\
172 2: fatal signals are blocked while decoding syscall (default)\n\
173 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
174 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
175 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
176 -q -- suppress messages about attaching, detaching, etc.\n\
177 -r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
178 -T -- print time spent in each syscall\n\
179 -v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
180 -x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
181 -y -- print paths associated with file descriptor arguments\n\
182 -h -- print help message\n\
183 -V -- print version\n\
184 -a column -- alignment COLUMN for printing syscall results (default %d)\n\
185 -e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
186 options: trace, abbrev, verbose, raw, signal, read, or write\n\
187 -o file -- send trace output to FILE instead of stderr\n\
188 -O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
189 -p pid -- trace process with process id PID, may be repeated\n\
190 -s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
191 -S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
192 -u username -- run command as username handling setuid and/or setgid\n\
193 -E var=val -- put var=val in the environment for command\n\
194 -E var -- remove var from the environment for command\n\
195 -P path -- trace accesses to path\n\
196 " /* this is broken, so don't document it
197 -z -- print only succeeding syscalls\n\
199 , DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
203 static void die(void) __attribute__ ((noreturn));
204 static void die(void)
206 if (strace_tracer_pid == getpid()) {
213 static void verror_msg(int err_no, const char *fmt, va_list p)
219 /* We want to print entire message with single fprintf to ensure
220 * message integrity if stderr is shared with other programs.
221 * Thus we use vasprintf + single fprintf.
224 if (vasprintf(&msg, fmt, p) >= 0) {
226 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
228 fprintf(stderr, "%s: %s\n", progname, msg);
231 /* malloc in vasprintf failed, try it without malloc */
232 fprintf(stderr, "%s: ", progname);
233 vfprintf(stderr, fmt, p);
235 fprintf(stderr, ": %s\n", strerror(err_no));
239 /* We don't switch stderr to buffered, thus fprintf(stderr)
240 * always flushes its output and this is not necessary: */
241 /* fflush(stderr); */
244 void error_msg(const char *fmt, ...)
248 verror_msg(0, fmt, p);
252 void error_msg_and_die(const char *fmt, ...)
256 verror_msg(0, fmt, p);
260 void perror_msg(const char *fmt, ...)
264 verror_msg(errno, fmt, p);
268 void perror_msg_and_die(const char *fmt, ...)
272 verror_msg(errno, fmt, p);
276 void die_out_of_memory(void)
278 static bool recursed = 0;
282 error_msg_and_die("Out of memory");
285 /* Glue for systems without a MMU that cannot provide fork() */
287 # define strace_vforked 0
289 # define strace_vforked 1
290 # define fork() vfork()
295 ptrace_attach_or_seize(int pid)
299 return ptrace(PTRACE_ATTACH, pid, 0, 0);
300 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
303 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
307 # define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
311 set_cloexec_flag(int fd)
315 flags = fcntl(fd, F_GETFD);
317 /* Can happen only if fd is bad.
318 * Should never happen: if it does, we have a bug
319 * in the caller. Therefore we just abort
320 * instead of propagating the error.
322 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
325 newflags = flags | FD_CLOEXEC;
326 if (flags == newflags)
329 fcntl(fd, F_SETFD, newflags); /* never fails */
333 * When strace is setuid executable, we have to swap uids
334 * before and after filesystem and process management operations.
339 int euid = geteuid(), uid = getuid();
341 if (euid != uid && setreuid(euid, uid) < 0) {
342 perror_msg_and_die("setreuid");
347 # define fopen_for_output fopen64
349 # define fopen_for_output fopen
353 strace_fopen(const char *path)
358 fp = fopen_for_output(path, "w");
360 perror_msg_and_die("Can't fopen '%s'", path);
362 set_cloexec_flag(fileno(fp));
366 static int popen_pid = 0;
369 # define _PATH_BSHELL "/bin/sh"
373 * We cannot use standard popen(3) here because we have to distinguish
374 * popen child process from other processes we trace, and standard popen(3)
375 * does not export its child's pid.
378 strace_popen(const char *command)
385 perror_msg_and_die("pipe");
387 set_cloexec_flag(fds[1]); /* never fails */
391 perror_msg_and_die("vfork");
393 if (popen_pid == 0) {
398 perror_msg_and_die("dup2");
401 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
402 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
408 fp = fdopen(fds[1], "w");
415 newoutf(struct tcb *tcp)
417 if (outfname && followfork > 1) {
418 char name[520 + sizeof(int) * 3];
419 sprintf(name, "%.512s.%u", outfname, tcp->pid);
420 tcp->outf = strace_fopen(name);
424 static void process_opt_p_list(char *opt)
428 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
429 * pidof uses space as delim, pgrep uses newline. :(
433 char *delim = opt + strcspn(opt, ", \n\t");
437 pid = atoi(opt); /* TODO: stricter parsing of the number? */
439 error_msg("Invalid process id: '%s'", opt);
443 if (pid == strace_tracer_pid) {
444 error_msg("I'm sorry, I can't let you do that, Dave.");
449 tcp = alloc_tcb(pid, 0);
450 tcp->flags |= TCB_ATTACHED;
464 * Block user interruptions as we would leave the traced
465 * process stopped (process state T) if we would terminate in
466 * between PTRACE_ATTACH and wait4() on SIGSTOP.
467 * We rely on cleanup() from this point on.
470 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
472 if (daemonized_tracer) {
475 perror_msg_and_die("fork");
477 if (pid) { /* parent */
479 * Wait for grandchild to attach to straced process
480 * (grandparent). Grandchild SIGKILLs us after it attached.
481 * Grandparent's wait() is unblocked by our death,
482 * it proceeds to exec the straced program.
485 _exit(0); /* paranoia */
488 /* We will be the tracer process. Remember our new pid: */
489 strace_tracer_pid = getpid();
492 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
495 /* Is this a process we should attach to, but not yet attached? */
496 if ((tcp->flags & (TCB_ATTACHED | TCB_STARTUP)) != TCB_ATTACHED)
499 /* Reinitialize the output since it may have changed */
503 if (followfork && !daemonized_tracer) {
504 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
507 sprintf(procdir, "/proc/%d/task", tcp->pid);
508 dir = opendir(procdir);
510 unsigned int ntid = 0, nerr = 0;
513 while ((de = readdir(dir)) != NULL) {
517 if (de->d_fileno == 0)
519 tid = atoi(de->d_name);
523 if (ptrace_attach_or_seize(tid) < 0) {
526 fprintf(stderr, "attach to pid %d failed\n", tid);
530 fprintf(stderr, "attach to pid %d succeeded\n", tid);
533 cur_tcp = alloctcb(tid);
534 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
538 sigprocmask(SIG_SETMASK, &empty_set, NULL);
541 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
545 perror("attach: ptrace(PTRACE_ATTACH, ...)");
550 fprintf(stderr, ntid > 1
551 ? "Process %u attached with %u threads - interrupt to quit\n"
552 : "Process %u attached - interrupt to quit\n",
555 if (!(tcp->flags & TCB_STARTUP)) {
556 /* -p PID, we failed to attach to PID itself
557 * but did attach to some of its sibling threads.
563 } /* if (opendir worked) */
565 if (ptrace_attach_or_seize(tcp->pid) < 0) {
566 perror("attach: ptrace(PTRACE_ATTACH, ...)");
570 tcp->flags |= TCB_STARTUP | post_attach_sigstop;
572 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
574 if (daemonized_tracer) {
576 * It is our grandparent we trace, not a -p PID.
577 * Don't want to just detach on exit, so...
579 tcp->flags &= ~TCB_ATTACHED;
581 * Make parent go away.
582 * Also makes grandparent's wait() unblock.
584 kill(getppid(), SIGKILL);
589 "Process %u attached - interrupt to quit\n",
591 } /* for each tcbtab[] */
595 sigprocmask(SIG_SETMASK, &empty_set, NULL);
599 startup_child(char **argv)
602 const char *filename;
603 char pathname[MAXPATHLEN];
608 if (strchr(filename, '/')) {
609 if (strlen(filename) > sizeof pathname - 1) {
610 errno = ENAMETOOLONG;
611 perror_msg_and_die("exec");
613 strcpy(pathname, filename);
615 #ifdef USE_DEBUGGING_EXEC
617 * Debuggers customarily check the current directory
618 * first regardless of the path but doing that gives
619 * security geeks a panic attack.
621 else if (stat(filename, &statbuf) == 0)
622 strcpy(pathname, filename);
623 #endif /* USE_DEBUGGING_EXEC */
628 for (path = getenv("PATH"); path && *path; path += m) {
629 const char *colon = strchr(path, ':');
635 m = n = strlen(path);
637 if (!getcwd(pathname, MAXPATHLEN))
639 len = strlen(pathname);
641 else if (n > sizeof pathname - 1)
644 strncpy(pathname, path, n);
647 if (len && pathname[len - 1] != '/')
648 pathname[len++] = '/';
649 strcpy(pathname + len, filename);
650 if (stat(pathname, &statbuf) == 0 &&
651 /* Accept only regular files
652 with some execute bits set.
653 XXX not perfect, might still fail */
654 S_ISREG(statbuf.st_mode) &&
655 (statbuf.st_mode & 0111))
659 if (stat(pathname, &statbuf) < 0) {
660 perror_msg_and_die("Can't stat '%s'", filename);
662 strace_child = pid = fork();
664 perror_msg_and_die("fork");
666 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
667 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
672 if (!daemonized_tracer && !use_seize) {
673 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
674 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
678 if (username != NULL) {
679 uid_t run_euid = run_uid;
680 gid_t run_egid = run_gid;
682 if (statbuf.st_mode & S_ISUID)
683 run_euid = statbuf.st_uid;
684 if (statbuf.st_mode & S_ISGID)
685 run_egid = statbuf.st_gid;
687 * It is important to set groups before we
688 * lose privileges on setuid.
690 if (initgroups(username, run_gid) < 0) {
691 perror_msg_and_die("initgroups");
693 if (setregid(run_gid, run_egid) < 0) {
694 perror_msg_and_die("setregid");
696 if (setreuid(run_uid, run_euid) < 0) {
697 perror_msg_and_die("setreuid");
700 else if (geteuid() != 0)
701 setreuid(run_uid, run_uid);
703 if (!daemonized_tracer) {
705 * Induce a ptrace stop. Tracer (our parent)
706 * will resume us with PTRACE_SYSCALL and display
707 * the immediately following execve syscall.
708 * Can't do this on NOMMU systems, we are after
709 * vfork: parent is blocked, stopping would deadlock.
714 struct sigaction sv_sigchld;
715 sigaction(SIGCHLD, NULL, &sv_sigchld);
717 * Make sure it is not SIG_IGN, otherwise wait
720 signal(SIGCHLD, SIG_DFL);
722 * Wait for grandchild to attach to us.
723 * It kills child after that, and wait() unblocks.
728 sigaction(SIGCHLD, &sv_sigchld, NULL);
731 execv(pathname, argv);
732 perror_msg_and_die("exec");
735 /* We are the tracer */
737 if (!daemonized_tracer) {
739 /* child did PTRACE_TRACEME, nothing to do in parent */
741 if (!strace_vforked) {
742 /* Wait until child stopped itself */
744 while (waitpid(pid, &status, WSTOPPED) < 0) {
747 perror_msg_and_die("waitpid");
749 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
751 perror_msg_and_die("Unexpected wait status %x", status);
754 /* Else: vforked case, we have no way to sync.
755 * Just attach to it as soon as possible.
756 * This means that we may miss a few first syscalls...
759 if (ptrace_attach_or_seize(pid)) {
761 perror_msg_and_die("Can't attach to %d", pid);
768 tcp->flags |= TCB_STARTUP | post_attach_sigstop;
770 tcp->flags |= TCB_STARTUP;
773 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
774 strace_tracer_pid = getpid();
775 /* The tracee is our parent: */
778 /* We want subsequent startup_attach() to attach to it: */
779 tcp->flags |= TCB_ATTACHED;
783 static void kill_save_errno(pid_t pid, int sig)
785 int saved_errno = errno;
787 (void) kill(pid, sig);
792 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
793 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
794 * and then see which options are supported by the kernel.
797 test_ptrace_setoptions_followfork(void)
799 int pid, expected_grandchild = 0, found_grandchild = 0;
800 const unsigned int test_options = PTRACE_O_TRACECLONE |
806 perror_msg_and_die("fork");
809 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
810 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
812 kill_save_errno(pid, SIGSTOP);
814 perror_msg_and_die("fork");
819 int status, tracee_pid;
822 tracee_pid = wait(&status);
823 if (tracee_pid <= 0) {
828 kill_save_errno(pid, SIGKILL);
829 perror_msg_and_die("%s: unexpected wait result %d",
830 __func__, tracee_pid);
832 if (WIFEXITED(status)) {
833 if (WEXITSTATUS(status)) {
834 if (tracee_pid != pid)
835 kill_save_errno(pid, SIGKILL);
836 error_msg_and_die("%s: unexpected exit status %u",
837 __func__, WEXITSTATUS(status));
841 if (WIFSIGNALED(status)) {
842 if (tracee_pid != pid)
843 kill_save_errno(pid, SIGKILL);
844 error_msg_and_die("%s: unexpected signal %u",
845 __func__, WTERMSIG(status));
847 if (!WIFSTOPPED(status)) {
848 if (tracee_pid != pid)
849 kill_save_errno(tracee_pid, SIGKILL);
850 kill_save_errno(pid, SIGKILL);
851 error_msg_and_die("%s: unexpected wait status %x",
854 if (tracee_pid != pid) {
855 found_grandchild = tracee_pid;
856 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
857 kill_save_errno(tracee_pid, SIGKILL);
858 kill_save_errno(pid, SIGKILL);
859 perror_msg_and_die("PTRACE_CONT doesn't work");
863 switch (WSTOPSIG(status)) {
865 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
866 && errno != EINVAL && errno != EIO)
867 perror_msg("PTRACE_SETOPTIONS");
870 if (status >> 16 == PTRACE_EVENT_FORK) {
873 if (ptrace(PTRACE_GETEVENTMSG, pid,
874 NULL, (long) &msg) == 0)
875 expected_grandchild = msg;
879 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
880 kill_save_errno(pid, SIGKILL);
881 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
884 if (expected_grandchild && expected_grandchild == found_grandchild) {
885 ptrace_setoptions |= test_options;
887 fprintf(stderr, "ptrace_setoptions = %#x\n",
891 error_msg("Test for PTRACE_O_TRACECLONE failed, "
892 "giving up using this feature.");
896 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
897 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
898 * and then see whether it will stop with (SIGTRAP | 0x80).
900 * Use of this option enables correct handling of user-generated SIGTRAPs,
901 * and SIGTRAPs generated by special instructions such as int3 on x86:
902 * _start: .globl _start
907 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
910 test_ptrace_setoptions_for_all(void)
912 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
919 perror_msg_and_die("fork");
923 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
924 /* Note: exits with exitcode 1 */
925 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
928 _exit(0); /* parent should see entry into this syscall */
932 int status, tracee_pid;
935 tracee_pid = wait(&status);
936 if (tracee_pid <= 0) {
939 kill_save_errno(pid, SIGKILL);
940 perror_msg_and_die("%s: unexpected wait result %d",
941 __func__, tracee_pid);
943 if (WIFEXITED(status)) {
944 if (WEXITSTATUS(status) == 0)
946 error_msg_and_die("%s: unexpected exit status %u",
947 __func__, WEXITSTATUS(status));
949 if (WIFSIGNALED(status)) {
950 error_msg_and_die("%s: unexpected signal %u",
951 __func__, WTERMSIG(status));
953 if (!WIFSTOPPED(status)) {
955 error_msg_and_die("%s: unexpected wait status %x",
958 if (WSTOPSIG(status) == SIGSTOP) {
960 * We don't check "options aren't accepted" error.
961 * If it happens, we'll never get (SIGTRAP | 0x80),
962 * and thus will decide to not use the option.
963 * IOW: the outcome of the test will be correct.
965 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
966 && errno != EINVAL && errno != EIO)
967 perror_msg("PTRACE_SETOPTIONS");
969 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
972 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
973 kill_save_errno(pid, SIGKILL);
974 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
979 syscall_trap_sig = (SIGTRAP | 0x80);
980 ptrace_setoptions |= test_options;
982 fprintf(stderr, "ptrace_setoptions = %#x\n",
987 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
988 "giving up using this feature.");
993 test_ptrace_seize(void)
999 perror_msg_and_die("fork");
1006 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1007 * attaching tracee continues to run unless a trap condition occurs.
1008 * PTRACE_SEIZE doesn't affect signal or group stop state.
1010 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1011 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1013 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1019 int status, tracee_pid;
1022 tracee_pid = waitpid(pid, &status, 0);
1023 if (tracee_pid <= 0) {
1026 perror_msg_and_die("%s: unexpected wait result %d",
1027 __func__, tracee_pid);
1029 if (WIFSIGNALED(status)) {
1032 error_msg_and_die("%s: unexpected wait status %x",
1036 # else /* !USE_SEIZE */
1037 # define test_ptrace_seize() ((void)0)
1040 /* Noinline: don't want main to have struct utsname permanently on stack */
1041 static void __attribute__ ((noinline))
1042 get_os_release(void)
1046 perror_msg_and_die("uname");
1047 os_release = strdup(u.release);
1049 die_out_of_memory();
1053 main(int argc, char *argv[])
1058 struct sigaction sa;
1060 progname = argv[0] ? argv[0] : "strace";
1062 strace_tracer_pid = getpid();
1066 /* Allocate the initial tcbtab. */
1067 tcbtabsize = argc; /* Surely enough for all -p args. */
1068 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
1070 die_out_of_memory();
1071 tcp = calloc(tcbtabsize, sizeof(*tcp));
1073 die_out_of_memory();
1074 for (c = 0; c < tcbtabsize; c++)
1078 set_sortby(DEFAULT_SORTBY);
1079 set_personality(DEFAULT_PERSONALITY);
1080 qualify("trace=all");
1081 qualify("abbrev=all");
1082 qualify("verbose=all");
1083 qualify("signal=all");
1084 while ((c = getopt(argc, argv,
1087 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
1090 if (cflag == CFLAG_BOTH) {
1091 error_msg_and_die("-c and -C are mutually exclusive options");
1093 cflag = CFLAG_ONLY_STATS;
1096 if (cflag == CFLAG_ONLY_STATS) {
1097 error_msg_and_die("-c and -C are mutually exclusive options");
1105 daemonized_tracer = 1;
1139 qualify("abbrev=none");
1142 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
1146 not_failing_only = 1;
1149 acolumn = atoi(optarg);
1151 error_msg_and_die("Bad column width '%s'", optarg);
1157 outfname = strdup(optarg);
1160 set_overhead(atoi(optarg));
1163 process_opt_p_list(optarg);
1167 if (pathtrace_select(optarg)) {
1168 error_msg_and_die("Failed to select path '%s'", optarg);
1172 max_strlen = atoi(optarg);
1173 if (max_strlen < 0) {
1174 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1181 username = strdup(optarg);
1184 if (putenv(optarg) < 0)
1185 die_out_of_memory();
1188 opt_intr = atoi(optarg);
1189 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1190 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1199 /* argc -= optind; - no need, argc is not used below */
1201 acolumn_spaces = malloc(acolumn + 1);
1202 if (!acolumn_spaces)
1203 die_out_of_memory();
1204 memset(acolumn_spaces, ' ', acolumn);
1205 acolumn_spaces[acolumn] = '\0';
1207 /* Must have PROG [ARGS], or -p PID. Not both. */
1208 if (!argv[0] == !nprocs)
1211 if (nprocs != 0 && daemonized_tracer) {
1212 error_msg_and_die("-D and -p are mutually exclusive options");
1218 if (followfork > 1 && cflag) {
1219 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
1222 /* See if they want to run as another user. */
1223 if (username != NULL) {
1224 struct passwd *pent;
1226 if (getuid() != 0 || geteuid() != 0) {
1227 error_msg_and_die("You must be root to use the -u option");
1229 pent = getpwnam(username);
1231 error_msg_and_die("Cannot find user '%s'", username);
1233 run_uid = pent->pw_uid;
1234 run_gid = pent->pw_gid;
1242 test_ptrace_setoptions_followfork();
1243 test_ptrace_setoptions_for_all();
1244 test_ptrace_seize();
1246 /* Check if they want to redirect the output. */
1248 /* See if they want to pipe the output. */
1249 if (outfname[0] == '|' || outfname[0] == '!') {
1251 * We can't do the <outfname>.PID funny business
1252 * when using popen, so prohibit it.
1255 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1256 outf = strace_popen(outfname + 1);
1258 else if (followfork <= 1)
1259 outf = strace_fopen(outfname);
1262 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1263 char *buf = malloc(BUFSIZ);
1265 die_out_of_memory();
1266 setvbuf(outf, buf, _IOLBF, BUFSIZ);
1268 if (outfname && argv[0]) {
1270 opt_intr = INTR_NEVER;
1274 opt_intr = INTR_WHILE_WAIT;
1276 /* argv[0] -pPID -oFILE Default interactive setting
1277 * yes 0 0 INTR_WHILE_WAIT
1278 * no 1 0 INTR_WHILE_WAIT
1279 * yes 0 1 INTR_NEVER
1280 * no 1 1 INTR_WHILE_WAIT
1283 /* STARTUP_CHILD must be called before the signal handlers get
1284 installed below as they are inherited into the spawned process.
1285 Also we do not need to be protected by them as during interruption
1286 in the STARTUP_CHILD mode we kill the spawned process anyway. */
1288 startup_child(argv);
1290 sigemptyset(&empty_set);
1291 sigemptyset(&blocked_set);
1292 sa.sa_handler = SIG_IGN;
1293 sigemptyset(&sa.sa_mask);
1295 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1296 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1297 if (opt_intr != INTR_ANYWHERE) {
1298 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1299 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1301 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1302 * fatal signals are blocked while syscall stop is processed,
1303 * and acted on in between, when waiting for new syscall stops.
1304 * In non-interactive mode, signals are ignored.
1306 if (opt_intr == INTR_WHILE_WAIT) {
1307 sigaddset(&blocked_set, SIGHUP);
1308 sigaddset(&blocked_set, SIGINT);
1309 sigaddset(&blocked_set, SIGQUIT);
1310 sigaddset(&blocked_set, SIGPIPE);
1311 sigaddset(&blocked_set, SIGTERM);
1312 sa.sa_handler = interrupt;
1314 /* SIG_IGN, or set handler for these */
1315 sigaction(SIGHUP, &sa, NULL);
1316 sigaction(SIGINT, &sa, NULL);
1317 sigaction(SIGQUIT, &sa, NULL);
1318 sigaction(SIGPIPE, &sa, NULL);
1319 sigaction(SIGTERM, &sa, NULL);
1321 /* Make sure SIGCHLD has the default action so that waitpid
1322 definitely works without losing track of children. The user
1323 should not have given us a bogus state to inherit, but he might
1324 have. Arguably we should detect SIG_IGN here and pass it on
1325 to children, but probably noone really needs that. */
1326 sa.sa_handler = SIG_DFL;
1327 sigaction(SIGCHLD, &sa, NULL);
1329 if (nprocs != 0 || daemonized_tracer)
1332 /* Do we want pids printed in our -o OUTFILE?
1333 * -ff: no (every pid has its own file); or
1334 * -f: yes (there can be more pids in the future); or
1335 * -p PID1,PID2: yes (there are already more than one pid)
1337 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
1344 if (exit_code > 0xff) {
1345 /* Avoid potential core file clobbering. */
1346 struct rlimit rlim = {0, 0};
1347 setrlimit(RLIMIT_CORE, &rlim);
1349 /* Child was killed by a signal, mimic that. */
1351 signal(exit_code, SIG_DFL);
1353 /* Paranoia - what if this signal is not fatal?
1354 Exit with 128 + signo then. */
1363 /* Allocate some more TCBs and expand the table.
1364 We don't want to relocate the TCBs because our
1365 callers have pointers and it would be a pain.
1366 So tcbtab is a table of pointers. Since we never
1367 free the TCBs, we allocate a single chunk of many. */
1369 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1370 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
1371 if (!newtab || !newtcbs)
1372 die_out_of_memory();
1375 while (i < tcbtabsize)
1376 tcbtab[i++] = newtcbs++;
1380 alloc_tcb(int pid, int command_options_parsed)
1385 if (nprocs == tcbtabsize)
1388 for (i = 0; i < tcbtabsize; i++) {
1390 if ((tcp->flags & TCB_INUSE) == 0) {
1391 memset(tcp, 0, sizeof(*tcp));
1393 tcp->flags = TCB_INUSE;
1394 tcp->outf = outf; /* Initialise to current out file */
1395 #if SUPPORTED_PERSONALITIES > 1
1396 tcp->currpers = current_personality;
1400 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
1401 if (command_options_parsed)
1406 error_msg_and_die("bug in alloc_tcb");
1417 for (i = 0; i < tcbtabsize; i++) {
1418 struct tcb *tcp = tcbtab[i];
1419 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1427 droptcb(struct tcb *tcp)
1434 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
1436 if (outfname && followfork > 1 && tcp->outf)
1439 memset(tcp, 0, sizeof(*tcp));
1442 /* detach traced process; continue with sig
1443 Never call DETACH twice on the same process as both unattached and
1444 attached-unstopped processes give the same ESRCH. For unattached process we
1445 would SIGSTOP it and wait for its SIGSTOP notification forever. */
1448 detach(struct tcb *tcp)
1451 int status, catch_sigstop;
1453 if (tcp->flags & TCB_BPTSET)
1457 * Linux wrongly insists the child be stopped
1458 * before detaching. Arghh. We go through hoops
1459 * to make a clean break of things.
1462 #undef PTRACE_DETACH
1463 #define PTRACE_DETACH PTRACE_SUNDETACH
1466 * We attached but possibly didn't see the expected SIGSTOP.
1467 * We must catch exactly one as otherwise the detached process
1468 * would be left stopped (process state T).
1470 catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1471 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1473 /* On a clear day, you can see forever. */
1475 else if (errno != ESRCH) {
1476 /* Shouldn't happen. */
1477 perror("detach: ptrace(PTRACE_DETACH, ...)");
1479 else if (my_tkill(tcp->pid, 0) < 0) {
1481 perror("detach: checking sanity");
1483 else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) {
1485 perror("detach: stopping child");
1489 if (catch_sigstop) {
1492 if (wait4(tcp->pid, &status, __WALL, NULL) < 0) {
1493 if (errno == ECHILD) /* Already gone. */
1495 if (errno != EINVAL) {
1496 perror("detach: waiting");
1500 /* No __WALL here. */
1501 if (waitpid(tcp->pid, &status, 0) < 0) {
1502 if (errno != ECHILD) {
1503 perror("detach: waiting");
1507 /* If no processes, try clones. */
1508 if (wait4(tcp->pid, &status, __WCLONE,
1510 if (errno != ECHILD)
1511 perror("detach: waiting");
1514 #endif /* __WCLONE */
1519 if (!WIFSTOPPED(status)) {
1520 /* Au revoir, mon ami. */
1523 if (WSTOPSIG(status) == SIGSTOP) {
1524 ptrace_restart(PTRACE_DETACH, tcp, 0);
1527 error = ptrace_restart(PTRACE_CONT, tcp,
1528 WSTOPSIG(status) == syscall_trap_sig ? 0
1529 : WSTOPSIG(status));
1536 fprintf(stderr, "Process %u detached\n", tcp->pid);
1550 /* 'interrupted' is a volatile object, fetch it only once */
1551 fatal_sig = interrupted;
1553 fatal_sig = SIGTERM;
1555 for (i = 0; i < tcbtabsize; i++) {
1557 if (!(tcp->flags & TCB_INUSE))
1561 "cleanup: looking at pid %u\n", tcp->pid);
1563 (!outfname || followfork < 2 || printing_tcp == tcp)) {
1564 tprints(" <unfinished ...>\n");
1565 printing_tcp = NULL;
1567 if (tcp->flags & TCB_ATTACHED)
1570 kill(tcp->pid, SIGCONT);
1571 kill(tcp->pid, fatal_sig);
1584 #ifndef HAVE_STRERROR
1586 #if !HAVE_DECL_SYS_ERRLIST
1587 extern int sys_nerr;
1588 extern char *sys_errlist[];
1589 #endif /* HAVE_DECL_SYS_ERRLIST */
1592 strerror(int err_no)
1594 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
1596 if (err_no < 1 || err_no >= sys_nerr) {
1597 sprintf(buf, "Unknown error %d", err_no);
1600 return sys_errlist[err_no];
1603 #endif /* HAVE_STERRROR */
1605 #ifndef HAVE_STRSIGNAL
1607 #if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
1608 extern char *sys_siglist[];
1610 #if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1611 extern char *_sys_siglist[];
1617 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3];
1619 if (sig < 1 || sig >= NSIG) {
1620 sprintf(buf, "Unknown signal %d", sig);
1623 #ifdef HAVE__SYS_SIGLIST
1624 return _sys_siglist[sig];
1626 return sys_siglist[sig];
1630 #endif /* HAVE_STRSIGNAL */
1636 struct rusage *rup = cflag ? &ru : NULL;
1638 static int wait4_options = __WALL;
1641 while (nprocs != 0) {
1652 sigprocmask(SIG_SETMASK, &empty_set, NULL);
1654 pid = wait4(-1, &status, wait4_options, rup);
1655 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
1656 /* this kernel does not support __WALL */
1657 wait4_options &= ~__WALL;
1658 pid = wait4(-1, &status, wait4_options, rup);
1660 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
1661 /* most likely a "cloned" process */
1662 pid = wait4(-1, &status, __WCLONE, rup);
1664 perror_msg("wait4(__WCLONE) failed");
1668 pid = wait4(-1, &status, 0, rup);
1669 # endif /* __WALL */
1672 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1675 switch (wait_errno) {
1680 * We would like to verify this case
1681 * but sometimes a race in Solbourne's
1682 * version of SunOS sometimes reports
1683 * ECHILD before sending us SIGCHILD.
1692 if (pid == popen_pid) {
1693 if (WIFEXITED(status) || WIFSIGNALED(status))
1698 event = ((unsigned)status >> 16);
1700 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
1702 static const char *const event_names[] = {
1703 [PTRACE_EVENT_CLONE] = "CLONE",
1704 [PTRACE_EVENT_FORK] = "FORK",
1705 [PTRACE_EVENT_VFORK] = "VFORK",
1706 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1707 [PTRACE_EVENT_EXEC] = "EXEC",
1708 [PTRACE_EVENT_EXIT] = "EXIT",
1711 if (event < ARRAY_SIZE(event_names))
1712 e = event_names[event];
1714 sprintf(buf, "?? (%u)", event);
1717 fprintf(stderr, " PTRACE_EVENT_%s", e);
1720 if (WIFSIGNALED(status))
1722 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1723 WCOREDUMP(status) ? "core," : "",
1724 signame(WTERMSIG(status)));
1726 sprintf(buf, "WIFSIGNALED,sig=%s",
1727 signame(WTERMSIG(status)));
1729 if (WIFEXITED(status))
1730 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1731 if (WIFSTOPPED(status))
1732 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
1734 if (WIFCONTINUED(status))
1735 strcpy(buf, "WIFCONTINUED");
1737 fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf);
1740 /* Look up 'pid' in our table. */
1743 /* Under Linux, execve changes pid to thread leader's pid,
1744 * and we see this changed pid on EVENT_EXEC and later,
1745 * execve sysexit. Leader "disappears" without exit
1746 * notification. Let user know that, drop leader's tcb,
1747 * and fix up pid in execve thread's tcb.
1748 * Effectively, execve thread's tcb replaces leader's tcb.
1750 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1751 * on exit syscall) in multithreaded programs exactly
1752 * in order to handle this case.
1754 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1755 * On 2.6 and earlier, it can return garbage.
1757 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') {
1759 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1763 struct tcb *execve_thread = pid2tcb(old_pid);
1766 curcol = tcp->curcol;
1769 tprints(" <unfinished ...>\n");
1771 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1772 printing_tcp = NULL;
1775 if (execve_thread) {
1776 /* swap output FILEs (needed for -ff) */
1777 tcp->outf = execve_thread->outf;
1778 execve_thread->outf = outf;
1782 tcp = execve_thread;
1785 tcp->flags |= TCB_REPRINT;
1792 /* This is needed to go with the CLONE_PTRACE
1793 changes in process.c/util.c: we might see
1794 the child's initial trap before we see the
1795 parent return from the clone syscall.
1796 Leave the child suspended until the parent
1797 returns from its system call. Only then
1798 will we have the association of parent and
1799 child so that we know how to do clearbpt
1801 tcp = alloctcb(pid);
1802 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1804 fprintf(stderr, "Process %d attached\n",
1808 /* This can happen if a clone call used
1809 CLONE_PTRACE itself. */
1811 if (WIFSTOPPED(status))
1812 ptrace(PTRACE_CONT, pid, (char *) 1, 0);
1813 error_msg_and_die("Unknown pid: %u", pid);
1816 /* set current output file */
1818 curcol = tcp->curcol;
1820 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1821 tcp->stime = ru.ru_stime;
1824 if (WIFSIGNALED(status)) {
1825 if (pid == strace_child)
1826 exit_code = 0x100 | WTERMSIG(status);
1827 if (cflag != CFLAG_ONLY_STATS
1828 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1831 tprintf("+++ killed by %s %s+++\n",
1832 signame(WTERMSIG(status)),
1833 WCOREDUMP(status) ? "(core dumped) " : "");
1835 tprintf("+++ killed by %s +++\n",
1836 signame(WTERMSIG(status)));
1838 printing_tcp = NULL;
1844 if (WIFEXITED(status)) {
1845 if (pid == strace_child)
1846 exit_code = WEXITSTATUS(status);
1847 if (tcp == printing_tcp) {
1848 tprints(" <unfinished ...>\n");
1849 printing_tcp = NULL;
1851 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1853 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
1854 printing_tcp = NULL;
1860 if (!WIFSTOPPED(status)) {
1861 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1866 /* Is this the very first time we see this tracee stopped? */
1867 if (tcp->flags & TCB_STARTUP) {
1869 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
1870 tcp->flags &= ~TCB_STARTUP;
1871 if (tcp->flags & TCB_BPTSET) {
1873 * One example is a breakpoint inherited from
1874 * parent through fork().
1876 if (clearbpt(tcp) < 0) {
1883 if (ptrace_setoptions) {
1885 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
1886 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
1887 if (errno != ESRCH) {
1888 /* Should never happen, really */
1889 perror_msg_and_die("PTRACE_SETOPTIONS");
1895 sig = WSTOPSIG(status);
1900 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
1902 * PTRACE_INTERRUPT-stop or group-stop.
1903 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
1915 goto restart_tracee_with_sig_0;
1918 /* Is this post-attach SIGSTOP?
1919 * Interestingly, the process may stop
1920 * with STOPSIG equal to some other signal
1921 * than SIGSTOP if we happend to attach
1922 * just before the process takes a signal.
1924 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
1926 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
1927 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
1928 goto restart_tracee_with_sig_0;
1931 if (sig != syscall_trap_sig) {
1934 /* Nonzero (true) if tracee is stopped by signal
1935 * (as opposed to "tracee received signal").
1937 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
1941 if (cflag != CFLAG_ONLY_STATS
1942 && (qual_flags[sig] & QUAL_SIGNAL)) {
1943 #if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
1947 upeek(tcp, PT_CR_IPSR, &psr);
1948 upeek(tcp, PT_CR_IIP, &pc);
1951 pc += (psr >> PSR_RI) & 0x3;
1952 # define PC_FORMAT_STR " @ %lx"
1953 # define PC_FORMAT_ARG , pc
1955 # define PC_FORMAT_STR ""
1956 # define PC_FORMAT_ARG /* nothing */
1961 printsiginfo(&si, verbose(tcp));
1962 tprintf(" (%s)" PC_FORMAT_STR " ---\n",
1966 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n",
1970 printing_tcp = NULL;
1975 /* It's signal-delivery-stop. Inject the signal */
1976 goto restart_tracee;
1978 /* It's group-stop */
1982 * This ends ptrace-stop, but does *not* end group-stop.
1983 * This makes stopping signals work properly on straced process
1984 * (that is, process really stops. It used to continue to run).
1986 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
1992 /* We don't have PTRACE_LISTEN support... */
1994 goto restart_tracee;
1997 /* We handled quick cases, we are permitted to interrupt now. */
2001 /* This should be syscall entry or exit.
2002 * (Or it still can be that pesky post-execve SIGTRAP!)
2005 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2006 /* ptrace() failed in trace_syscall() with ESRCH.
2007 * Likely a result of process disappearing mid-flight.
2008 * Observed case: exit_group() terminating
2009 * all processes in thread group.
2011 if (tcp->flags & TCB_ATTACHED) {
2013 /* Do we have dangling line "syscall(param, param"?
2014 * Finish the line then.
2016 printing_tcp->flags |= TCB_REPRINT;
2017 tprints(" <unfinished ...>\n");
2018 printing_tcp = NULL;
2021 /* We assume that ptrace error was caused by process death.
2022 * We used to detach(tcp) here, but since we no longer
2023 * implement "detach before death" policy/hack,
2024 * we can let this process to report its death to us
2025 * normally, via WIFEXITED or WIFSIGNALED wait status.
2028 /* It's our real child (and we also trace it) */
2029 /* my_tkill(pid, SIGKILL); - why? */
2030 /* droptcb(tcp); - why? */
2034 restart_tracee_with_sig_0:
2037 /* Remember current print column before continuing. */
2038 tcp->curcol = curcol;
2039 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2048 tprintf(const char *fmt, ...)
2052 va_start(args, fmt);
2054 int n = vfprintf(outf, fmt, args);
2057 perror(outfname == NULL
2058 ? "<writing to pipe>" : outfname);
2066 tprints(const char *str)
2069 int n = fputs(str, outf);
2071 curcol += strlen(str);
2075 perror(outfname == NULL
2076 ? "<writing to pipe>" : outfname);
2081 printleader(struct tcb *tcp)
2084 if (printing_tcp->ptrace_errno) {
2085 if (printing_tcp->flags & TCB_INSYSCALL) {
2086 tprints(" <unavailable>) ");
2089 tprints("= ? <unavailable>\n");
2090 printing_tcp->ptrace_errno = 0;
2091 } else if (!outfname || followfork < 2 || printing_tcp == tcp) {
2092 printing_tcp->flags |= TCB_REPRINT;
2093 tprints(" <unfinished ...>\n");
2101 tprintf("%-5d ", tcp->pid);
2102 else if (nprocs > 1 && !outfname)
2103 tprintf("[pid %5u] ", tcp->pid);
2106 char str[sizeof("HH:MM:SS")];
2107 struct timeval tv, dtv;
2108 static struct timeval otv;
2110 gettimeofday(&tv, NULL);
2112 if (otv.tv_sec == 0)
2114 tv_sub(&dtv, &tv, &otv);
2115 tprintf("%6ld.%06ld ",
2116 (long) dtv.tv_sec, (long) dtv.tv_usec);
2119 else if (tflag > 2) {
2120 tprintf("%ld.%06ld ",
2121 (long) tv.tv_sec, (long) tv.tv_usec);
2124 time_t local = tv.tv_sec;
2125 strftime(str, sizeof(str), "%T", localtime(&local));
2127 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
2129 tprintf("%s ", str);
2139 if (curcol < acolumn)
2140 tprints(acolumn_spaces + curcol);