blob: bc98d365e9d276ff9c1f7e972bab755b2e135c51 [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 Vlasenkoa50d2a82012-03-15 12:49:52 +010061cflag_t cflag = CFLAG_NONE;
62unsigned int followfork = 0;
Denys Vlasenkof44cce42011-06-21 14:34:10 +020063unsigned int ptrace_setoptions = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010064unsigned int xflag = 0;
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +010065bool need_fork_exec_workarounds = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010066bool debug_flag = 0;
67bool Tflag = 0;
68bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020069/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020070static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010071static unsigned int tflag = 0;
72static bool iflag = 0;
73static bool rflag = 0;
74static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010075
76/* -I n */
77enum {
78 INTR_NOT_SET = 0,
79 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
80 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
81 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
82 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
83 NUM_INTR_OPTS
84};
85static int opt_intr;
86/* We play with signal mask only if this mode is active: */
87#define interactive (opt_intr == INTR_WHILE_WAIT)
88
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000089/*
90 * daemonized_tracer supports -D option.
91 * With this option, strace forks twice.
92 * Unlike normal case, with -D *grandparent* process exec's,
93 * becoming a traced process. Child exits (this prevents traced process
94 * from having children it doesn't expect to have), and grandchild
95 * attaches to grandparent similarly to strace -p PID.
96 * This allows for more transparent interaction in cases
97 * when process and its parent are communicating via signals,
98 * wait() etc. Without -D, strace process gets lodged in between,
99 * disrupting parent<->child link.
100 */
101static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000102
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100103#ifdef USE_SEIZE
104static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
105# define use_seize (post_attach_sigstop == 0)
106#else
107# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
108# define use_seize 0
109#endif
110
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000111/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100112bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000113
Grant Edwards8a082772011-04-07 20:25:40 +0000114/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100115bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000116
117/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100118bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000119
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100120static bool detach_on_execve = 0;
121static bool skip_startup_execve = 0;
122
Dmitry V. Levina6809652008-11-10 17:14:58 +0000123static int exit_code = 0;
124static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200125static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700126
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000127static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200128static uid_t run_uid;
129static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000130
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100131unsigned int max_strlen = DEFAULT_STRLEN;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000132static int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200133static char *acolumn_spaces;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100134
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000135static char *outfname = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100136/* If -ff, points to stderr. Else, it's our common output log */
137static FILE *shared_log;
138
Denys Vlasenko000b6012012-01-28 01:25:03 +0100139struct tcb *printing_tcp = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100140static struct tcb *current_tcp;
141
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200142static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200143static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200144static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000145
Denys Vlasenkoeec8d5d2013-02-14 03:29:48 +0100146unsigned os_release; /* generated from uname()'s u.release */
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100147
Denys Vlasenko4c196382012-01-04 15:11:09 +0100148static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100149static int trace(void);
150static void cleanup(void);
151static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000152static sigset_t empty_set, blocked_set;
153
154#ifdef HAVE_SIG_ATOMIC_T
155static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100156#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000157static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100158#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000159
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100160#ifndef HAVE_STRERROR
161
162#if !HAVE_DECL_SYS_ERRLIST
163extern int sys_nerr;
164extern char *sys_errlist[];
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +0100165#endif
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100166
167const char *
168strerror(int err_no)
169{
170 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
171
172 if (err_no < 1 || err_no >= sys_nerr) {
173 sprintf(buf, "Unknown error %d", err_no);
174 return buf;
175 }
176 return sys_errlist[err_no];
177}
178
179#endif /* HAVE_STERRROR */
180
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000181static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200182usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000183{
184 fprintf(ofp, "\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200185usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
186 [-a column] [-o file] [-s strsize] [-P path]...\n\
187 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
188 or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
189 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000190-c -- count time, calls, and errors for each syscall and report summary\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200191-C -- like -c but also print regular output\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100192-d -- enable debug output to stderr\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100193-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000194-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100195-F -- attempt to follow vforks (deprecated, use -f)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000196-i -- print instruction pointer at time of syscall\n\
197-q -- suppress messages about attaching, detaching, etc.\n\
198-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100199-T -- print time spent in each syscall\n\
200-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000201-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000202-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200203-h -- print help message, -V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000204-a column -- alignment COLUMN for printing syscall results (default %d)\n\
205-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
206 options: trace, abbrev, verbose, raw, signal, read, or write\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200207-I interruptible --\n\
208 1: no signals are blocked\n\
209 2: fatal signals are blocked while decoding syscall (default)\n\
210 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
211 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
212 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000213-o file -- send trace output to FILE instead of stderr\n\
214-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
215-p pid -- trace process with process id PID, may be repeated\n\
216-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
217-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
218-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000219-E var=val -- put var=val in the environment for command\n\
220-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000221-P path -- trace accesses to path\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100222"
223/* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000224-z -- print only succeeding syscalls\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100225 */
226/* experimental, don't document it yet (option letter may change in the future!)
227-b -- detach on successful execve\n\
228 */
Roland McGrathde6e5332003-01-24 04:31:23 +0000229, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000230 exit(exitval);
231}
232
Denys Vlasenko75422762011-05-27 14:36:01 +0200233static void die(void) __attribute__ ((noreturn));
234static void die(void)
235{
236 if (strace_tracer_pid == getpid()) {
237 cflag = 0;
238 cleanup();
239 }
240 exit(1);
241}
242
243static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200244{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100245 char *msg;
246
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000247 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100248
249 /* We want to print entire message with single fprintf to ensure
250 * message integrity if stderr is shared with other programs.
251 * Thus we use vasprintf + single fprintf.
252 */
253 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100254 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100255 if (err_no)
256 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
257 else
258 fprintf(stderr, "%s: %s\n", progname, msg);
259 free(msg);
260 } else {
261 /* malloc in vasprintf failed, try it without malloc */
262 fprintf(stderr, "%s: ", progname);
263 vfprintf(stderr, fmt, p);
264 if (err_no)
265 fprintf(stderr, ": %s\n", strerror(err_no));
266 else
267 putc('\n', stderr);
268 }
269 /* We don't switch stderr to buffered, thus fprintf(stderr)
270 * always flushes its output and this is not necessary: */
271 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200272}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200273
Denys Vlasenko75422762011-05-27 14:36:01 +0200274void error_msg(const char *fmt, ...)
275{
276 va_list p;
277 va_start(p, fmt);
278 verror_msg(0, fmt, p);
279 va_end(p);
280}
281
282void error_msg_and_die(const char *fmt, ...)
283{
284 va_list p;
285 va_start(p, fmt);
286 verror_msg(0, fmt, p);
287 die();
288}
289
290void perror_msg(const char *fmt, ...)
291{
292 va_list p;
293 va_start(p, fmt);
294 verror_msg(errno, fmt, p);
295 va_end(p);
296}
297
298void perror_msg_and_die(const char *fmt, ...)
299{
300 va_list p;
301 va_start(p, fmt);
302 verror_msg(errno, fmt, p);
303 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200304}
305
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200306void die_out_of_memory(void)
307{
308 static bool recursed = 0;
309 if (recursed)
310 exit(1);
311 recursed = 1;
312 error_msg_and_die("Out of memory");
313}
314
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000315static void
316error_opt_arg(int opt, const char *arg)
317{
318 error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
319}
320
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400321/* Glue for systems without a MMU that cannot provide fork() */
322#ifdef HAVE_FORK
323# define strace_vforked 0
324#else
325# define strace_vforked 1
326# define fork() vfork()
327#endif
328
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100329#ifdef USE_SEIZE
330static int
331ptrace_attach_or_seize(int pid)
332{
333 int r;
334 if (!use_seize)
335 return ptrace(PTRACE_ATTACH, pid, 0, 0);
Denys Vlasenko26bc0602012-07-10 16:36:32 +0200336 r = ptrace(PTRACE_SEIZE, pid, 0, 0);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100337 if (r)
338 return r;
339 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
340 return r;
341}
342#else
343# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
344#endif
345
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100346/*
347 * Used when we want to unblock stopped traced process.
348 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
349 * Returns 0 on success or if error was ESRCH
350 * (presumably process was killed while we talk to it).
351 * Otherwise prints error message and returns -1.
352 */
353static int
354ptrace_restart(int op, struct tcb *tcp, int sig)
355{
356 int err;
357 const char *msg;
358
359 errno = 0;
360 ptrace(op, tcp->pid, (void *) 0, (long) sig);
361 err = errno;
Denys Vlasenko23506752012-03-21 10:32:49 +0100362 if (!err)
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100363 return 0;
364
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100365 msg = "SYSCALL";
366 if (op == PTRACE_CONT)
367 msg = "CONT";
368 if (op == PTRACE_DETACH)
369 msg = "DETACH";
370#ifdef PTRACE_LISTEN
371 if (op == PTRACE_LISTEN)
372 msg = "LISTEN";
373#endif
Denys Vlasenko23506752012-03-21 10:32:49 +0100374 /*
375 * Why curcol != 0? Otherwise sometimes we get this:
376 *
377 * 10252 kill(10253, SIGKILL) = 0
378 * <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
379 *
380 * 10252 died after we retrieved syscall exit data,
381 * but before we tried to restart it. Log looks ugly.
382 */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100383 if (current_tcp && current_tcp->curcol != 0) {
Denys Vlasenko23506752012-03-21 10:32:49 +0100384 tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
385 line_ended();
386 }
387 if (err == ESRCH)
388 return 0;
389 errno = err;
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100390 perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
391 return -1;
392}
393
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200394static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000395set_cloexec_flag(int fd)
396{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200397 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000398
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200399 flags = fcntl(fd, F_GETFD);
400 if (flags < 0) {
401 /* Can happen only if fd is bad.
402 * Should never happen: if it does, we have a bug
403 * in the caller. Therefore we just abort
404 * instead of propagating the error.
405 */
406 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000407 }
408
409 newflags = flags | FD_CLOEXEC;
410 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200411 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000412
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200413 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000414}
415
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100416static void kill_save_errno(pid_t pid, int sig)
417{
418 int saved_errno = errno;
419
420 (void) kill(pid, sig);
421 errno = saved_errno;
422}
423
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100424/*
425 * When strace is setuid executable, we have to swap uids
426 * before and after filesystem and process management operations.
427 */
428static void
429swap_uid(void)
430{
431 int euid = geteuid(), uid = getuid();
432
433 if (euid != uid && setreuid(euid, uid) < 0) {
434 perror_msg_and_die("setreuid");
435 }
436}
437
438#if _LFS64_LARGEFILE
439# define fopen_for_output fopen64
440#else
441# define fopen_for_output fopen
442#endif
443
444static FILE *
445strace_fopen(const char *path)
446{
447 FILE *fp;
448
449 swap_uid();
450 fp = fopen_for_output(path, "w");
451 if (!fp)
452 perror_msg_and_die("Can't fopen '%s'", path);
453 swap_uid();
454 set_cloexec_flag(fileno(fp));
455 return fp;
456}
457
458static int popen_pid = 0;
459
460#ifndef _PATH_BSHELL
461# define _PATH_BSHELL "/bin/sh"
462#endif
463
464/*
465 * We cannot use standard popen(3) here because we have to distinguish
466 * popen child process from other processes we trace, and standard popen(3)
467 * does not export its child's pid.
468 */
469static FILE *
470strace_popen(const char *command)
471{
472 FILE *fp;
473 int fds[2];
474
475 swap_uid();
476 if (pipe(fds) < 0)
477 perror_msg_and_die("pipe");
478
479 set_cloexec_flag(fds[1]); /* never fails */
480
481 popen_pid = vfork();
482 if (popen_pid == -1)
483 perror_msg_and_die("vfork");
484
485 if (popen_pid == 0) {
486 /* child */
487 close(fds[1]);
488 if (fds[0] != 0) {
489 if (dup2(fds[0], 0))
490 perror_msg_and_die("dup2");
491 close(fds[0]);
492 }
493 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
494 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
495 }
496
497 /* parent */
498 close(fds[0]);
499 swap_uid();
500 fp = fdopen(fds[1], "w");
501 if (!fp)
502 die_out_of_memory();
503 return fp;
504}
505
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100506void
507tprintf(const char *fmt, ...)
508{
509 va_list args;
510
511 va_start(args, fmt);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100512 if (current_tcp) {
Denys Vlasenko6e4f3c12012-04-16 18:22:19 +0200513 int n = strace_vfprintf(current_tcp->outf, fmt, args);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100514 if (n < 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100515 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000516 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100517 } else
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100518 current_tcp->curcol += n;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100519 }
520 va_end(args);
521}
522
523void
524tprints(const char *str)
525{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100526 if (current_tcp) {
Denys Vlasenko142aee02012-04-16 18:10:15 +0200527 int n = fputs_unlocked(str, current_tcp->outf);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100528 if (n >= 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100529 current_tcp->curcol += strlen(str);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100530 return;
531 }
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100532 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000533 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100534 }
535}
536
537void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100538line_ended(void)
539{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100540 if (current_tcp) {
541 current_tcp->curcol = 0;
542 fflush(current_tcp->outf);
543 }
544 if (printing_tcp) {
545 printing_tcp->curcol = 0;
546 printing_tcp = NULL;
547 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100548}
549
550void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100551printleader(struct tcb *tcp)
552{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100553 /* If -ff, "previous tcb we printed" is always the same as current,
554 * because we have per-tcb output files.
555 */
556 if (followfork >= 2)
557 printing_tcp = tcp;
558
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100559 if (printing_tcp) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100560 current_tcp = printing_tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100561 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
562 /*
563 * case 1: we have a shared log (i.e. not -ff), and last line
564 * wasn't finished (same or different tcb, doesn't matter).
565 * case 2: split log, we are the same tcb, but our last line
566 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
567 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100568 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100569 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100570 }
571 }
572
573 printing_tcp = tcp;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100574 current_tcp = tcp;
575 current_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100576
577 if (print_pid_pfx)
578 tprintf("%-5d ", tcp->pid);
579 else if (nprocs > 1 && !outfname)
580 tprintf("[pid %5u] ", tcp->pid);
581
582 if (tflag) {
583 char str[sizeof("HH:MM:SS")];
584 struct timeval tv, dtv;
585 static struct timeval otv;
586
587 gettimeofday(&tv, NULL);
588 if (rflag) {
589 if (otv.tv_sec == 0)
590 otv = tv;
591 tv_sub(&dtv, &tv, &otv);
592 tprintf("%6ld.%06ld ",
593 (long) dtv.tv_sec, (long) dtv.tv_usec);
594 otv = tv;
595 }
596 else if (tflag > 2) {
597 tprintf("%ld.%06ld ",
598 (long) tv.tv_sec, (long) tv.tv_usec);
599 }
600 else {
601 time_t local = tv.tv_sec;
602 strftime(str, sizeof(str), "%T", localtime(&local));
603 if (tflag > 1)
604 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
605 else
606 tprintf("%s ", str);
607 }
608 }
609 if (iflag)
610 printcall(tcp);
611}
612
613void
614tabto(void)
615{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100616 if (current_tcp->curcol < acolumn)
617 tprints(acolumn_spaces + current_tcp->curcol);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100618}
619
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100620/* Should be only called directly *after successful attach* to a tracee.
621 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
622 * may create bogus empty FILE.<nonexistant_pid>, and then die.
623 */
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200624static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000625newoutf(struct tcb *tcp)
626{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100627 tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100628 if (followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000629 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000630 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200631 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000632 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000633}
634
Denys Vlasenko558e5122012-03-12 23:32:16 +0100635static void
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100636expand_tcbtab(void)
637{
638 /* Allocate some more TCBs and expand the table.
639 We don't want to relocate the TCBs because our
640 callers have pointers and it would be a pain.
641 So tcbtab is a table of pointers. Since we never
642 free the TCBs, we allocate a single chunk of many. */
643 int i = tcbtabsize;
644 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
645 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
646 if (!newtab || !newtcbs)
647 die_out_of_memory();
648 tcbtabsize *= 2;
649 tcbtab = newtab;
650 while (i < tcbtabsize)
651 tcbtab[i++] = newtcbs++;
652}
653
654static struct tcb *
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100655alloctcb(int pid)
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100656{
657 int i;
658 struct tcb *tcp;
659
660 if (nprocs == tcbtabsize)
661 expand_tcbtab();
662
663 for (i = 0; i < tcbtabsize; i++) {
664 tcp = tcbtab[i];
665 if ((tcp->flags & TCB_INUSE) == 0) {
666 memset(tcp, 0, sizeof(*tcp));
667 tcp->pid = pid;
668 tcp->flags = TCB_INUSE;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100669#if SUPPORTED_PERSONALITIES > 1
670 tcp->currpers = current_personality;
671#endif
672 nprocs++;
673 if (debug_flag)
674 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100675 return tcp;
676 }
677 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100678 error_msg_and_die("bug in alloctcb");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100679}
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100680
681static void
682droptcb(struct tcb *tcp)
683{
684 if (tcp->pid == 0)
685 return;
686
687 nprocs--;
688 if (debug_flag)
689 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
690
691 if (tcp->outf) {
Denys Vlasenko8511f2a2012-03-22 09:35:51 +0100692 if (followfork >= 2) {
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100693 if (tcp->curcol != 0)
694 fprintf(tcp->outf, " <detached ...>\n");
695 fclose(tcp->outf);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100696 } else {
697 if (printing_tcp == tcp && tcp->curcol != 0)
698 fprintf(tcp->outf, " <detached ...>\n");
699 fflush(tcp->outf);
700 }
701 }
702
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100703 if (current_tcp == tcp)
704 current_tcp = NULL;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100705 if (printing_tcp == tcp)
706 printing_tcp = NULL;
707
708 memset(tcp, 0, sizeof(*tcp));
709}
710
711/* detach traced process; continue with sig
712 * Never call DETACH twice on the same process as both unattached and
713 * attached-unstopped processes give the same ESRCH. For unattached process we
714 * would SIGSTOP it and wait for its SIGSTOP notification forever.
715 */
716static int
717detach(struct tcb *tcp)
718{
719 int error;
720 int status, sigstop_expected;
721
722 if (tcp->flags & TCB_BPTSET)
723 clearbpt(tcp);
724
725 /*
726 * Linux wrongly insists the child be stopped
727 * before detaching. Arghh. We go through hoops
728 * to make a clean break of things.
729 */
730#if defined(SPARC)
Denys Vlasenko978fbc92012-09-13 10:28:43 +0200731# undef PTRACE_DETACH
732# define PTRACE_DETACH PTRACE_SUNDETACH
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100733#endif
734
735 error = 0;
736 sigstop_expected = 0;
737 if (tcp->flags & TCB_ATTACHED) {
738 /*
739 * We attached but possibly didn't see the expected SIGSTOP.
740 * We must catch exactly one as otherwise the detached process
741 * would be left stopped (process state T).
742 */
743 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
744 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
745 if (error == 0) {
746 /* On a clear day, you can see forever. */
747 }
748 else if (errno != ESRCH) {
749 /* Shouldn't happen. */
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000750 perror_msg("%s", "detach: ptrace(PTRACE_DETACH, ...)");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100751 }
752 else if (my_tkill(tcp->pid, 0) < 0) {
753 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000754 perror_msg("%s", "detach: checking sanity");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100755 }
756 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
757 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000758 perror_msg("%s", "detach: stopping child");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100759 }
760 else
761 sigstop_expected = 1;
762 }
763
764 if (sigstop_expected) {
765 for (;;) {
766#ifdef __WALL
767 if (waitpid(tcp->pid, &status, __WALL) < 0) {
768 if (errno == ECHILD) /* Already gone. */
769 break;
770 if (errno != EINVAL) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000771 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100772 break;
773 }
774#endif /* __WALL */
775 /* No __WALL here. */
776 if (waitpid(tcp->pid, &status, 0) < 0) {
777 if (errno != ECHILD) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000778 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100779 break;
780 }
781#ifdef __WCLONE
782 /* If no processes, try clones. */
783 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
784 if (errno != ECHILD)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000785 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100786 break;
787 }
788#endif /* __WCLONE */
789 }
790#ifdef __WALL
791 }
792#endif
793 if (!WIFSTOPPED(status)) {
794 /* Au revoir, mon ami. */
795 break;
796 }
797 if (WSTOPSIG(status) == SIGSTOP) {
798 ptrace_restart(PTRACE_DETACH, tcp, 0);
799 break;
800 }
801 error = ptrace_restart(PTRACE_CONT, tcp,
802 WSTOPSIG(status) == syscall_trap_sig ? 0
803 : WSTOPSIG(status));
804 if (error < 0)
805 break;
806 }
807 }
808
809 if (!qflag && (tcp->flags & TCB_ATTACHED))
810 fprintf(stderr, "Process %u detached\n", tcp->pid);
811
812 droptcb(tcp);
813
814 return error;
815}
816
817static void
Denys Vlasenko558e5122012-03-12 23:32:16 +0100818process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100819{
820 while (*opt) {
821 /*
822 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
823 * pidof uses space as delim, pgrep uses newline. :(
824 */
825 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100826 char *delim = opt + strcspn(opt, ", \n\t");
827 char c = *delim;
828
829 *delim = '\0';
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000830 pid = string_to_uint(opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100831 if (pid <= 0) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000832 error_msg_and_die("Invalid process id: '%s'", opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100833 }
834 if (pid == strace_tracer_pid) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000835 error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100836 }
837 *delim = c;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100838 alloctcb(pid);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100839 if (c == '\0')
840 break;
841 opt = delim + 1;
842 }
843}
844
Roland McGrath02203312007-06-11 22:06:31 +0000845static void
846startup_attach(void)
847{
848 int tcbi;
849 struct tcb *tcp;
850
851 /*
852 * Block user interruptions as we would leave the traced
853 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200854 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200855 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000856 */
857 if (interactive)
858 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
859
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000860 if (daemonized_tracer) {
861 pid_t pid = fork();
862 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200863 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000864 }
865 if (pid) { /* parent */
866 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200867 * Wait for grandchild to attach to straced process
868 * (grandparent). Grandchild SIGKILLs us after it attached.
869 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000870 * it proceeds to exec the straced program.
871 */
872 pause();
873 _exit(0); /* paranoia */
874 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200875 /* grandchild */
876 /* We will be the tracer process. Remember our new pid: */
877 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000878 }
879
Roland McGrath02203312007-06-11 22:06:31 +0000880 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
881 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200882
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100883 if (!(tcp->flags & TCB_INUSE))
884 continue;
885
Denys Vlasenkod116a732011-09-05 14:01:33 +0200886 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100887 if (tcp->flags & TCB_ATTACHED)
888 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200889
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000890 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000891 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000892 DIR *dir;
893
894 sprintf(procdir, "/proc/%d/task", tcp->pid);
895 dir = opendir(procdir);
896 if (dir != NULL) {
897 unsigned int ntid = 0, nerr = 0;
898 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200899
Roland McGrath02203312007-06-11 22:06:31 +0000900 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200901 struct tcb *cur_tcp;
902 int tid;
903
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000904 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000905 continue;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000906 /* we trust /proc filesystem */
Roland McGrath02203312007-06-11 22:06:31 +0000907 tid = atoi(de->d_name);
908 if (tid <= 0)
909 continue;
910 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100911 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000912 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100913 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200914 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200915 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200916 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100917 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200918 fprintf(stderr, "attach to pid %d succeeded\n", tid);
919 cur_tcp = tcp;
920 if (tid != tcp->pid)
921 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100922 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100923 newoutf(cur_tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000924 }
925 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200926 if (interactive) {
927 sigprocmask(SIG_SETMASK, &empty_set, NULL);
928 if (interrupted)
929 goto ret;
930 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
931 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000932 ntid -= nerr;
933 if (ntid == 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000934 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000935 droptcb(tcp);
936 continue;
937 }
938 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000939 fprintf(stderr, ntid > 1
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100940? "Process %u attached with %u threads\n"
941: "Process %u attached\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200942 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000943 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100944 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200945 /* -p PID, we failed to attach to PID itself
946 * but did attach to some of its sibling threads.
947 * Drop PID's tcp.
948 */
949 droptcb(tcp);
950 }
Roland McGrath02203312007-06-11 22:06:31 +0000951 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000952 } /* if (opendir worked) */
953 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100954 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000955 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000956 droptcb(tcp);
957 continue;
958 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100959 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100960 newoutf(tcp);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100961 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200962 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000963
964 if (daemonized_tracer) {
965 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000966 * Make parent go away.
967 * Also makes grandparent's wait() unblock.
968 */
969 kill(getppid(), SIGKILL);
970 }
971
Roland McGrath02203312007-06-11 22:06:31 +0000972 if (!qflag)
973 fprintf(stderr,
Denys Vlasenko9c3861d2012-03-16 15:21:49 +0100974 "Process %u attached\n",
Roland McGrath02203312007-06-11 22:06:31 +0000975 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200976 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000977
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200978 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000979 if (interactive)
980 sigprocmask(SIG_SETMASK, &empty_set, NULL);
981}
982
983static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200984startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000985{
986 struct stat statbuf;
987 const char *filename;
988 char pathname[MAXPATHLEN];
989 int pid = 0;
990 struct tcb *tcp;
991
992 filename = argv[0];
993 if (strchr(filename, '/')) {
994 if (strlen(filename) > sizeof pathname - 1) {
995 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200996 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000997 }
998 strcpy(pathname, filename);
999 }
1000#ifdef USE_DEBUGGING_EXEC
1001 /*
1002 * Debuggers customarily check the current directory
1003 * first regardless of the path but doing that gives
1004 * security geeks a panic attack.
1005 */
1006 else if (stat(filename, &statbuf) == 0)
1007 strcpy(pathname, filename);
1008#endif /* USE_DEBUGGING_EXEC */
1009 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +00001010 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +00001011 int m, n, len;
1012
1013 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +01001014 const char *colon = strchr(path, ':');
1015 if (colon) {
1016 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +00001017 m = n + 1;
1018 }
1019 else
1020 m = n = strlen(path);
1021 if (n == 0) {
1022 if (!getcwd(pathname, MAXPATHLEN))
1023 continue;
1024 len = strlen(pathname);
1025 }
1026 else if (n > sizeof pathname - 1)
1027 continue;
1028 else {
1029 strncpy(pathname, path, n);
1030 len = n;
1031 }
1032 if (len && pathname[len - 1] != '/')
1033 pathname[len++] = '/';
1034 strcpy(pathname + len, filename);
1035 if (stat(pathname, &statbuf) == 0 &&
1036 /* Accept only regular files
1037 with some execute bits set.
1038 XXX not perfect, might still fail */
1039 S_ISREG(statbuf.st_mode) &&
1040 (statbuf.st_mode & 0111))
1041 break;
1042 }
1043 }
1044 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001045 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +00001046 }
Dmitry V. Levina6809652008-11-10 17:14:58 +00001047 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001048 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001049 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001050 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001051 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1052 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001053 ) {
1054 pid = getpid();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001055 if (shared_log != stderr)
1056 close(fileno(shared_log));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001057 if (!daemonized_tracer && !use_seize) {
1058 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001059 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001060 }
Roland McGrath02203312007-06-11 22:06:31 +00001061 }
Roland McGrath02203312007-06-11 22:06:31 +00001062
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001063 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +00001064 uid_t run_euid = run_uid;
1065 gid_t run_egid = run_gid;
1066
1067 if (statbuf.st_mode & S_ISUID)
1068 run_euid = statbuf.st_uid;
1069 if (statbuf.st_mode & S_ISGID)
1070 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +00001071 /*
1072 * It is important to set groups before we
1073 * lose privileges on setuid.
1074 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001075 if (initgroups(username, run_gid) < 0) {
1076 perror_msg_and_die("initgroups");
1077 }
1078 if (setregid(run_gid, run_egid) < 0) {
1079 perror_msg_and_die("setregid");
1080 }
1081 if (setreuid(run_uid, run_euid) < 0) {
1082 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +00001083 }
1084 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001085 else if (geteuid() != 0)
Dmitry V. Levin508279c2012-08-24 17:56:53 +00001086 if (setreuid(run_uid, run_uid) < 0) {
1087 perror_msg_and_die("setreuid");
1088 }
Roland McGrath02203312007-06-11 22:06:31 +00001089
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001090 if (!daemonized_tracer) {
1091 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001092 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001093 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001094 * the immediately following execve syscall.
1095 * Can't do this on NOMMU systems, we are after
1096 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001097 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -04001098 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001099 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001100 } else {
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001101 alarm(3);
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001102 /* we depend on SIGCHLD set to SIG_DFL by init code */
1103 /* if it happens to be SIG_IGN'ed, wait won't block */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001104 wait(NULL);
1105 alarm(0);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001106 }
Roland McGrath02203312007-06-11 22:06:31 +00001107
1108 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001109 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +00001110 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001111
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001112 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +02001113
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001114 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001115 if (!use_seize) {
1116 /* child did PTRACE_TRACEME, nothing to do in parent */
1117 } else {
1118 if (!strace_vforked) {
1119 /* Wait until child stopped itself */
1120 int status;
1121 while (waitpid(pid, &status, WSTOPPED) < 0) {
1122 if (errno == EINTR)
1123 continue;
1124 perror_msg_and_die("waitpid");
1125 }
1126 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001127 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001128 perror_msg_and_die("Unexpected wait status %x", status);
1129 }
1130 }
1131 /* Else: vforked case, we have no way to sync.
1132 * Just attach to it as soon as possible.
1133 * This means that we may miss a few first syscalls...
1134 */
1135
1136 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001137 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001138 perror_msg_and_die("Can't attach to %d", pid);
1139 }
1140 if (!strace_vforked)
1141 kill(pid, SIGCONT);
1142 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001143 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001144 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001145 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001146 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001147 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001148 newoutf(tcp);
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001149 }
1150 else {
1151 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1152 strace_tracer_pid = getpid();
1153 /* The tracee is our parent: */
1154 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +01001155 alloctcb(pid);
1156 /* attaching will be done later, by startup_attach */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001157 /* note: we don't do newoutf(tcp) here either! */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001158 }
Roland McGrath02203312007-06-11 22:06:31 +00001159}
1160
Wang Chaob13c0de2010-11-12 17:25:19 +08001161/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001162 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +08001163 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001164 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +08001165 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001166static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001167test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +08001168{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001169 int pid, expected_grandchild = 0, found_grandchild = 0;
1170 const unsigned int test_options = PTRACE_O_TRACECLONE |
1171 PTRACE_O_TRACEFORK |
1172 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +08001173
Denys Vlasenko5d645812011-08-20 12:48:18 +02001174 pid = fork();
1175 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001176 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +02001177 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001178 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001179 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001180 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1181 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001182 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001183 if (fork() < 0)
1184 perror_msg_and_die("fork");
1185 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +08001186 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001187
1188 while (1) {
1189 int status, tracee_pid;
1190
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001191 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001192 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001193 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001194 if (errno == EINTR)
1195 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001196 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001197 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001198 kill_save_errno(pid, SIGKILL);
1199 perror_msg_and_die("%s: unexpected wait result %d",
1200 __func__, tracee_pid);
1201 }
1202 if (WIFEXITED(status)) {
1203 if (WEXITSTATUS(status)) {
1204 if (tracee_pid != pid)
1205 kill_save_errno(pid, SIGKILL);
1206 error_msg_and_die("%s: unexpected exit status %u",
1207 __func__, WEXITSTATUS(status));
1208 }
1209 continue;
1210 }
1211 if (WIFSIGNALED(status)) {
1212 if (tracee_pid != pid)
1213 kill_save_errno(pid, SIGKILL);
1214 error_msg_and_die("%s: unexpected signal %u",
1215 __func__, WTERMSIG(status));
1216 }
1217 if (!WIFSTOPPED(status)) {
1218 if (tracee_pid != pid)
1219 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001220 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001221 error_msg_and_die("%s: unexpected wait status %x",
1222 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001223 }
1224 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001225 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001226 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1227 kill_save_errno(tracee_pid, SIGKILL);
1228 kill_save_errno(pid, SIGKILL);
1229 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001230 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001231 continue;
1232 }
1233 switch (WSTOPSIG(status)) {
1234 case SIGSTOP:
1235 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1236 && errno != EINVAL && errno != EIO)
1237 perror_msg("PTRACE_SETOPTIONS");
1238 break;
1239 case SIGTRAP:
1240 if (status >> 16 == PTRACE_EVENT_FORK) {
1241 long msg = 0;
1242
1243 if (ptrace(PTRACE_GETEVENTMSG, pid,
1244 NULL, (long) &msg) == 0)
1245 expected_grandchild = msg;
1246 }
1247 break;
1248 }
1249 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1250 kill_save_errno(pid, SIGKILL);
1251 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001252 }
1253 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001254 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001255 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001256 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001257 fprintf(stderr, "ptrace_setoptions = %#x\n",
1258 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001259 return 0;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001260 }
1261 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1262 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001263 return 1;
Wang Chaob13c0de2010-11-12 17:25:19 +08001264}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001265
1266/*
1267 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1268 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1269 * and then see whether it will stop with (SIGTRAP | 0x80).
1270 *
1271 * Use of this option enables correct handling of user-generated SIGTRAPs,
1272 * and SIGTRAPs generated by special instructions such as int3 on x86:
1273 * _start: .globl _start
1274 * int3
1275 * movl $42, %ebx
1276 * movl $1, %eax
1277 * int $0x80
1278 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1279 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001280static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001281test_ptrace_setoptions_for_all(void)
1282{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001283 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1284 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001285 int pid;
1286 int it_worked = 0;
1287
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001288 /* this fork test doesn't work on no-mmu systems */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001289 /* FIXME: isn't it better to assume we *succeed*? */
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001290 if (strace_vforked)
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001291 return 1;
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001292
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001293 pid = fork();
1294 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001295 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001296
1297 if (pid == 0) {
1298 pid = getpid();
1299 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001300 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001301 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1302 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001303 kill(pid, SIGSTOP);
1304 _exit(0); /* parent should see entry into this syscall */
1305 }
1306
1307 while (1) {
1308 int status, tracee_pid;
1309
1310 errno = 0;
1311 tracee_pid = wait(&status);
1312 if (tracee_pid <= 0) {
1313 if (errno == EINTR)
1314 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001315 kill_save_errno(pid, SIGKILL);
1316 perror_msg_and_die("%s: unexpected wait result %d",
1317 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001318 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001319 if (WIFEXITED(status)) {
1320 if (WEXITSTATUS(status) == 0)
1321 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001322 error_msg_and_die("%s: unexpected exit status %u",
1323 __func__, WEXITSTATUS(status));
1324 }
1325 if (WIFSIGNALED(status)) {
1326 error_msg_and_die("%s: unexpected signal %u",
1327 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001328 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001329 if (!WIFSTOPPED(status)) {
1330 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001331 error_msg_and_die("%s: unexpected wait status %x",
1332 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001333 }
1334 if (WSTOPSIG(status) == SIGSTOP) {
1335 /*
1336 * We don't check "options aren't accepted" error.
1337 * If it happens, we'll never get (SIGTRAP | 0x80),
1338 * and thus will decide to not use the option.
1339 * IOW: the outcome of the test will be correct.
1340 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001341 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1342 && errno != EINVAL && errno != EIO)
1343 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001344 }
1345 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1346 it_worked = 1;
1347 }
1348 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001349 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001350 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001351 }
1352 }
1353
1354 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001355 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001356 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001357 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001358 fprintf(stderr, "ptrace_setoptions = %#x\n",
1359 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001360 return 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001361 }
1362
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001363 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1364 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001365 return 1;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001366}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001367
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001368#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001369static void
1370test_ptrace_seize(void)
1371{
1372 int pid;
1373
1374 pid = fork();
1375 if (pid < 0)
1376 perror_msg_and_die("fork");
1377
1378 if (pid == 0) {
1379 pause();
1380 _exit(0);
1381 }
1382
1383 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1384 * attaching tracee continues to run unless a trap condition occurs.
1385 * PTRACE_SEIZE doesn't affect signal or group stop state.
1386 */
Denys Vlasenko26bc0602012-07-10 16:36:32 +02001387 if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001388 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001389 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001390 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1391 }
1392
1393 kill(pid, SIGKILL);
1394
1395 while (1) {
1396 int status, tracee_pid;
1397
1398 errno = 0;
1399 tracee_pid = waitpid(pid, &status, 0);
1400 if (tracee_pid <= 0) {
1401 if (errno == EINTR)
1402 continue;
1403 perror_msg_and_die("%s: unexpected wait result %d",
1404 __func__, tracee_pid);
1405 }
1406 if (WIFSIGNALED(status)) {
1407 return;
1408 }
1409 error_msg_and_die("%s: unexpected wait status %x",
1410 __func__, status);
1411 }
1412}
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001413#else /* !USE_SEIZE */
1414# define test_ptrace_seize() ((void)0)
1415#endif
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001416
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001417static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001418get_os_release(void)
1419{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001420 unsigned rel;
1421 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001422 struct utsname u;
1423 if (uname(&u) < 0)
1424 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001425 /* u.release has this form: "3.2.9[-some-garbage]" */
1426 rel = 0;
1427 p = u.release;
1428 for (;;) {
1429 if (!(*p >= '0' && *p <= '9'))
1430 error_msg_and_die("Bad OS release string: '%s'", u.release);
1431 /* Note: this open-codes KERNEL_VERSION(): */
1432 rel = (rel << 8) | atoi(p);
1433 if (rel >= KERNEL_VERSION(1,0,0))
1434 break;
1435 while (*p >= '0' && *p <= '9')
1436 p++;
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001437 if (*p != '.') {
1438 if (rel >= KERNEL_VERSION(0,1,0)) {
1439 /* "X.Y-something" means "X.Y.0" */
1440 rel <<= 8;
1441 break;
1442 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001443 error_msg_and_die("Bad OS release string: '%s'", u.release);
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001444 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001445 p++;
1446 }
1447 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001448}
1449
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001450/*
1451 * Initialization part of main() was eating much stack (~0.5k),
1452 * which was unused after init.
1453 * We can reuse it if we move init code into a separate function.
1454 *
1455 * Don't want main() to inline us and defeat the reason
1456 * we have a separate function.
1457 */
1458static void __attribute__ ((noinline))
1459init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001460{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001461 struct tcb *tcp;
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001462 int c, i;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001463 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001464 struct sigaction sa;
1465
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001466 progname = argv[0] ? argv[0] : "strace";
1467
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001468 /* Make sure SIGCHLD has the default action so that waitpid
1469 definitely works without losing track of children. The user
1470 should not have given us a bogus state to inherit, but he might
1471 have. Arguably we should detect SIG_IGN here and pass it on
1472 to children, but probably noone really needs that. */
1473 signal(SIGCHLD, SIG_DFL);
1474
Denys Vlasenko75422762011-05-27 14:36:01 +02001475 strace_tracer_pid = getpid();
1476
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001477 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001478
Roland McGrathee9d4352002-12-18 04:16:10 +00001479 /* Allocate the initial tcbtab. */
1480 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001481 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001482 if (!tcbtab)
1483 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001484 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001485 if (!tcp)
1486 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001487 for (c = 0; c < tcbtabsize; c++)
1488 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001489
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001490 shared_log = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001491 set_sortby(DEFAULT_SORTBY);
1492 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001493 qualify("trace=all");
1494 qualify("abbrev=all");
1495 qualify("verbose=all");
1496 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001497 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001498 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001499 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001500 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001501 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001502 case 'b':
1503 detach_on_execve = 1;
1504 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001505 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001506 if (cflag == CFLAG_BOTH) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001507 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001508 }
1509 cflag = CFLAG_ONLY_STATS;
1510 break;
1511 case 'C':
1512 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001513 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001514 }
1515 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001516 break;
1517 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001518 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001519 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001520 case 'D':
1521 daemonized_tracer = 1;
1522 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001523 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001524 optF = 1;
1525 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001526 case 'f':
1527 followfork++;
1528 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001529 case 'h':
1530 usage(stdout, 0);
1531 break;
1532 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001533 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001534 break;
1535 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001536 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001537 break;
1538 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001539 rflag = 1;
1540 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001541 case 't':
1542 tflag++;
1543 break;
1544 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001545 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001546 break;
1547 case 'x':
1548 xflag++;
1549 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001550 case 'y':
1551 show_fd_path = 1;
1552 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001553 case 'v':
1554 qualify("abbrev=none");
1555 break;
1556 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001557 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001558 exit(0);
1559 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001560 case 'z':
1561 not_failing_only = 1;
1562 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001563 case 'a':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001564 acolumn = string_to_uint(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001565 if (acolumn < 0)
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001566 error_opt_arg(c, optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001567 break;
1568 case 'e':
1569 qualify(optarg);
1570 break;
1571 case 'o':
1572 outfname = strdup(optarg);
1573 break;
1574 case 'O':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001575 i = string_to_uint(optarg);
1576 if (i < 0)
1577 error_opt_arg(c, optarg);
1578 set_overhead(i);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001579 break;
1580 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001581 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001582 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001583 case 'P':
1584 tracing_paths = 1;
1585 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001586 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001587 }
1588 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001589 case 's':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001590 i = string_to_uint(optarg);
1591 if (i < 0)
1592 error_opt_arg(c, optarg);
1593 max_strlen = i;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001594 break;
1595 case 'S':
1596 set_sortby(optarg);
1597 break;
1598 case 'u':
1599 username = strdup(optarg);
1600 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001601 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001602 if (putenv(optarg) < 0)
1603 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001604 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001605 case 'I':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001606 opt_intr = string_to_uint(optarg);
1607 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1608 error_opt_arg(c, optarg);
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001609 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001610 default:
1611 usage(stderr, 1);
1612 break;
1613 }
1614 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001615 argv += optind;
1616 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001617
Denys Vlasenko102ec492011-08-25 01:27:59 +02001618 acolumn_spaces = malloc(acolumn + 1);
1619 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001620 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001621 memset(acolumn_spaces, ' ', acolumn);
1622 acolumn_spaces[acolumn] = '\0';
1623
Denys Vlasenko837399a2012-01-24 11:37:03 +01001624 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001625 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001626 usage(stderr, 1);
1627
Denys Vlasenkofd883382012-03-09 13:03:41 +01001628 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001629 error_msg_and_die("-D and -p are mutually exclusive");
Wang Chaod322a4b2010-08-05 14:30:11 +08001630 }
1631
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001632 if (!followfork)
1633 followfork = optF;
1634
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001635 if (followfork >= 2 && cflag) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001636 error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
Roland McGrathcb9def62006-04-25 07:48:03 +00001637 }
1638
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001639 /* See if they want to run as another user. */
1640 if (username != NULL) {
1641 struct passwd *pent;
1642
1643 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001644 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001645 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001646 pent = getpwnam(username);
1647 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001648 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001649 }
1650 run_uid = pent->pw_uid;
1651 run_gid = pent->pw_gid;
1652 }
1653 else {
1654 run_uid = getuid();
1655 run_gid = getgid();
1656 }
1657
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001658 /*
1659 * On any reasonably recent Linux kernel (circa about 2.5.46)
1660 * need_fork_exec_workarounds should stay 0 after these tests:
1661 */
1662 /*need_fork_exec_workarounds = 0; - already is */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001663 if (followfork)
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001664 need_fork_exec_workarounds = test_ptrace_setoptions_followfork();
1665 need_fork_exec_workarounds |= test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001666 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001667
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001668 /* Check if they want to redirect the output. */
1669 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001670 /* See if they want to pipe the output. */
1671 if (outfname[0] == '|' || outfname[0] == '!') {
1672 /*
1673 * We can't do the <outfname>.PID funny business
1674 * when using popen, so prohibit it.
1675 */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001676 if (followfork >= 2)
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001677 error_msg_and_die("Piping the output and -ff are mutually exclusive");
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001678 shared_log = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001679 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001680 else if (followfork < 2)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001681 shared_log = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001682 } else {
1683 /* -ff without -o FILE is the same as single -f */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001684 if (followfork >= 2)
Denys Vlasenko328bf252012-03-12 23:34:13 +01001685 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001686 }
1687
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001688 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001689 char *buf = malloc(BUFSIZ);
1690 if (!buf)
1691 die_out_of_memory();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001692 setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001693 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001694 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001695 if (!opt_intr)
1696 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001697 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001698 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001699 if (!opt_intr)
1700 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001701
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001702 /* argv[0] -pPID -oFILE Default interactive setting
1703 * yes 0 0 INTR_WHILE_WAIT
1704 * no 1 0 INTR_WHILE_WAIT
1705 * yes 0 1 INTR_NEVER
1706 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001707 */
1708
1709 /* STARTUP_CHILD must be called before the signal handlers get
1710 installed below as they are inherited into the spawned process.
1711 Also we do not need to be protected by them as during interruption
1712 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001713 if (argv[0]) {
1714 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001715 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001716 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001717
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001718 sigemptyset(&empty_set);
1719 sigemptyset(&blocked_set);
1720 sa.sa_handler = SIG_IGN;
1721 sigemptyset(&sa.sa_mask);
1722 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001723 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1724 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1725 if (opt_intr != INTR_ANYWHERE) {
1726 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1727 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1728 /*
1729 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1730 * fatal signals are blocked while syscall stop is processed,
1731 * and acted on in between, when waiting for new syscall stops.
1732 * In non-interactive mode, signals are ignored.
1733 */
1734 if (opt_intr == INTR_WHILE_WAIT) {
1735 sigaddset(&blocked_set, SIGHUP);
1736 sigaddset(&blocked_set, SIGINT);
1737 sigaddset(&blocked_set, SIGQUIT);
1738 sigaddset(&blocked_set, SIGPIPE);
1739 sigaddset(&blocked_set, SIGTERM);
1740 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001741 }
1742 /* SIG_IGN, or set handler for these */
1743 sigaction(SIGHUP, &sa, NULL);
1744 sigaction(SIGINT, &sa, NULL);
1745 sigaction(SIGQUIT, &sa, NULL);
1746 sigaction(SIGPIPE, &sa, NULL);
1747 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001748 }
Denys Vlasenkofd883382012-03-09 13:03:41 +01001749 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001750 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001751
Denys Vlasenkofd883382012-03-09 13:03:41 +01001752 /* Do we want pids printed in our -o OUTFILE?
1753 * -ff: no (every pid has its own file); or
1754 * -f: yes (there can be more pids in the future); or
1755 * -p PID1,PID2: yes (there are already more than one pid)
1756 */
1757 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001758}
1759
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001760static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001761pid2tcb(int pid)
1762{
1763 int i;
1764
1765 if (pid <= 0)
1766 return NULL;
1767
1768 for (i = 0; i < tcbtabsize; i++) {
1769 struct tcb *tcp = tcbtab[i];
1770 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1771 return tcp;
1772 }
1773
1774 return NULL;
1775}
1776
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001777static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001778cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001779{
1780 int i;
1781 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001782 int fatal_sig;
1783
1784 /* 'interrupted' is a volatile object, fetch it only once */
1785 fatal_sig = interrupted;
1786 if (!fatal_sig)
1787 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788
Roland McGrathee9d4352002-12-18 04:16:10 +00001789 for (i = 0; i < tcbtabsize; i++) {
1790 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001791 if (!(tcp->flags & TCB_INUSE))
1792 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001793 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794 fprintf(stderr,
1795 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001796 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001797 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001798 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001799 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001800 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001801 }
1802 if (cflag)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001803 call_summary(shared_log);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804}
1805
1806static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001807interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001808{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001809 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001810}
1811
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001812static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001813trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001814{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001815 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001816 struct rusage *rup = cflag ? &ru : NULL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001817#ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001818 static int wait4_options = __WALL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001819#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001820
Roland McGratheb9e2e82009-06-02 16:49:22 -07001821 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001822 int pid;
1823 int wait_errno;
1824 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001825 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001826 struct tcb *tcp;
1827 unsigned event;
1828
Denys Vlasenko222713a2009-03-17 14:29:59 +00001829 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001830 return 0;
1831 if (interactive)
1832 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001833#ifdef __WALL
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001834 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001835 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001836 /* this kernel does not support __WALL */
1837 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001838 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001839 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001840 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001841 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001842 pid = wait4(-1, &status, __WCLONE, rup);
1843 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001844 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001845 }
1846 }
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001847#else
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001848 pid = wait4(-1, &status, 0, rup);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001849#endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001850 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001851 if (interactive)
1852 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001853
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001854 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001855 switch (wait_errno) {
1856 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001857 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001858 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001859 /*
1860 * We would like to verify this case
1861 * but sometimes a race in Solbourne's
1862 * version of SunOS sometimes reports
1863 * ECHILD before sending us SIGCHILD.
1864 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001865 return 0;
1866 default:
1867 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001868 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001869 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001870 }
1871 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001872 if (pid == popen_pid) {
1873 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001874 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001875 continue;
1876 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001877
1878 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001879 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001880 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001881 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001882 strcpy(buf, "???");
1883 if (WIFSIGNALED(status))
1884#ifdef WCOREDUMP
1885 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1886 WCOREDUMP(status) ? "core," : "",
1887 signame(WTERMSIG(status)));
1888#else
1889 sprintf(buf, "WIFSIGNALED,sig=%s",
1890 signame(WTERMSIG(status)));
1891#endif
1892 if (WIFEXITED(status))
1893 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1894 if (WIFSTOPPED(status))
1895 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001896#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001897 if (WIFCONTINUED(status))
1898 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001899#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001900 evbuf[0] = '\0';
1901 if (event != 0) {
1902 static const char *const event_names[] = {
1903 [PTRACE_EVENT_CLONE] = "CLONE",
1904 [PTRACE_EVENT_FORK] = "FORK",
1905 [PTRACE_EVENT_VFORK] = "VFORK",
1906 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1907 [PTRACE_EVENT_EXEC] = "EXEC",
1908 [PTRACE_EVENT_EXIT] = "EXIT",
1909 };
1910 const char *e;
1911 if (event < ARRAY_SIZE(event_names))
1912 e = event_names[event];
1913 else {
1914 sprintf(buf, "?? (%u)", event);
1915 e = buf;
1916 }
1917 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1918 }
1919 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001920 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001921
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001922 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001923 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001924
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001925 if (!tcp) {
Roland McGrath41c48222008-07-18 00:25:10 +00001926 if (followfork) {
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001927 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001928 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001929 newoutf(tcp);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001930 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001931 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001932 pid);
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001933 } else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001934 /* This can happen if a clone call used
1935 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001936 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001937 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001938 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001939 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001940 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001941
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001942 clear_regs();
1943 if (WIFSTOPPED(status))
1944 get_regs(pid);
1945
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001946 /* Under Linux, execve changes pid to thread leader's pid,
1947 * and we see this changed pid on EVENT_EXEC and later,
1948 * execve sysexit. Leader "disappears" without exit
1949 * notification. Let user know that, drop leader's tcb,
1950 * and fix up pid in execve thread's tcb.
1951 * Effectively, execve thread's tcb replaces leader's tcb.
1952 *
1953 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1954 * on exit syscall) in multithreaded programs exactly
1955 * in order to handle this case.
1956 *
1957 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1958 * On 2.6 and earlier, it can return garbage.
1959 */
1960 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001961 FILE *fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001962 struct tcb *execve_thread;
1963 long old_pid = 0;
1964
1965 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1966 goto dont_switch_tcbs;
1967 if (old_pid <= 0 || old_pid == pid)
1968 goto dont_switch_tcbs;
1969 execve_thread = pid2tcb(old_pid);
1970 /* It should be !NULL, but I feel paranoid */
1971 if (!execve_thread)
1972 goto dont_switch_tcbs;
1973
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001974 if (execve_thread->curcol != 0) {
1975 /*
1976 * One case we are here is -ff:
1977 * try "strace -oLOG -ff test/threaded_execve"
1978 */
1979 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001980 /*execve_thread->curcol = 0; - no need, see code below */
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001981 }
1982 /* Swap output FILEs (needed for -ff) */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001983 fp = execve_thread->outf;
1984 execve_thread->outf = tcp->outf;
1985 tcp->outf = fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001986 /* And their column positions */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001987 execve_thread->curcol = tcp->curcol;
1988 tcp->curcol = 0;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001989 /* Drop leader, but close execve'd thread outfile (if -ff) */
1990 droptcb(tcp);
1991 /* Switch to the thread, reusing leader's outfile and pid */
1992 tcp = execve_thread;
1993 tcp->pid = pid;
1994 if (cflag != CFLAG_ONLY_STATS) {
1995 printleader(tcp);
1996 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1997 line_ended();
1998 tcp->flags |= TCB_REPRINT;
1999 }
2000 }
2001 dont_switch_tcbs:
2002
2003 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
2004 if (!skip_startup_execve)
2005 detach(tcp);
2006 /* This was initial execve for "strace PROG". Skip. */
2007 skip_startup_execve = 0;
2008 }
2009
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002010 /* Set current output file */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01002011 current_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002012
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002013 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002014 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2015 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002016 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07002017
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002018 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002019 if (pid == strace_child)
2020 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002021 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002022 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2023 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002024#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01002025 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00002026 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002027 WCOREDUMP(status) ? "(core dumped) " : "");
2028#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002029 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002030 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00002031#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002032 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002033 }
2034 droptcb(tcp);
2035 continue;
2036 }
2037 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002038 if (pid == strace_child)
2039 exit_code = WEXITSTATUS(status);
Denys Vlasenkob5e09082012-03-21 14:27:40 +01002040 if (cflag != CFLAG_ONLY_STATS) {
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002041 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01002042 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002043 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002044 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002045 droptcb(tcp);
2046 continue;
2047 }
2048 if (!WIFSTOPPED(status)) {
2049 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2050 droptcb(tcp);
2051 continue;
2052 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002053
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002054 /* Is this the very first time we see this tracee stopped? */
2055 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002056 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002057 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002058 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002059 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002060 /*
2061 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002062 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002063 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002064 if (clearbpt(tcp) < 0) {
2065 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002066 droptcb(tcp);
2067 cleanup();
2068 return -1;
2069 }
2070 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002071 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002072 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002073 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2074 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2075 if (errno != ESRCH) {
2076 /* Should never happen, really */
2077 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002078 }
2079 }
2080 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002081 }
2082
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002083 sig = WSTOPSIG(status);
2084
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002085 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002086 /* Ptrace event */
2087#ifdef USE_SEIZE
Denys Vlasenko26bc0602012-07-10 16:36:32 +02002088 if (event == PTRACE_EVENT_STOP) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002089 /*
2090 * PTRACE_INTERRUPT-stop or group-stop.
2091 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2092 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002093 if (sig == SIGSTOP
2094 || sig == SIGTSTP
2095 || sig == SIGTTIN
2096 || sig == SIGTTOU
2097 ) {
2098 stopped = 1;
2099 goto show_stopsig;
2100 }
2101 }
2102#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002103 goto restart_tracee_with_sig_0;
2104 }
2105
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002106 /* Is this post-attach SIGSTOP?
2107 * Interestingly, the process may stop
2108 * with STOPSIG equal to some other signal
2109 * than SIGSTOP if we happend to attach
2110 * just before the process takes a signal.
2111 */
2112 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002113 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002114 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2115 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002116 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002117 }
2118
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002119 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002120 siginfo_t si;
2121
2122 /* Nonzero (true) if tracee is stopped by signal
2123 * (as opposed to "tracee received signal").
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002124 * TODO: shouldn't we check for errno == EINVAL too?
2125 * We can get ESRCH instead, you know...
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002126 */
2127 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002128#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002129 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002130#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002131 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002132 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002133#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002134 long pc = 0;
2135 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002136
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002137 upeek(tcp, PT_CR_IPSR, &psr);
2138 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002139
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002140# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002141 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002142# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002143# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002144#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002145# define PC_FORMAT_STR ""
2146# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002147#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002148 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002149 if (!stopped) {
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002150 tprintf("--- %s ", signame(sig));
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002151 printsiginfo(&si, verbose(tcp));
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002152 tprintf(PC_FORMAT_STR " ---\n"
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002153 PC_FORMAT_ARG);
2154 } else
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002155 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002156 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002157 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002158 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002159 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002160
2161 if (!stopped)
2162 /* It's signal-delivery-stop. Inject the signal */
2163 goto restart_tracee;
2164
2165 /* It's group-stop */
2166#ifdef USE_SEIZE
2167 if (use_seize) {
2168 /*
2169 * This ends ptrace-stop, but does *not* end group-stop.
2170 * This makes stopping signals work properly on straced process
2171 * (that is, process really stops. It used to continue to run).
2172 */
2173 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2174 cleanup();
2175 return -1;
2176 }
2177 continue;
2178 }
2179 /* We don't have PTRACE_LISTEN support... */
2180#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002181 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002182 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002183
2184 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002185 if (interrupted)
2186 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002187
2188 /* This should be syscall entry or exit.
2189 * (Or it still can be that pesky post-execve SIGTRAP!)
2190 * Handle it.
2191 */
Denys Vlasenko23506752012-03-21 10:32:49 +01002192 if (trace_syscall(tcp) < 0) {
2193 /* ptrace() failed in trace_syscall().
Roland McGratheb9e2e82009-06-02 16:49:22 -07002194 * Likely a result of process disappearing mid-flight.
Denys Vlasenko23506752012-03-21 10:32:49 +01002195 * Observed case: exit_group() or SIGKILL terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002196 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002197 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002198 * We used to detach(tcp) here, but since we no longer
2199 * implement "detach before death" policy/hack,
2200 * we can let this process to report its death to us
2201 * normally, via WIFEXITED or WIFSIGNALED wait status.
2202 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002203 continue;
2204 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002205 restart_tracee_with_sig_0:
2206 sig = 0;
2207 restart_tracee:
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002208 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002209 cleanup();
2210 return -1;
2211 }
2212 }
2213 return 0;
2214}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002215
2216int
2217main(int argc, char *argv[])
2218{
2219 init(argc, argv);
2220
2221 /* Run main tracing loop */
2222 if (trace() < 0)
2223 return 1;
2224
2225 cleanup();
2226 fflush(NULL);
Dmitry V. Levincf534362012-07-12 20:54:46 +00002227 if (shared_log != stderr)
2228 fclose(shared_log);
2229 if (popen_pid) {
2230 while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR)
2231 ;
2232 }
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002233 if (exit_code > 0xff) {
2234 /* Avoid potential core file clobbering. */
2235 struct rlimit rlim = {0, 0};
2236 setrlimit(RLIMIT_CORE, &rlim);
2237
2238 /* Child was killed by a signal, mimic that. */
2239 exit_code &= 0xff;
2240 signal(exit_code, SIG_DFL);
2241 raise(exit_code);
2242 /* Paranoia - what if this signal is not fatal?
2243 Exit with 128 + signo then. */
2244 exit_code += 128;
2245 }
2246
2247 return exit_code;
2248}