blob: fa786d769bef399bd6e680ab23e0d5cb0a01eb80 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
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>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
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.
18 *
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.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029 */
30
31#include "defs.h"
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020032#include <stdarg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000033#include <sys/param.h>
34#include <fcntl.h>
35#include <sys/resource.h>
36#include <sys/wait.h>
37#include <sys/stat.h>
38#include <pwd.h>
39#include <grp.h>
Roland McGrath70b08532004-04-09 00:25:21 +000040#include <dirent.h>
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +010041#include <sys/utsname.h>
Denys Vlasenko84703742012-02-25 02:38:52 +010042#if defined(IA64)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +000043# include <asm/ptrace_offsets.h>
44#endif
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010045/* In some libc, these aren't declared. Do it ourself: */
Denys Vlasenko96d5a762008-12-29 19:13:27 +000046extern char **environ;
Denys Vlasenko418d66a2009-01-17 01:52:54 +000047extern int optind;
48extern char *optarg;
Denys Vlasenko96d5a762008-12-29 19:13:27 +000049
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010050
51#if defined __NR_tkill
52# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
53#else
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). */
Denys Vlasenko978fbc92012-09-13 10:28:43 +020057# warning "tkill(2) not available, risk of strace hangs!"
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010058# define my_tkill(tid, sig) kill((tid), (sig))
59#endif
60
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +010061/* Glue for systems without a MMU that cannot provide fork() */
62#if !defined(HAVE_FORK)
63# undef NOMMU_SYSTEM
64# define NOMMU_SYSTEM 1
65#endif
66#if NOMMU_SYSTEM
67# define fork() vfork()
68#endif
69
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010070cflag_t cflag = CFLAG_NONE;
71unsigned int followfork = 0;
Denys Vlasenkof44cce42011-06-21 14:34:10 +020072unsigned int ptrace_setoptions = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010073unsigned int xflag = 0;
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +010074bool need_fork_exec_workarounds = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010075bool debug_flag = 0;
76bool Tflag = 0;
77bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020078/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020079static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010080static unsigned int tflag = 0;
81static bool iflag = 0;
82static bool rflag = 0;
83static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010084
85/* -I n */
86enum {
87 INTR_NOT_SET = 0,
88 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
89 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
90 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
91 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
92 NUM_INTR_OPTS
93};
94static int opt_intr;
95/* We play with signal mask only if this mode is active: */
96#define interactive (opt_intr == INTR_WHILE_WAIT)
97
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000098/*
99 * daemonized_tracer supports -D option.
100 * With this option, strace forks twice.
101 * Unlike normal case, with -D *grandparent* process exec's,
102 * becoming a traced process. Child exits (this prevents traced process
103 * from having children it doesn't expect to have), and grandchild
104 * attaches to grandparent similarly to strace -p PID.
105 * This allows for more transparent interaction in cases
106 * when process and its parent are communicating via signals,
107 * wait() etc. Without -D, strace process gets lodged in between,
108 * disrupting parent<->child link.
109 */
110static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000111
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +0100112#if USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100113static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
114# define use_seize (post_attach_sigstop == 0)
115#else
116# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
117# define use_seize 0
118#endif
119
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000120/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100121bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000122
Grant Edwards8a082772011-04-07 20:25:40 +0000123/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100124bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000125
126/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100127bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000128
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100129static bool detach_on_execve = 0;
130static bool skip_startup_execve = 0;
131
Dmitry V. Levina6809652008-11-10 17:14:58 +0000132static int exit_code = 0;
133static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200134static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700135
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000136static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200137static uid_t run_uid;
138static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000139
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100140unsigned int max_strlen = DEFAULT_STRLEN;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000141static int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200142static char *acolumn_spaces;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100143
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000144static char *outfname = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100145/* If -ff, points to stderr. Else, it's our common output log */
146static FILE *shared_log;
147
Denys Vlasenko000b6012012-01-28 01:25:03 +0100148struct tcb *printing_tcp = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100149static struct tcb *current_tcp;
150
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200151static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200152static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200153static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000154
Denys Vlasenkoeec8d5d2013-02-14 03:29:48 +0100155unsigned os_release; /* generated from uname()'s u.release */
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100156
Denys Vlasenko4c196382012-01-04 15:11:09 +0100157static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100158static int trace(void);
159static void cleanup(void);
160static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000161static sigset_t empty_set, blocked_set;
162
163#ifdef HAVE_SIG_ATOMIC_T
164static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100165#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000166static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100167#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000168
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100169#ifndef HAVE_STRERROR
170
171#if !HAVE_DECL_SYS_ERRLIST
172extern int sys_nerr;
173extern char *sys_errlist[];
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +0100174#endif
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100175
176const char *
177strerror(int err_no)
178{
179 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
180
181 if (err_no < 1 || err_no >= sys_nerr) {
182 sprintf(buf, "Unknown error %d", err_no);
183 return buf;
184 }
185 return sys_errlist[err_no];
186}
187
188#endif /* HAVE_STERRROR */
189
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000190static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200191usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000192{
193 fprintf(ofp, "\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200194usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
195 [-a column] [-o file] [-s strsize] [-P path]...\n\
196 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
197 or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
198 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000199-c -- count time, calls, and errors for each syscall and report summary\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200200-C -- like -c but also print regular output\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100201-d -- enable debug output to stderr\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100202-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000203-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100204-F -- attempt to follow vforks (deprecated, use -f)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000205-i -- print instruction pointer at time of syscall\n\
206-q -- suppress messages about attaching, detaching, etc.\n\
207-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100208-T -- print time spent in each syscall\n\
209-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000210-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000211-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200212-h -- print help message, -V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000213-a column -- alignment COLUMN for printing syscall results (default %d)\n\
214-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
215 options: trace, abbrev, verbose, raw, signal, read, or write\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200216-I interruptible --\n\
217 1: no signals are blocked\n\
218 2: fatal signals are blocked while decoding syscall (default)\n\
219 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
220 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
221 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000222-o file -- send trace output to FILE instead of stderr\n\
223-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
224-p pid -- trace process with process id PID, may be repeated\n\
225-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
226-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
227-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000228-E var=val -- put var=val in the environment for command\n\
229-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000230-P path -- trace accesses to path\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100231"
232/* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000233-z -- print only succeeding syscalls\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100234 */
235/* experimental, don't document it yet (option letter may change in the future!)
236-b -- detach on successful execve\n\
237 */
Roland McGrathde6e5332003-01-24 04:31:23 +0000238, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000239 exit(exitval);
240}
241
Denys Vlasenko75422762011-05-27 14:36:01 +0200242static void die(void) __attribute__ ((noreturn));
243static void die(void)
244{
245 if (strace_tracer_pid == getpid()) {
246 cflag = 0;
247 cleanup();
248 }
249 exit(1);
250}
251
252static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200253{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100254 char *msg;
255
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000256 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100257
258 /* We want to print entire message with single fprintf to ensure
259 * message integrity if stderr is shared with other programs.
260 * Thus we use vasprintf + single fprintf.
261 */
262 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100263 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100264 if (err_no)
265 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
266 else
267 fprintf(stderr, "%s: %s\n", progname, msg);
268 free(msg);
269 } else {
270 /* malloc in vasprintf failed, try it without malloc */
271 fprintf(stderr, "%s: ", progname);
272 vfprintf(stderr, fmt, p);
273 if (err_no)
274 fprintf(stderr, ": %s\n", strerror(err_no));
275 else
276 putc('\n', stderr);
277 }
278 /* We don't switch stderr to buffered, thus fprintf(stderr)
279 * always flushes its output and this is not necessary: */
280 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200281}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200282
Denys Vlasenko75422762011-05-27 14:36:01 +0200283void error_msg(const char *fmt, ...)
284{
285 va_list p;
286 va_start(p, fmt);
287 verror_msg(0, fmt, p);
288 va_end(p);
289}
290
291void error_msg_and_die(const char *fmt, ...)
292{
293 va_list p;
294 va_start(p, fmt);
295 verror_msg(0, fmt, p);
296 die();
297}
298
299void perror_msg(const char *fmt, ...)
300{
301 va_list p;
302 va_start(p, fmt);
303 verror_msg(errno, fmt, p);
304 va_end(p);
305}
306
307void perror_msg_and_die(const char *fmt, ...)
308{
309 va_list p;
310 va_start(p, fmt);
311 verror_msg(errno, fmt, p);
312 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200313}
314
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200315void die_out_of_memory(void)
316{
317 static bool recursed = 0;
318 if (recursed)
319 exit(1);
320 recursed = 1;
321 error_msg_and_die("Out of memory");
322}
323
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000324static void
325error_opt_arg(int opt, const char *arg)
326{
327 error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
328}
329
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +0100330#if USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100331static int
332ptrace_attach_or_seize(int pid)
333{
334 int r;
335 if (!use_seize)
336 return ptrace(PTRACE_ATTACH, pid, 0, 0);
Denys Vlasenko26bc0602012-07-10 16:36:32 +0200337 r = ptrace(PTRACE_SEIZE, pid, 0, 0);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100338 if (r)
339 return r;
340 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
341 return r;
342}
343#else
344# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
345#endif
346
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100347/*
348 * Used when we want to unblock stopped traced process.
349 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
350 * Returns 0 on success or if error was ESRCH
351 * (presumably process was killed while we talk to it).
352 * Otherwise prints error message and returns -1.
353 */
354static int
355ptrace_restart(int op, struct tcb *tcp, int sig)
356{
357 int err;
358 const char *msg;
359
360 errno = 0;
361 ptrace(op, tcp->pid, (void *) 0, (long) sig);
362 err = errno;
Denys Vlasenko23506752012-03-21 10:32:49 +0100363 if (!err)
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100364 return 0;
365
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100366 msg = "SYSCALL";
367 if (op == PTRACE_CONT)
368 msg = "CONT";
369 if (op == PTRACE_DETACH)
370 msg = "DETACH";
371#ifdef PTRACE_LISTEN
372 if (op == PTRACE_LISTEN)
373 msg = "LISTEN";
374#endif
Denys Vlasenko23506752012-03-21 10:32:49 +0100375 /*
376 * Why curcol != 0? Otherwise sometimes we get this:
377 *
378 * 10252 kill(10253, SIGKILL) = 0
379 * <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
380 *
381 * 10252 died after we retrieved syscall exit data,
382 * but before we tried to restart it. Log looks ugly.
383 */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100384 if (current_tcp && current_tcp->curcol != 0) {
Denys Vlasenko23506752012-03-21 10:32:49 +0100385 tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
386 line_ended();
387 }
388 if (err == ESRCH)
389 return 0;
390 errno = err;
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100391 perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
392 return -1;
393}
394
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200395static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000396set_cloexec_flag(int fd)
397{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200398 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000399
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200400 flags = fcntl(fd, F_GETFD);
401 if (flags < 0) {
402 /* Can happen only if fd is bad.
403 * Should never happen: if it does, we have a bug
404 * in the caller. Therefore we just abort
405 * instead of propagating the error.
406 */
407 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000408 }
409
410 newflags = flags | FD_CLOEXEC;
411 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200412 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000413
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200414 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000415}
416
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100417static void kill_save_errno(pid_t pid, int sig)
418{
419 int saved_errno = errno;
420
421 (void) kill(pid, sig);
422 errno = saved_errno;
423}
424
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100425/*
426 * When strace is setuid executable, we have to swap uids
427 * before and after filesystem and process management operations.
428 */
429static void
430swap_uid(void)
431{
432 int euid = geteuid(), uid = getuid();
433
434 if (euid != uid && setreuid(euid, uid) < 0) {
435 perror_msg_and_die("setreuid");
436 }
437}
438
439#if _LFS64_LARGEFILE
440# define fopen_for_output fopen64
441#else
442# define fopen_for_output fopen
443#endif
444
445static FILE *
446strace_fopen(const char *path)
447{
448 FILE *fp;
449
450 swap_uid();
451 fp = fopen_for_output(path, "w");
452 if (!fp)
453 perror_msg_and_die("Can't fopen '%s'", path);
454 swap_uid();
455 set_cloexec_flag(fileno(fp));
456 return fp;
457}
458
459static int popen_pid = 0;
460
461#ifndef _PATH_BSHELL
462# define _PATH_BSHELL "/bin/sh"
463#endif
464
465/*
466 * We cannot use standard popen(3) here because we have to distinguish
467 * popen child process from other processes we trace, and standard popen(3)
468 * does not export its child's pid.
469 */
470static FILE *
471strace_popen(const char *command)
472{
473 FILE *fp;
474 int fds[2];
475
476 swap_uid();
477 if (pipe(fds) < 0)
478 perror_msg_and_die("pipe");
479
480 set_cloexec_flag(fds[1]); /* never fails */
481
482 popen_pid = vfork();
483 if (popen_pid == -1)
484 perror_msg_and_die("vfork");
485
486 if (popen_pid == 0) {
487 /* child */
488 close(fds[1]);
489 if (fds[0] != 0) {
490 if (dup2(fds[0], 0))
491 perror_msg_and_die("dup2");
492 close(fds[0]);
493 }
494 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
495 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
496 }
497
498 /* parent */
499 close(fds[0]);
500 swap_uid();
501 fp = fdopen(fds[1], "w");
502 if (!fp)
503 die_out_of_memory();
504 return fp;
505}
506
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100507void
508tprintf(const char *fmt, ...)
509{
510 va_list args;
511
512 va_start(args, fmt);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100513 if (current_tcp) {
Denys Vlasenko6e4f3c12012-04-16 18:22:19 +0200514 int n = strace_vfprintf(current_tcp->outf, fmt, args);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100515 if (n < 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100516 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000517 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100518 } else
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100519 current_tcp->curcol += n;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100520 }
521 va_end(args);
522}
523
524void
525tprints(const char *str)
526{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100527 if (current_tcp) {
Denys Vlasenko142aee02012-04-16 18:10:15 +0200528 int n = fputs_unlocked(str, current_tcp->outf);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100529 if (n >= 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100530 current_tcp->curcol += strlen(str);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100531 return;
532 }
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100533 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000534 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100535 }
536}
537
538void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100539line_ended(void)
540{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100541 if (current_tcp) {
542 current_tcp->curcol = 0;
543 fflush(current_tcp->outf);
544 }
545 if (printing_tcp) {
546 printing_tcp->curcol = 0;
547 printing_tcp = NULL;
548 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100549}
550
551void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100552printleader(struct tcb *tcp)
553{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100554 /* If -ff, "previous tcb we printed" is always the same as current,
555 * because we have per-tcb output files.
556 */
557 if (followfork >= 2)
558 printing_tcp = tcp;
559
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100560 if (printing_tcp) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100561 current_tcp = printing_tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100562 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
563 /*
564 * case 1: we have a shared log (i.e. not -ff), and last line
565 * wasn't finished (same or different tcb, doesn't matter).
566 * case 2: split log, we are the same tcb, but our last line
567 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
568 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100569 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100570 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100571 }
572 }
573
574 printing_tcp = tcp;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100575 current_tcp = tcp;
576 current_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100577
578 if (print_pid_pfx)
579 tprintf("%-5d ", tcp->pid);
580 else if (nprocs > 1 && !outfname)
581 tprintf("[pid %5u] ", tcp->pid);
582
583 if (tflag) {
584 char str[sizeof("HH:MM:SS")];
585 struct timeval tv, dtv;
586 static struct timeval otv;
587
588 gettimeofday(&tv, NULL);
589 if (rflag) {
590 if (otv.tv_sec == 0)
591 otv = tv;
592 tv_sub(&dtv, &tv, &otv);
593 tprintf("%6ld.%06ld ",
594 (long) dtv.tv_sec, (long) dtv.tv_usec);
595 otv = tv;
596 }
597 else if (tflag > 2) {
598 tprintf("%ld.%06ld ",
599 (long) tv.tv_sec, (long) tv.tv_usec);
600 }
601 else {
602 time_t local = tv.tv_sec;
603 strftime(str, sizeof(str), "%T", localtime(&local));
604 if (tflag > 1)
605 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
606 else
607 tprintf("%s ", str);
608 }
609 }
610 if (iflag)
611 printcall(tcp);
612}
613
614void
615tabto(void)
616{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100617 if (current_tcp->curcol < acolumn)
618 tprints(acolumn_spaces + current_tcp->curcol);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100619}
620
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100621/* Should be only called directly *after successful attach* to a tracee.
622 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
623 * may create bogus empty FILE.<nonexistant_pid>, and then die.
624 */
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200625static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000626newoutf(struct tcb *tcp)
627{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100628 tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100629 if (followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000630 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000631 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200632 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000633 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000634}
635
Denys Vlasenko558e5122012-03-12 23:32:16 +0100636static void
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100637expand_tcbtab(void)
638{
639 /* Allocate some more TCBs and expand the table.
640 We don't want to relocate the TCBs because our
641 callers have pointers and it would be a pain.
642 So tcbtab is a table of pointers. Since we never
643 free the TCBs, we allocate a single chunk of many. */
644 int i = tcbtabsize;
645 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
646 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
647 if (!newtab || !newtcbs)
648 die_out_of_memory();
649 tcbtabsize *= 2;
650 tcbtab = newtab;
651 while (i < tcbtabsize)
652 tcbtab[i++] = newtcbs++;
653}
654
655static struct tcb *
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100656alloctcb(int pid)
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100657{
658 int i;
659 struct tcb *tcp;
660
661 if (nprocs == tcbtabsize)
662 expand_tcbtab();
663
664 for (i = 0; i < tcbtabsize; i++) {
665 tcp = tcbtab[i];
666 if ((tcp->flags & TCB_INUSE) == 0) {
667 memset(tcp, 0, sizeof(*tcp));
668 tcp->pid = pid;
669 tcp->flags = TCB_INUSE;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100670#if SUPPORTED_PERSONALITIES > 1
671 tcp->currpers = current_personality;
672#endif
673 nprocs++;
674 if (debug_flag)
675 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100676 return tcp;
677 }
678 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100679 error_msg_and_die("bug in alloctcb");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100680}
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100681
682static void
683droptcb(struct tcb *tcp)
684{
685 if (tcp->pid == 0)
686 return;
687
688 nprocs--;
689 if (debug_flag)
690 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
691
692 if (tcp->outf) {
Denys Vlasenko8511f2a2012-03-22 09:35:51 +0100693 if (followfork >= 2) {
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100694 if (tcp->curcol != 0)
695 fprintf(tcp->outf, " <detached ...>\n");
696 fclose(tcp->outf);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100697 } else {
698 if (printing_tcp == tcp && tcp->curcol != 0)
699 fprintf(tcp->outf, " <detached ...>\n");
700 fflush(tcp->outf);
701 }
702 }
703
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100704 if (current_tcp == tcp)
705 current_tcp = NULL;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100706 if (printing_tcp == tcp)
707 printing_tcp = NULL;
708
709 memset(tcp, 0, sizeof(*tcp));
710}
711
712/* detach traced process; continue with sig
713 * Never call DETACH twice on the same process as both unattached and
714 * attached-unstopped processes give the same ESRCH. For unattached process we
715 * would SIGSTOP it and wait for its SIGSTOP notification forever.
716 */
717static int
718detach(struct tcb *tcp)
719{
720 int error;
721 int status, sigstop_expected;
722
723 if (tcp->flags & TCB_BPTSET)
724 clearbpt(tcp);
725
726 /*
727 * Linux wrongly insists the child be stopped
728 * before detaching. Arghh. We go through hoops
729 * to make a clean break of things.
730 */
731#if defined(SPARC)
Denys Vlasenko978fbc92012-09-13 10:28:43 +0200732# undef PTRACE_DETACH
733# define PTRACE_DETACH PTRACE_SUNDETACH
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100734#endif
735
736 error = 0;
737 sigstop_expected = 0;
738 if (tcp->flags & TCB_ATTACHED) {
739 /*
740 * We attached but possibly didn't see the expected SIGSTOP.
741 * We must catch exactly one as otherwise the detached process
742 * would be left stopped (process state T).
743 */
744 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
745 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
746 if (error == 0) {
747 /* On a clear day, you can see forever. */
748 }
749 else if (errno != ESRCH) {
750 /* Shouldn't happen. */
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000751 perror_msg("%s", "detach: ptrace(PTRACE_DETACH, ...)");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100752 }
753 else if (my_tkill(tcp->pid, 0) < 0) {
754 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000755 perror_msg("%s", "detach: checking sanity");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100756 }
757 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
758 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000759 perror_msg("%s", "detach: stopping child");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100760 }
761 else
762 sigstop_expected = 1;
763 }
764
765 if (sigstop_expected) {
766 for (;;) {
767#ifdef __WALL
768 if (waitpid(tcp->pid, &status, __WALL) < 0) {
769 if (errno == ECHILD) /* Already gone. */
770 break;
771 if (errno != EINVAL) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000772 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100773 break;
774 }
775#endif /* __WALL */
776 /* No __WALL here. */
777 if (waitpid(tcp->pid, &status, 0) < 0) {
778 if (errno != ECHILD) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000779 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100780 break;
781 }
782#ifdef __WCLONE
783 /* If no processes, try clones. */
784 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
785 if (errno != ECHILD)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000786 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100787 break;
788 }
789#endif /* __WCLONE */
790 }
791#ifdef __WALL
792 }
793#endif
794 if (!WIFSTOPPED(status)) {
795 /* Au revoir, mon ami. */
796 break;
797 }
798 if (WSTOPSIG(status) == SIGSTOP) {
799 ptrace_restart(PTRACE_DETACH, tcp, 0);
800 break;
801 }
802 error = ptrace_restart(PTRACE_CONT, tcp,
803 WSTOPSIG(status) == syscall_trap_sig ? 0
804 : WSTOPSIG(status));
805 if (error < 0)
806 break;
807 }
808 }
809
810 if (!qflag && (tcp->flags & TCB_ATTACHED))
811 fprintf(stderr, "Process %u detached\n", tcp->pid);
812
813 droptcb(tcp);
814
815 return error;
816}
817
818static void
Denys Vlasenko558e5122012-03-12 23:32:16 +0100819process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100820{
821 while (*opt) {
822 /*
823 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
824 * pidof uses space as delim, pgrep uses newline. :(
825 */
826 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100827 char *delim = opt + strcspn(opt, ", \n\t");
828 char c = *delim;
829
830 *delim = '\0';
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000831 pid = string_to_uint(opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100832 if (pid <= 0) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000833 error_msg_and_die("Invalid process id: '%s'", opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100834 }
835 if (pid == strace_tracer_pid) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000836 error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100837 }
838 *delim = c;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100839 alloctcb(pid);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100840 if (c == '\0')
841 break;
842 opt = delim + 1;
843 }
844}
845
Roland McGrath02203312007-06-11 22:06:31 +0000846static void
847startup_attach(void)
848{
849 int tcbi;
850 struct tcb *tcp;
851
852 /*
853 * Block user interruptions as we would leave the traced
854 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200855 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200856 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000857 */
858 if (interactive)
859 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
860
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000861 if (daemonized_tracer) {
862 pid_t pid = fork();
863 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200864 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000865 }
866 if (pid) { /* parent */
867 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200868 * Wait for grandchild to attach to straced process
869 * (grandparent). Grandchild SIGKILLs us after it attached.
870 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000871 * it proceeds to exec the straced program.
872 */
873 pause();
874 _exit(0); /* paranoia */
875 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200876 /* grandchild */
877 /* We will be the tracer process. Remember our new pid: */
878 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000879 }
880
Roland McGrath02203312007-06-11 22:06:31 +0000881 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
882 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200883
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100884 if (!(tcp->flags & TCB_INUSE))
885 continue;
886
Denys Vlasenkod116a732011-09-05 14:01:33 +0200887 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100888 if (tcp->flags & TCB_ATTACHED)
889 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200890
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000891 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000892 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000893 DIR *dir;
894
895 sprintf(procdir, "/proc/%d/task", tcp->pid);
896 dir = opendir(procdir);
897 if (dir != NULL) {
898 unsigned int ntid = 0, nerr = 0;
899 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200900
Roland McGrath02203312007-06-11 22:06:31 +0000901 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200902 struct tcb *cur_tcp;
903 int tid;
904
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000905 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000906 continue;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000907 /* we trust /proc filesystem */
Roland McGrath02203312007-06-11 22:06:31 +0000908 tid = atoi(de->d_name);
909 if (tid <= 0)
910 continue;
911 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100912 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000913 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100914 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200915 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200916 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200917 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100918 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200919 fprintf(stderr, "attach to pid %d succeeded\n", tid);
920 cur_tcp = tcp;
921 if (tid != tcp->pid)
922 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100923 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100924 newoutf(cur_tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000925 }
926 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200927 if (interactive) {
928 sigprocmask(SIG_SETMASK, &empty_set, NULL);
929 if (interrupted)
930 goto ret;
931 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
932 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000933 ntid -= nerr;
934 if (ntid == 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000935 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000936 droptcb(tcp);
937 continue;
938 }
939 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000940 fprintf(stderr, ntid > 1
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100941? "Process %u attached with %u threads\n"
942: "Process %u attached\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200943 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000944 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100945 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200946 /* -p PID, we failed to attach to PID itself
947 * but did attach to some of its sibling threads.
948 * Drop PID's tcp.
949 */
950 droptcb(tcp);
951 }
Roland McGrath02203312007-06-11 22:06:31 +0000952 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000953 } /* if (opendir worked) */
954 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100955 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000956 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000957 droptcb(tcp);
958 continue;
959 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100960 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100961 newoutf(tcp);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100962 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200963 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000964
965 if (daemonized_tracer) {
966 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000967 * Make parent go away.
968 * Also makes grandparent's wait() unblock.
969 */
970 kill(getppid(), SIGKILL);
971 }
972
Roland McGrath02203312007-06-11 22:06:31 +0000973 if (!qflag)
974 fprintf(stderr,
Denys Vlasenko9c3861d2012-03-16 15:21:49 +0100975 "Process %u attached\n",
Roland McGrath02203312007-06-11 22:06:31 +0000976 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200977 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000978
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200979 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000980 if (interactive)
981 sigprocmask(SIG_SETMASK, &empty_set, NULL);
982}
983
984static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200985startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000986{
987 struct stat statbuf;
988 const char *filename;
989 char pathname[MAXPATHLEN];
990 int pid = 0;
991 struct tcb *tcp;
992
993 filename = argv[0];
994 if (strchr(filename, '/')) {
995 if (strlen(filename) > sizeof pathname - 1) {
996 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200997 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000998 }
999 strcpy(pathname, filename);
1000 }
1001#ifdef USE_DEBUGGING_EXEC
1002 /*
1003 * Debuggers customarily check the current directory
1004 * first regardless of the path but doing that gives
1005 * security geeks a panic attack.
1006 */
1007 else if (stat(filename, &statbuf) == 0)
1008 strcpy(pathname, filename);
1009#endif /* USE_DEBUGGING_EXEC */
1010 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +00001011 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +00001012 int m, n, len;
1013
1014 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +01001015 const char *colon = strchr(path, ':');
1016 if (colon) {
1017 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +00001018 m = n + 1;
1019 }
1020 else
1021 m = n = strlen(path);
1022 if (n == 0) {
1023 if (!getcwd(pathname, MAXPATHLEN))
1024 continue;
1025 len = strlen(pathname);
1026 }
1027 else if (n > sizeof pathname - 1)
1028 continue;
1029 else {
1030 strncpy(pathname, path, n);
1031 len = n;
1032 }
1033 if (len && pathname[len - 1] != '/')
1034 pathname[len++] = '/';
1035 strcpy(pathname + len, filename);
1036 if (stat(pathname, &statbuf) == 0 &&
1037 /* Accept only regular files
1038 with some execute bits set.
1039 XXX not perfect, might still fail */
1040 S_ISREG(statbuf.st_mode) &&
1041 (statbuf.st_mode & 0111))
1042 break;
1043 }
1044 }
1045 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001046 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +00001047 }
Dmitry V. Levina6809652008-11-10 17:14:58 +00001048 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001049 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001050 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001051 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001052 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1053 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001054 ) {
1055 pid = getpid();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001056 if (shared_log != stderr)
1057 close(fileno(shared_log));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001058 if (!daemonized_tracer && !use_seize) {
1059 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001060 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001061 }
Roland McGrath02203312007-06-11 22:06:31 +00001062 }
Roland McGrath02203312007-06-11 22:06:31 +00001063
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001064 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +00001065 uid_t run_euid = run_uid;
1066 gid_t run_egid = run_gid;
1067
1068 if (statbuf.st_mode & S_ISUID)
1069 run_euid = statbuf.st_uid;
1070 if (statbuf.st_mode & S_ISGID)
1071 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +00001072 /*
1073 * It is important to set groups before we
1074 * lose privileges on setuid.
1075 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001076 if (initgroups(username, run_gid) < 0) {
1077 perror_msg_and_die("initgroups");
1078 }
1079 if (setregid(run_gid, run_egid) < 0) {
1080 perror_msg_and_die("setregid");
1081 }
1082 if (setreuid(run_uid, run_euid) < 0) {
1083 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +00001084 }
1085 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001086 else if (geteuid() != 0)
Dmitry V. Levin508279c2012-08-24 17:56:53 +00001087 if (setreuid(run_uid, run_uid) < 0) {
1088 perror_msg_and_die("setreuid");
1089 }
Roland McGrath02203312007-06-11 22:06:31 +00001090
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001091 if (!daemonized_tracer) {
1092 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001093 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001094 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001095 * the immediately following execve syscall.
1096 * Can't do this on NOMMU systems, we are after
1097 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001098 */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001099 if (!NOMMU_SYSTEM)
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001100 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001101 } else {
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001102 alarm(3);
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001103 /* we depend on SIGCHLD set to SIG_DFL by init code */
1104 /* if it happens to be SIG_IGN'ed, wait won't block */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001105 wait(NULL);
1106 alarm(0);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001107 }
Roland McGrath02203312007-06-11 22:06:31 +00001108
1109 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001110 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +00001111 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001112
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001113 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +02001114
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001115 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001116 if (!use_seize) {
1117 /* child did PTRACE_TRACEME, nothing to do in parent */
1118 } else {
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001119 if (!NOMMU_SYSTEM) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001120 /* Wait until child stopped itself */
1121 int status;
1122 while (waitpid(pid, &status, WSTOPPED) < 0) {
1123 if (errno == EINTR)
1124 continue;
1125 perror_msg_and_die("waitpid");
1126 }
1127 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001128 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001129 perror_msg_and_die("Unexpected wait status %x", status);
1130 }
1131 }
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001132 /* Else: NOMMU case, we have no way to sync.
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001133 * Just attach to it as soon as possible.
1134 * This means that we may miss a few first syscalls...
1135 */
1136
1137 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001138 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001139 perror_msg_and_die("Can't attach to %d", pid);
1140 }
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001141 if (!NOMMU_SYSTEM)
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001142 kill(pid, SIGCONT);
1143 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001144 tcp = alloctcb(pid);
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001145 if (!NOMMU_SYSTEM)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001146 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001147 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001148 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001149 newoutf(tcp);
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001150 }
1151 else {
1152 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1153 strace_tracer_pid = getpid();
1154 /* The tracee is our parent: */
1155 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +01001156 alloctcb(pid);
1157 /* attaching will be done later, by startup_attach */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001158 /* note: we don't do newoutf(tcp) here either! */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001159
1160//NOMMU BUG! -D is active, we (child) return, and this smashes the stack!
1161//When parent will be unpaused, it segfaults.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001162 }
Roland McGrath02203312007-06-11 22:06:31 +00001163}
1164
Wang Chaob13c0de2010-11-12 17:25:19 +08001165/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001166 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +08001167 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001168 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +08001169 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001170static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001171test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +08001172{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001173 int pid, expected_grandchild = 0, found_grandchild = 0;
1174 const unsigned int test_options = PTRACE_O_TRACECLONE |
1175 PTRACE_O_TRACEFORK |
1176 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +08001177
Denys Vlasenko5d645812011-08-20 12:48:18 +02001178 pid = fork();
1179 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001180 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +02001181 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001182 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001183 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001184 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1185 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001186 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001187 if (fork() < 0)
1188 perror_msg_and_die("fork");
1189 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +08001190 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001191
1192 while (1) {
1193 int status, tracee_pid;
1194
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001195 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001196 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001197 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001198 if (errno == EINTR)
1199 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001200 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001201 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001202 kill_save_errno(pid, SIGKILL);
1203 perror_msg_and_die("%s: unexpected wait result %d",
1204 __func__, tracee_pid);
1205 }
1206 if (WIFEXITED(status)) {
1207 if (WEXITSTATUS(status)) {
1208 if (tracee_pid != pid)
1209 kill_save_errno(pid, SIGKILL);
1210 error_msg_and_die("%s: unexpected exit status %u",
1211 __func__, WEXITSTATUS(status));
1212 }
1213 continue;
1214 }
1215 if (WIFSIGNALED(status)) {
1216 if (tracee_pid != pid)
1217 kill_save_errno(pid, SIGKILL);
1218 error_msg_and_die("%s: unexpected signal %u",
1219 __func__, WTERMSIG(status));
1220 }
1221 if (!WIFSTOPPED(status)) {
1222 if (tracee_pid != pid)
1223 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001224 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001225 error_msg_and_die("%s: unexpected wait status %x",
1226 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001227 }
1228 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001229 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001230 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1231 kill_save_errno(tracee_pid, SIGKILL);
1232 kill_save_errno(pid, SIGKILL);
1233 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001234 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001235 continue;
1236 }
1237 switch (WSTOPSIG(status)) {
1238 case SIGSTOP:
1239 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1240 && errno != EINVAL && errno != EIO)
1241 perror_msg("PTRACE_SETOPTIONS");
1242 break;
1243 case SIGTRAP:
1244 if (status >> 16 == PTRACE_EVENT_FORK) {
1245 long msg = 0;
1246
1247 if (ptrace(PTRACE_GETEVENTMSG, pid,
1248 NULL, (long) &msg) == 0)
1249 expected_grandchild = msg;
1250 }
1251 break;
1252 }
1253 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1254 kill_save_errno(pid, SIGKILL);
1255 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001256 }
1257 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001258 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001259 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001260 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001261 fprintf(stderr, "ptrace_setoptions = %#x\n",
1262 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001263 return 0;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001264 }
1265 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1266 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001267 return 1;
Wang Chaob13c0de2010-11-12 17:25:19 +08001268}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001269
1270/*
1271 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1272 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1273 * and then see whether it will stop with (SIGTRAP | 0x80).
1274 *
1275 * Use of this option enables correct handling of user-generated SIGTRAPs,
1276 * and SIGTRAPs generated by special instructions such as int3 on x86:
1277 * _start: .globl _start
1278 * int3
1279 * movl $42, %ebx
1280 * movl $1, %eax
1281 * int $0x80
1282 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1283 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001284static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001285test_ptrace_setoptions_for_all(void)
1286{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001287 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1288 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001289 int pid;
1290 int it_worked = 0;
1291
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001292 /* this fork test doesn't work on no-mmu systems */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001293 if (NOMMU_SYSTEM)
1294 return 0; /* be bold, and pretend that test succeeded */
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001295
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001296 pid = fork();
1297 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001298 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001299
1300 if (pid == 0) {
1301 pid = getpid();
1302 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001303 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001304 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1305 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001306 kill(pid, SIGSTOP);
1307 _exit(0); /* parent should see entry into this syscall */
1308 }
1309
1310 while (1) {
1311 int status, tracee_pid;
1312
1313 errno = 0;
1314 tracee_pid = wait(&status);
1315 if (tracee_pid <= 0) {
1316 if (errno == EINTR)
1317 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001318 kill_save_errno(pid, SIGKILL);
1319 perror_msg_and_die("%s: unexpected wait result %d",
1320 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001321 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001322 if (WIFEXITED(status)) {
1323 if (WEXITSTATUS(status) == 0)
1324 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001325 error_msg_and_die("%s: unexpected exit status %u",
1326 __func__, WEXITSTATUS(status));
1327 }
1328 if (WIFSIGNALED(status)) {
1329 error_msg_and_die("%s: unexpected signal %u",
1330 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001331 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001332 if (!WIFSTOPPED(status)) {
1333 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001334 error_msg_and_die("%s: unexpected wait status %x",
1335 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001336 }
1337 if (WSTOPSIG(status) == SIGSTOP) {
1338 /*
1339 * We don't check "options aren't accepted" error.
1340 * If it happens, we'll never get (SIGTRAP | 0x80),
1341 * and thus will decide to not use the option.
1342 * IOW: the outcome of the test will be correct.
1343 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001344 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1345 && errno != EINVAL && errno != EIO)
1346 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001347 }
1348 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1349 it_worked = 1;
1350 }
1351 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001352 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001353 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001354 }
1355 }
1356
1357 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001358 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001359 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001360 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001361 fprintf(stderr, "ptrace_setoptions = %#x\n",
1362 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001363 return 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001364 }
1365
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001366 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1367 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001368 return 1;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001369}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001370
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001371#if USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001372static void
1373test_ptrace_seize(void)
1374{
1375 int pid;
1376
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001377 /* this fork test doesn't work on no-mmu systems */
1378 if (NOMMU_SYSTEM) {
1379 post_attach_sigstop = 0; /* this sets use_seize to 1 */
1380 return;
1381 }
1382
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001383 pid = fork();
1384 if (pid < 0)
1385 perror_msg_and_die("fork");
1386
1387 if (pid == 0) {
1388 pause();
1389 _exit(0);
1390 }
1391
1392 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1393 * attaching tracee continues to run unless a trap condition occurs.
1394 * PTRACE_SEIZE doesn't affect signal or group stop state.
1395 */
Denys Vlasenko26bc0602012-07-10 16:36:32 +02001396 if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001397 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001398 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001399 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1400 }
1401
1402 kill(pid, SIGKILL);
1403
1404 while (1) {
1405 int status, tracee_pid;
1406
1407 errno = 0;
1408 tracee_pid = waitpid(pid, &status, 0);
1409 if (tracee_pid <= 0) {
1410 if (errno == EINTR)
1411 continue;
1412 perror_msg_and_die("%s: unexpected wait result %d",
1413 __func__, tracee_pid);
1414 }
1415 if (WIFSIGNALED(status)) {
1416 return;
1417 }
1418 error_msg_and_die("%s: unexpected wait status %x",
1419 __func__, status);
1420 }
1421}
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001422#else /* !USE_SEIZE */
1423# define test_ptrace_seize() ((void)0)
1424#endif
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001425
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001426static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001427get_os_release(void)
1428{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001429 unsigned rel;
1430 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001431 struct utsname u;
1432 if (uname(&u) < 0)
1433 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001434 /* u.release has this form: "3.2.9[-some-garbage]" */
1435 rel = 0;
1436 p = u.release;
1437 for (;;) {
1438 if (!(*p >= '0' && *p <= '9'))
1439 error_msg_and_die("Bad OS release string: '%s'", u.release);
1440 /* Note: this open-codes KERNEL_VERSION(): */
1441 rel = (rel << 8) | atoi(p);
1442 if (rel >= KERNEL_VERSION(1,0,0))
1443 break;
1444 while (*p >= '0' && *p <= '9')
1445 p++;
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001446 if (*p != '.') {
1447 if (rel >= KERNEL_VERSION(0,1,0)) {
1448 /* "X.Y-something" means "X.Y.0" */
1449 rel <<= 8;
1450 break;
1451 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001452 error_msg_and_die("Bad OS release string: '%s'", u.release);
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001453 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001454 p++;
1455 }
1456 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001457}
1458
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001459/*
1460 * Initialization part of main() was eating much stack (~0.5k),
1461 * which was unused after init.
1462 * We can reuse it if we move init code into a separate function.
1463 *
1464 * Don't want main() to inline us and defeat the reason
1465 * we have a separate function.
1466 */
1467static void __attribute__ ((noinline))
1468init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001469{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001470 struct tcb *tcp;
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001471 int c, i;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001472 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001473 struct sigaction sa;
1474
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001475 progname = argv[0] ? argv[0] : "strace";
1476
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001477 /* Make sure SIGCHLD has the default action so that waitpid
1478 definitely works without losing track of children. The user
1479 should not have given us a bogus state to inherit, but he might
1480 have. Arguably we should detect SIG_IGN here and pass it on
1481 to children, but probably noone really needs that. */
1482 signal(SIGCHLD, SIG_DFL);
1483
Denys Vlasenko75422762011-05-27 14:36:01 +02001484 strace_tracer_pid = getpid();
1485
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001486 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001487
Roland McGrathee9d4352002-12-18 04:16:10 +00001488 /* Allocate the initial tcbtab. */
1489 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001490 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001491 if (!tcbtab)
1492 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001493 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001494 if (!tcp)
1495 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001496 for (c = 0; c < tcbtabsize; c++)
1497 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001498
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001499 shared_log = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001500 set_sortby(DEFAULT_SORTBY);
1501 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001502 qualify("trace=all");
1503 qualify("abbrev=all");
1504 qualify("verbose=all");
1505 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001506 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001507 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001508 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001509 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001510 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001511 case 'b':
1512 detach_on_execve = 1;
1513 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001514 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001515 if (cflag == CFLAG_BOTH) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001516 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001517 }
1518 cflag = CFLAG_ONLY_STATS;
1519 break;
1520 case 'C':
1521 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001522 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001523 }
1524 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001525 break;
1526 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001527 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001528 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001529 case 'D':
1530 daemonized_tracer = 1;
1531 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001532 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001533 optF = 1;
1534 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001535 case 'f':
1536 followfork++;
1537 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001538 case 'h':
1539 usage(stdout, 0);
1540 break;
1541 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001542 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001543 break;
1544 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001545 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001546 break;
1547 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001548 rflag = 1;
1549 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001550 case 't':
1551 tflag++;
1552 break;
1553 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001554 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001555 break;
1556 case 'x':
1557 xflag++;
1558 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001559 case 'y':
1560 show_fd_path = 1;
1561 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001562 case 'v':
1563 qualify("abbrev=none");
1564 break;
1565 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001566 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001567 exit(0);
1568 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001569 case 'z':
1570 not_failing_only = 1;
1571 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001572 case 'a':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001573 acolumn = string_to_uint(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001574 if (acolumn < 0)
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001575 error_opt_arg(c, optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001576 break;
1577 case 'e':
1578 qualify(optarg);
1579 break;
1580 case 'o':
1581 outfname = strdup(optarg);
1582 break;
1583 case 'O':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001584 i = string_to_uint(optarg);
1585 if (i < 0)
1586 error_opt_arg(c, optarg);
1587 set_overhead(i);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001588 break;
1589 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001590 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001591 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001592 case 'P':
1593 tracing_paths = 1;
1594 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001595 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001596 }
1597 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001598 case 's':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001599 i = string_to_uint(optarg);
1600 if (i < 0)
1601 error_opt_arg(c, optarg);
1602 max_strlen = i;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001603 break;
1604 case 'S':
1605 set_sortby(optarg);
1606 break;
1607 case 'u':
1608 username = strdup(optarg);
1609 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001610 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001611 if (putenv(optarg) < 0)
1612 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001613 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001614 case 'I':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001615 opt_intr = string_to_uint(optarg);
1616 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1617 error_opt_arg(c, optarg);
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001618 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001619 default:
1620 usage(stderr, 1);
1621 break;
1622 }
1623 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001624 argv += optind;
1625 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001626
Denys Vlasenko102ec492011-08-25 01:27:59 +02001627 acolumn_spaces = malloc(acolumn + 1);
1628 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001629 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001630 memset(acolumn_spaces, ' ', acolumn);
1631 acolumn_spaces[acolumn] = '\0';
1632
Denys Vlasenko837399a2012-01-24 11:37:03 +01001633 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001634 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001635 usage(stderr, 1);
1636
Denys Vlasenkofd883382012-03-09 13:03:41 +01001637 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001638 error_msg_and_die("-D and -p are mutually exclusive");
Wang Chaod322a4b2010-08-05 14:30:11 +08001639 }
1640
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001641 if (!followfork)
1642 followfork = optF;
1643
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001644 if (followfork >= 2 && cflag) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001645 error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
Roland McGrathcb9def62006-04-25 07:48:03 +00001646 }
1647
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001648 /* See if they want to run as another user. */
1649 if (username != NULL) {
1650 struct passwd *pent;
1651
1652 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001653 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001654 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001655 pent = getpwnam(username);
1656 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001657 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001658 }
1659 run_uid = pent->pw_uid;
1660 run_gid = pent->pw_gid;
1661 }
1662 else {
1663 run_uid = getuid();
1664 run_gid = getgid();
1665 }
1666
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001667 /*
1668 * On any reasonably recent Linux kernel (circa about 2.5.46)
1669 * need_fork_exec_workarounds should stay 0 after these tests:
1670 */
1671 /*need_fork_exec_workarounds = 0; - already is */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001672 if (followfork)
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001673 need_fork_exec_workarounds = test_ptrace_setoptions_followfork();
1674 need_fork_exec_workarounds |= test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001675 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001676
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001677 /* Check if they want to redirect the output. */
1678 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001679 /* See if they want to pipe the output. */
1680 if (outfname[0] == '|' || outfname[0] == '!') {
1681 /*
1682 * We can't do the <outfname>.PID funny business
1683 * when using popen, so prohibit it.
1684 */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001685 if (followfork >= 2)
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001686 error_msg_and_die("Piping the output and -ff are mutually exclusive");
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001687 shared_log = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001688 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001689 else if (followfork < 2)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001690 shared_log = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001691 } else {
1692 /* -ff without -o FILE is the same as single -f */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001693 if (followfork >= 2)
Denys Vlasenko328bf252012-03-12 23:34:13 +01001694 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001695 }
1696
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001697 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001698 char *buf = malloc(BUFSIZ);
1699 if (!buf)
1700 die_out_of_memory();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001701 setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001702 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001703 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001704 if (!opt_intr)
1705 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001706 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001707 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001708 if (!opt_intr)
1709 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001710
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001711 /* argv[0] -pPID -oFILE Default interactive setting
1712 * yes 0 0 INTR_WHILE_WAIT
1713 * no 1 0 INTR_WHILE_WAIT
1714 * yes 0 1 INTR_NEVER
1715 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001716 */
1717
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01001718 sigemptyset(&empty_set);
1719 sigemptyset(&blocked_set);
1720
Roland McGrath54cc1c82007-11-03 23:34:11 +00001721 /* STARTUP_CHILD must be called before the signal handlers get
1722 installed below as they are inherited into the spawned process.
1723 Also we do not need to be protected by them as during interruption
1724 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001725 if (argv[0]) {
1726 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001727 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001728 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001729
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001730 sa.sa_handler = SIG_IGN;
1731 sigemptyset(&sa.sa_mask);
1732 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001733 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1734 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1735 if (opt_intr != INTR_ANYWHERE) {
1736 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1737 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1738 /*
1739 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1740 * fatal signals are blocked while syscall stop is processed,
1741 * and acted on in between, when waiting for new syscall stops.
1742 * In non-interactive mode, signals are ignored.
1743 */
1744 if (opt_intr == INTR_WHILE_WAIT) {
1745 sigaddset(&blocked_set, SIGHUP);
1746 sigaddset(&blocked_set, SIGINT);
1747 sigaddset(&blocked_set, SIGQUIT);
1748 sigaddset(&blocked_set, SIGPIPE);
1749 sigaddset(&blocked_set, SIGTERM);
1750 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001751 }
1752 /* SIG_IGN, or set handler for these */
1753 sigaction(SIGHUP, &sa, NULL);
1754 sigaction(SIGINT, &sa, NULL);
1755 sigaction(SIGQUIT, &sa, NULL);
1756 sigaction(SIGPIPE, &sa, NULL);
1757 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001758 }
Denys Vlasenkofd883382012-03-09 13:03:41 +01001759 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001760 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001761
Denys Vlasenkofd883382012-03-09 13:03:41 +01001762 /* Do we want pids printed in our -o OUTFILE?
1763 * -ff: no (every pid has its own file); or
1764 * -f: yes (there can be more pids in the future); or
1765 * -p PID1,PID2: yes (there are already more than one pid)
1766 */
1767 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001768}
1769
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001770static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001771pid2tcb(int pid)
1772{
1773 int i;
1774
1775 if (pid <= 0)
1776 return NULL;
1777
1778 for (i = 0; i < tcbtabsize; i++) {
1779 struct tcb *tcp = tcbtab[i];
1780 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1781 return tcp;
1782 }
1783
1784 return NULL;
1785}
1786
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001787static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001788cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001789{
1790 int i;
1791 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001792 int fatal_sig;
1793
1794 /* 'interrupted' is a volatile object, fetch it only once */
1795 fatal_sig = interrupted;
1796 if (!fatal_sig)
1797 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001798
Roland McGrathee9d4352002-12-18 04:16:10 +00001799 for (i = 0; i < tcbtabsize; i++) {
1800 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001801 if (!(tcp->flags & TCB_INUSE))
1802 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001803 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804 fprintf(stderr,
1805 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001806 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001807 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001808 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001809 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001810 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001811 }
1812 if (cflag)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001813 call_summary(shared_log);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001814}
1815
1816static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001817interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001818{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001819 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001820}
1821
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001822static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001823trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001824{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001825 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001826 struct rusage *rup = cflag ? &ru : NULL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001827#ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001828 static int wait4_options = __WALL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001829#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001830
Roland McGratheb9e2e82009-06-02 16:49:22 -07001831 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001832 int pid;
1833 int wait_errno;
1834 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001835 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001836 struct tcb *tcp;
1837 unsigned event;
1838
Denys Vlasenko222713a2009-03-17 14:29:59 +00001839 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001840 return 0;
1841 if (interactive)
1842 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001843#ifdef __WALL
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001844 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001845 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001846 /* this kernel does not support __WALL */
1847 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001848 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001849 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001850 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001851 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001852 pid = wait4(-1, &status, __WCLONE, rup);
1853 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001854 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001855 }
1856 }
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001857#else
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001858 pid = wait4(-1, &status, 0, rup);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001859#endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001860 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001861 if (interactive)
1862 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001863
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001864 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001865 switch (wait_errno) {
1866 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001867 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001868 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001869 /*
1870 * We would like to verify this case
1871 * but sometimes a race in Solbourne's
1872 * version of SunOS sometimes reports
1873 * ECHILD before sending us SIGCHILD.
1874 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001875 return 0;
1876 default:
1877 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001878 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001879 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001880 }
1881 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001882 if (pid == popen_pid) {
1883 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001884 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001885 continue;
1886 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001887
1888 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001889 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001890 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001891 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001892 strcpy(buf, "???");
1893 if (WIFSIGNALED(status))
1894#ifdef WCOREDUMP
1895 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1896 WCOREDUMP(status) ? "core," : "",
1897 signame(WTERMSIG(status)));
1898#else
1899 sprintf(buf, "WIFSIGNALED,sig=%s",
1900 signame(WTERMSIG(status)));
1901#endif
1902 if (WIFEXITED(status))
1903 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1904 if (WIFSTOPPED(status))
1905 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001906#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001907 if (WIFCONTINUED(status))
1908 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001909#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001910 evbuf[0] = '\0';
1911 if (event != 0) {
1912 static const char *const event_names[] = {
1913 [PTRACE_EVENT_CLONE] = "CLONE",
1914 [PTRACE_EVENT_FORK] = "FORK",
1915 [PTRACE_EVENT_VFORK] = "VFORK",
1916 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1917 [PTRACE_EVENT_EXEC] = "EXEC",
1918 [PTRACE_EVENT_EXIT] = "EXIT",
1919 };
1920 const char *e;
1921 if (event < ARRAY_SIZE(event_names))
1922 e = event_names[event];
1923 else {
1924 sprintf(buf, "?? (%u)", event);
1925 e = buf;
1926 }
1927 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1928 }
1929 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001930 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001931
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001932 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001933 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001934
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001935 if (!tcp) {
Roland McGrath41c48222008-07-18 00:25:10 +00001936 if (followfork) {
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001937 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001938 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001939 newoutf(tcp);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001940 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001941 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001942 pid);
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001943 } else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001944 /* This can happen if a clone call used
1945 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001946 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001947 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001948 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001949 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001950 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001951
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001952 clear_regs();
1953 if (WIFSTOPPED(status))
1954 get_regs(pid);
1955
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001956 /* Under Linux, execve changes pid to thread leader's pid,
1957 * and we see this changed pid on EVENT_EXEC and later,
1958 * execve sysexit. Leader "disappears" without exit
1959 * notification. Let user know that, drop leader's tcb,
1960 * and fix up pid in execve thread's tcb.
1961 * Effectively, execve thread's tcb replaces leader's tcb.
1962 *
1963 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1964 * on exit syscall) in multithreaded programs exactly
1965 * in order to handle this case.
1966 *
1967 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1968 * On 2.6 and earlier, it can return garbage.
1969 */
1970 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001971 FILE *fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001972 struct tcb *execve_thread;
1973 long old_pid = 0;
1974
1975 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1976 goto dont_switch_tcbs;
1977 if (old_pid <= 0 || old_pid == pid)
1978 goto dont_switch_tcbs;
1979 execve_thread = pid2tcb(old_pid);
1980 /* It should be !NULL, but I feel paranoid */
1981 if (!execve_thread)
1982 goto dont_switch_tcbs;
1983
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001984 if (execve_thread->curcol != 0) {
1985 /*
1986 * One case we are here is -ff:
1987 * try "strace -oLOG -ff test/threaded_execve"
1988 */
1989 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001990 /*execve_thread->curcol = 0; - no need, see code below */
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001991 }
1992 /* Swap output FILEs (needed for -ff) */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001993 fp = execve_thread->outf;
1994 execve_thread->outf = tcp->outf;
1995 tcp->outf = fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001996 /* And their column positions */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001997 execve_thread->curcol = tcp->curcol;
1998 tcp->curcol = 0;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001999 /* Drop leader, but close execve'd thread outfile (if -ff) */
2000 droptcb(tcp);
2001 /* Switch to the thread, reusing leader's outfile and pid */
2002 tcp = execve_thread;
2003 tcp->pid = pid;
2004 if (cflag != CFLAG_ONLY_STATS) {
2005 printleader(tcp);
2006 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
2007 line_ended();
2008 tcp->flags |= TCB_REPRINT;
2009 }
2010 }
2011 dont_switch_tcbs:
2012
2013 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
2014 if (!skip_startup_execve)
2015 detach(tcp);
2016 /* This was initial execve for "strace PROG". Skip. */
2017 skip_startup_execve = 0;
2018 }
2019
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002020 /* Set current output file */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01002021 current_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002022
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002023 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002024 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2025 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002026 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07002027
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002028 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002029 if (pid == strace_child)
2030 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002031 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002032 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2033 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002034#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01002035 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00002036 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002037 WCOREDUMP(status) ? "(core dumped) " : "");
2038#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002039 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002040 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00002041#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002042 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002043 }
2044 droptcb(tcp);
2045 continue;
2046 }
2047 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002048 if (pid == strace_child)
2049 exit_code = WEXITSTATUS(status);
Denys Vlasenkob5e09082012-03-21 14:27:40 +01002050 if (cflag != CFLAG_ONLY_STATS) {
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002051 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01002052 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002053 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002054 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002055 droptcb(tcp);
2056 continue;
2057 }
2058 if (!WIFSTOPPED(status)) {
2059 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2060 droptcb(tcp);
2061 continue;
2062 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002063
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002064 /* Is this the very first time we see this tracee stopped? */
2065 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002066 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002067 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002068 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002069 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002070 /*
2071 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002072 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002073 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002074 if (clearbpt(tcp) < 0) {
2075 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002076 droptcb(tcp);
2077 cleanup();
2078 return -1;
2079 }
2080 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002081 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002082 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002083 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2084 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2085 if (errno != ESRCH) {
2086 /* Should never happen, really */
2087 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002088 }
2089 }
2090 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002091 }
2092
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002093 sig = WSTOPSIG(status);
2094
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002095 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002096 /* Ptrace event */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01002097#if USE_SEIZE
Denys Vlasenko26bc0602012-07-10 16:36:32 +02002098 if (event == PTRACE_EVENT_STOP) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002099 /*
2100 * PTRACE_INTERRUPT-stop or group-stop.
2101 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2102 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002103 if (sig == SIGSTOP
2104 || sig == SIGTSTP
2105 || sig == SIGTTIN
2106 || sig == SIGTTOU
2107 ) {
2108 stopped = 1;
2109 goto show_stopsig;
2110 }
2111 }
2112#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002113 goto restart_tracee_with_sig_0;
2114 }
2115
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002116 /* Is this post-attach SIGSTOP?
2117 * Interestingly, the process may stop
2118 * with STOPSIG equal to some other signal
2119 * than SIGSTOP if we happend to attach
2120 * just before the process takes a signal.
2121 */
2122 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002123 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002124 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2125 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002126 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002127 }
2128
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002129 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002130 siginfo_t si;
2131
2132 /* Nonzero (true) if tracee is stopped by signal
2133 * (as opposed to "tracee received signal").
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002134 * TODO: shouldn't we check for errno == EINVAL too?
2135 * We can get ESRCH instead, you know...
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002136 */
2137 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01002138#if USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002139 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002140#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002141 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002142 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002143#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002144 long pc = 0;
2145 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002146
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002147 upeek(tcp, PT_CR_IPSR, &psr);
2148 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002149
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002150# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002151 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002152# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002153# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002154#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002155# define PC_FORMAT_STR ""
2156# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002157#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002158 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002159 if (!stopped) {
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002160 tprintf("--- %s ", signame(sig));
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002161 printsiginfo(&si, verbose(tcp));
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002162 tprintf(PC_FORMAT_STR " ---\n"
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002163 PC_FORMAT_ARG);
2164 } else
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002165 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002166 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002167 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002168 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002169 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002170
2171 if (!stopped)
2172 /* It's signal-delivery-stop. Inject the signal */
2173 goto restart_tracee;
2174
2175 /* It's group-stop */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +01002176#if USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002177 if (use_seize) {
2178 /*
2179 * This ends ptrace-stop, but does *not* end group-stop.
2180 * This makes stopping signals work properly on straced process
2181 * (that is, process really stops. It used to continue to run).
2182 */
2183 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2184 cleanup();
2185 return -1;
2186 }
2187 continue;
2188 }
2189 /* We don't have PTRACE_LISTEN support... */
2190#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002191 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002192 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002193
2194 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002195 if (interrupted)
2196 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002197
2198 /* This should be syscall entry or exit.
2199 * (Or it still can be that pesky post-execve SIGTRAP!)
2200 * Handle it.
2201 */
Denys Vlasenko23506752012-03-21 10:32:49 +01002202 if (trace_syscall(tcp) < 0) {
2203 /* ptrace() failed in trace_syscall().
Roland McGratheb9e2e82009-06-02 16:49:22 -07002204 * Likely a result of process disappearing mid-flight.
Denys Vlasenko23506752012-03-21 10:32:49 +01002205 * Observed case: exit_group() or SIGKILL terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002206 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002207 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002208 * We used to detach(tcp) here, but since we no longer
2209 * implement "detach before death" policy/hack,
2210 * we can let this process to report its death to us
2211 * normally, via WIFEXITED or WIFSIGNALED wait status.
2212 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002213 continue;
2214 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002215 restart_tracee_with_sig_0:
2216 sig = 0;
2217 restart_tracee:
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002218 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002219 cleanup();
2220 return -1;
2221 }
2222 }
2223 return 0;
2224}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002225
2226int
2227main(int argc, char *argv[])
2228{
2229 init(argc, argv);
2230
2231 /* Run main tracing loop */
2232 if (trace() < 0)
2233 return 1;
2234
2235 cleanup();
2236 fflush(NULL);
Dmitry V. Levincf534362012-07-12 20:54:46 +00002237 if (shared_log != stderr)
2238 fclose(shared_log);
2239 if (popen_pid) {
2240 while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR)
2241 ;
2242 }
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002243 if (exit_code > 0xff) {
2244 /* Avoid potential core file clobbering. */
2245 struct rlimit rlim = {0, 0};
2246 setrlimit(RLIMIT_CORE, &rlim);
2247
2248 /* Child was killed by a signal, mimic that. */
2249 exit_code &= 0xff;
2250 signal(exit_code, SIG_DFL);
2251 raise(exit_code);
2252 /* Paranoia - what if this signal is not fatal?
2253 Exit with 128 + signo then. */
2254 exit_code += 128;
2255 }
2256
2257 return exit_code;
2258}