blob: eac6ba59ba07540f96840428496ecc4ee9f7db3a [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
61#undef KERNEL_VERSION
62#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
63
64cflag_t cflag = CFLAG_NONE;
65unsigned int followfork = 0;
Denys Vlasenkof44cce42011-06-21 14:34:10 +020066unsigned int ptrace_setoptions = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010067unsigned int xflag = 0;
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +010068bool need_fork_exec_workarounds = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010069bool debug_flag = 0;
70bool Tflag = 0;
71bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020072/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020073static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010074static unsigned int tflag = 0;
75static bool iflag = 0;
76static bool rflag = 0;
77static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010078
79/* -I n */
80enum {
81 INTR_NOT_SET = 0,
82 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
83 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
84 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
85 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
86 NUM_INTR_OPTS
87};
88static int opt_intr;
89/* We play with signal mask only if this mode is active: */
90#define interactive (opt_intr == INTR_WHILE_WAIT)
91
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000092/*
93 * daemonized_tracer supports -D option.
94 * With this option, strace forks twice.
95 * Unlike normal case, with -D *grandparent* process exec's,
96 * becoming a traced process. Child exits (this prevents traced process
97 * from having children it doesn't expect to have), and grandchild
98 * attaches to grandparent similarly to strace -p PID.
99 * This allows for more transparent interaction in cases
100 * when process and its parent are communicating via signals,
101 * wait() etc. Without -D, strace process gets lodged in between,
102 * disrupting parent<->child link.
103 */
104static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000105
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100106#ifdef USE_SEIZE
107static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
108# define use_seize (post_attach_sigstop == 0)
109#else
110# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
111# define use_seize 0
112#endif
113
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000114/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100115bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000116
Grant Edwards8a082772011-04-07 20:25:40 +0000117/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100118bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000119
120/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100121bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000122
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100123static bool detach_on_execve = 0;
124static bool skip_startup_execve = 0;
125
Dmitry V. Levina6809652008-11-10 17:14:58 +0000126static int exit_code = 0;
127static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200128static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700129
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000130static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200131static uid_t run_uid;
132static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000133
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100134unsigned int max_strlen = DEFAULT_STRLEN;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000135static int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200136static char *acolumn_spaces;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100137
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000138static char *outfname = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100139/* If -ff, points to stderr. Else, it's our common output log */
140static FILE *shared_log;
141
Denys Vlasenko000b6012012-01-28 01:25:03 +0100142struct tcb *printing_tcp = NULL;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100143static struct tcb *current_tcp;
144
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200145static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200146static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200147static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000148
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +0100149static unsigned os_release; /* generated from uname()'s u.release */
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100150
Denys Vlasenko4c196382012-01-04 15:11:09 +0100151static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100152static int trace(void);
153static void cleanup(void);
154static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000155static sigset_t empty_set, blocked_set;
156
157#ifdef HAVE_SIG_ATOMIC_T
158static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100159#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000160static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100161#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000162
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100163#ifndef HAVE_STRERROR
164
165#if !HAVE_DECL_SYS_ERRLIST
166extern int sys_nerr;
167extern char *sys_errlist[];
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +0100168#endif
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100169
170const char *
171strerror(int err_no)
172{
173 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
174
175 if (err_no < 1 || err_no >= sys_nerr) {
176 sprintf(buf, "Unknown error %d", err_no);
177 return buf;
178 }
179 return sys_errlist[err_no];
180}
181
182#endif /* HAVE_STERRROR */
183
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000184static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200185usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000186{
187 fprintf(ofp, "\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200188usage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
189 [-a column] [-o file] [-s strsize] [-P path]...\n\
190 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
191 or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
192 -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000193-c -- count time, calls, and errors for each syscall and report summary\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200194-C -- like -c but also print regular output\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100195-d -- enable debug output to stderr\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100196-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000197-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100198-F -- attempt to follow vforks (deprecated, use -f)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000199-i -- print instruction pointer at time of syscall\n\
200-q -- suppress messages about attaching, detaching, etc.\n\
201-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100202-T -- print time spent in each syscall\n\
203-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000204-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000205-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200206-h -- print help message, -V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000207-a column -- alignment COLUMN for printing syscall results (default %d)\n\
208-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
209 options: trace, abbrev, verbose, raw, signal, read, or write\n\
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +0200210-I interruptible --\n\
211 1: no signals are blocked\n\
212 2: fatal signals are blocked while decoding syscall (default)\n\
213 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
214 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
215 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000216-o file -- send trace output to FILE instead of stderr\n\
217-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
218-p pid -- trace process with process id PID, may be repeated\n\
219-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
220-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
221-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000222-E var=val -- put var=val in the environment for command\n\
223-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000224-P path -- trace accesses to path\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100225"
226/* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000227-z -- print only succeeding syscalls\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100228 */
229/* experimental, don't document it yet (option letter may change in the future!)
230-b -- detach on successful execve\n\
231 */
Roland McGrathde6e5332003-01-24 04:31:23 +0000232, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000233 exit(exitval);
234}
235
Denys Vlasenko75422762011-05-27 14:36:01 +0200236static void die(void) __attribute__ ((noreturn));
237static void die(void)
238{
239 if (strace_tracer_pid == getpid()) {
240 cflag = 0;
241 cleanup();
242 }
243 exit(1);
244}
245
246static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200247{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100248 char *msg;
249
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000250 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100251
252 /* We want to print entire message with single fprintf to ensure
253 * message integrity if stderr is shared with other programs.
254 * Thus we use vasprintf + single fprintf.
255 */
256 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100257 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100258 if (err_no)
259 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
260 else
261 fprintf(stderr, "%s: %s\n", progname, msg);
262 free(msg);
263 } else {
264 /* malloc in vasprintf failed, try it without malloc */
265 fprintf(stderr, "%s: ", progname);
266 vfprintf(stderr, fmt, p);
267 if (err_no)
268 fprintf(stderr, ": %s\n", strerror(err_no));
269 else
270 putc('\n', stderr);
271 }
272 /* We don't switch stderr to buffered, thus fprintf(stderr)
273 * always flushes its output and this is not necessary: */
274 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200275}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200276
Denys Vlasenko75422762011-05-27 14:36:01 +0200277void error_msg(const char *fmt, ...)
278{
279 va_list p;
280 va_start(p, fmt);
281 verror_msg(0, fmt, p);
282 va_end(p);
283}
284
285void error_msg_and_die(const char *fmt, ...)
286{
287 va_list p;
288 va_start(p, fmt);
289 verror_msg(0, fmt, p);
290 die();
291}
292
293void perror_msg(const char *fmt, ...)
294{
295 va_list p;
296 va_start(p, fmt);
297 verror_msg(errno, fmt, p);
298 va_end(p);
299}
300
301void perror_msg_and_die(const char *fmt, ...)
302{
303 va_list p;
304 va_start(p, fmt);
305 verror_msg(errno, fmt, p);
306 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200307}
308
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200309void die_out_of_memory(void)
310{
311 static bool recursed = 0;
312 if (recursed)
313 exit(1);
314 recursed = 1;
315 error_msg_and_die("Out of memory");
316}
317
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000318static void
319error_opt_arg(int opt, const char *arg)
320{
321 error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
322}
323
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400324/* Glue for systems without a MMU that cannot provide fork() */
325#ifdef HAVE_FORK
326# define strace_vforked 0
327#else
328# define strace_vforked 1
329# define fork() vfork()
330#endif
331
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100332#ifdef USE_SEIZE
333static int
334ptrace_attach_or_seize(int pid)
335{
336 int r;
337 if (!use_seize)
338 return ptrace(PTRACE_ATTACH, pid, 0, 0);
Denys Vlasenko26bc0602012-07-10 16:36:32 +0200339 r = ptrace(PTRACE_SEIZE, pid, 0, 0);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100340 if (r)
341 return r;
342 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
343 return r;
344}
345#else
346# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
347#endif
348
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100349/*
350 * Used when we want to unblock stopped traced process.
351 * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
352 * Returns 0 on success or if error was ESRCH
353 * (presumably process was killed while we talk to it).
354 * Otherwise prints error message and returns -1.
355 */
356static int
357ptrace_restart(int op, struct tcb *tcp, int sig)
358{
359 int err;
360 const char *msg;
361
362 errno = 0;
363 ptrace(op, tcp->pid, (void *) 0, (long) sig);
364 err = errno;
Denys Vlasenko23506752012-03-21 10:32:49 +0100365 if (!err)
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100366 return 0;
367
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100368 msg = "SYSCALL";
369 if (op == PTRACE_CONT)
370 msg = "CONT";
371 if (op == PTRACE_DETACH)
372 msg = "DETACH";
373#ifdef PTRACE_LISTEN
374 if (op == PTRACE_LISTEN)
375 msg = "LISTEN";
376#endif
Denys Vlasenko23506752012-03-21 10:32:49 +0100377 /*
378 * Why curcol != 0? Otherwise sometimes we get this:
379 *
380 * 10252 kill(10253, SIGKILL) = 0
381 * <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
382 *
383 * 10252 died after we retrieved syscall exit data,
384 * but before we tried to restart it. Log looks ugly.
385 */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100386 if (current_tcp && current_tcp->curcol != 0) {
Denys Vlasenko23506752012-03-21 10:32:49 +0100387 tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
388 line_ended();
389 }
390 if (err == ESRCH)
391 return 0;
392 errno = err;
Denys Vlasenko852f98a2012-03-20 16:26:25 +0100393 perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
394 return -1;
395}
396
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200397static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000398set_cloexec_flag(int fd)
399{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200400 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000401
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200402 flags = fcntl(fd, F_GETFD);
403 if (flags < 0) {
404 /* Can happen only if fd is bad.
405 * Should never happen: if it does, we have a bug
406 * in the caller. Therefore we just abort
407 * instead of propagating the error.
408 */
409 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000410 }
411
412 newflags = flags | FD_CLOEXEC;
413 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200414 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000415
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200416 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000417}
418
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100419static void kill_save_errno(pid_t pid, int sig)
420{
421 int saved_errno = errno;
422
423 (void) kill(pid, sig);
424 errno = saved_errno;
425}
426
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100427/*
428 * When strace is setuid executable, we have to swap uids
429 * before and after filesystem and process management operations.
430 */
431static void
432swap_uid(void)
433{
434 int euid = geteuid(), uid = getuid();
435
436 if (euid != uid && setreuid(euid, uid) < 0) {
437 perror_msg_and_die("setreuid");
438 }
439}
440
441#if _LFS64_LARGEFILE
442# define fopen_for_output fopen64
443#else
444# define fopen_for_output fopen
445#endif
446
447static FILE *
448strace_fopen(const char *path)
449{
450 FILE *fp;
451
452 swap_uid();
453 fp = fopen_for_output(path, "w");
454 if (!fp)
455 perror_msg_and_die("Can't fopen '%s'", path);
456 swap_uid();
457 set_cloexec_flag(fileno(fp));
458 return fp;
459}
460
461static int popen_pid = 0;
462
463#ifndef _PATH_BSHELL
464# define _PATH_BSHELL "/bin/sh"
465#endif
466
467/*
468 * We cannot use standard popen(3) here because we have to distinguish
469 * popen child process from other processes we trace, and standard popen(3)
470 * does not export its child's pid.
471 */
472static FILE *
473strace_popen(const char *command)
474{
475 FILE *fp;
476 int fds[2];
477
478 swap_uid();
479 if (pipe(fds) < 0)
480 perror_msg_and_die("pipe");
481
482 set_cloexec_flag(fds[1]); /* never fails */
483
484 popen_pid = vfork();
485 if (popen_pid == -1)
486 perror_msg_and_die("vfork");
487
488 if (popen_pid == 0) {
489 /* child */
490 close(fds[1]);
491 if (fds[0] != 0) {
492 if (dup2(fds[0], 0))
493 perror_msg_and_die("dup2");
494 close(fds[0]);
495 }
496 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
497 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
498 }
499
500 /* parent */
501 close(fds[0]);
502 swap_uid();
503 fp = fdopen(fds[1], "w");
504 if (!fp)
505 die_out_of_memory();
506 return fp;
507}
508
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100509void
510tprintf(const char *fmt, ...)
511{
512 va_list args;
513
514 va_start(args, fmt);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100515 if (current_tcp) {
Denys Vlasenko6e4f3c12012-04-16 18:22:19 +0200516 int n = strace_vfprintf(current_tcp->outf, fmt, args);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100517 if (n < 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100518 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000519 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100520 } else
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100521 current_tcp->curcol += n;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100522 }
523 va_end(args);
524}
525
526void
527tprints(const char *str)
528{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100529 if (current_tcp) {
Denys Vlasenko142aee02012-04-16 18:10:15 +0200530 int n = fputs_unlocked(str, current_tcp->outf);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100531 if (n >= 0) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100532 current_tcp->curcol += strlen(str);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100533 return;
534 }
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100535 if (current_tcp->outf != stderr)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000536 perror_msg("%s", outfname);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100537 }
538}
539
540void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100541line_ended(void)
542{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100543 if (current_tcp) {
544 current_tcp->curcol = 0;
545 fflush(current_tcp->outf);
546 }
547 if (printing_tcp) {
548 printing_tcp->curcol = 0;
549 printing_tcp = NULL;
550 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100551}
552
553void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100554printleader(struct tcb *tcp)
555{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100556 /* If -ff, "previous tcb we printed" is always the same as current,
557 * because we have per-tcb output files.
558 */
559 if (followfork >= 2)
560 printing_tcp = tcp;
561
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100562 if (printing_tcp) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100563 current_tcp = printing_tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100564 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
565 /*
566 * case 1: we have a shared log (i.e. not -ff), and last line
567 * wasn't finished (same or different tcb, doesn't matter).
568 * case 2: split log, we are the same tcb, but our last line
569 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
570 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100571 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100572 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100573 }
574 }
575
576 printing_tcp = tcp;
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100577 current_tcp = tcp;
578 current_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100579
580 if (print_pid_pfx)
581 tprintf("%-5d ", tcp->pid);
582 else if (nprocs > 1 && !outfname)
583 tprintf("[pid %5u] ", tcp->pid);
584
585 if (tflag) {
586 char str[sizeof("HH:MM:SS")];
587 struct timeval tv, dtv;
588 static struct timeval otv;
589
590 gettimeofday(&tv, NULL);
591 if (rflag) {
592 if (otv.tv_sec == 0)
593 otv = tv;
594 tv_sub(&dtv, &tv, &otv);
595 tprintf("%6ld.%06ld ",
596 (long) dtv.tv_sec, (long) dtv.tv_usec);
597 otv = tv;
598 }
599 else if (tflag > 2) {
600 tprintf("%ld.%06ld ",
601 (long) tv.tv_sec, (long) tv.tv_usec);
602 }
603 else {
604 time_t local = tv.tv_sec;
605 strftime(str, sizeof(str), "%T", localtime(&local));
606 if (tflag > 1)
607 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
608 else
609 tprintf("%s ", str);
610 }
611 }
612 if (iflag)
613 printcall(tcp);
614}
615
616void
617tabto(void)
618{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100619 if (current_tcp->curcol < acolumn)
620 tprints(acolumn_spaces + current_tcp->curcol);
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100621}
622
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100623/* Should be only called directly *after successful attach* to a tracee.
624 * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
625 * may create bogus empty FILE.<nonexistant_pid>, and then die.
626 */
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200627static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000628newoutf(struct tcb *tcp)
629{
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100630 tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100631 if (followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000632 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000633 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200634 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000635 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000636}
637
Denys Vlasenko558e5122012-03-12 23:32:16 +0100638static void
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100639expand_tcbtab(void)
640{
641 /* Allocate some more TCBs and expand the table.
642 We don't want to relocate the TCBs because our
643 callers have pointers and it would be a pain.
644 So tcbtab is a table of pointers. Since we never
645 free the TCBs, we allocate a single chunk of many. */
646 int i = tcbtabsize;
647 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
648 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
649 if (!newtab || !newtcbs)
650 die_out_of_memory();
651 tcbtabsize *= 2;
652 tcbtab = newtab;
653 while (i < tcbtabsize)
654 tcbtab[i++] = newtcbs++;
655}
656
657static struct tcb *
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100658alloctcb(int pid)
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100659{
660 int i;
661 struct tcb *tcp;
662
663 if (nprocs == tcbtabsize)
664 expand_tcbtab();
665
666 for (i = 0; i < tcbtabsize; i++) {
667 tcp = tcbtab[i];
668 if ((tcp->flags & TCB_INUSE) == 0) {
669 memset(tcp, 0, sizeof(*tcp));
670 tcp->pid = pid;
671 tcp->flags = TCB_INUSE;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100672#if SUPPORTED_PERSONALITIES > 1
673 tcp->currpers = current_personality;
674#endif
675 nprocs++;
676 if (debug_flag)
677 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100678 return tcp;
679 }
680 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100681 error_msg_and_die("bug in alloctcb");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100682}
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100683
684static void
685droptcb(struct tcb *tcp)
686{
687 if (tcp->pid == 0)
688 return;
689
690 nprocs--;
691 if (debug_flag)
692 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
693
694 if (tcp->outf) {
Denys Vlasenko8511f2a2012-03-22 09:35:51 +0100695 if (followfork >= 2) {
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100696 if (tcp->curcol != 0)
697 fprintf(tcp->outf, " <detached ...>\n");
698 fclose(tcp->outf);
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100699 } else {
700 if (printing_tcp == tcp && tcp->curcol != 0)
701 fprintf(tcp->outf, " <detached ...>\n");
702 fflush(tcp->outf);
703 }
704 }
705
Denys Vlasenko6764f8f2012-03-22 09:56:20 +0100706 if (current_tcp == tcp)
707 current_tcp = NULL;
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100708 if (printing_tcp == tcp)
709 printing_tcp = NULL;
710
711 memset(tcp, 0, sizeof(*tcp));
712}
713
714/* detach traced process; continue with sig
715 * Never call DETACH twice on the same process as both unattached and
716 * attached-unstopped processes give the same ESRCH. For unattached process we
717 * would SIGSTOP it and wait for its SIGSTOP notification forever.
718 */
719static int
720detach(struct tcb *tcp)
721{
722 int error;
723 int status, sigstop_expected;
724
725 if (tcp->flags & TCB_BPTSET)
726 clearbpt(tcp);
727
728 /*
729 * Linux wrongly insists the child be stopped
730 * before detaching. Arghh. We go through hoops
731 * to make a clean break of things.
732 */
733#if defined(SPARC)
Denys Vlasenko978fbc92012-09-13 10:28:43 +0200734# undef PTRACE_DETACH
735# define PTRACE_DETACH PTRACE_SUNDETACH
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100736#endif
737
738 error = 0;
739 sigstop_expected = 0;
740 if (tcp->flags & TCB_ATTACHED) {
741 /*
742 * We attached but possibly didn't see the expected SIGSTOP.
743 * We must catch exactly one as otherwise the detached process
744 * would be left stopped (process state T).
745 */
746 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
747 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
748 if (error == 0) {
749 /* On a clear day, you can see forever. */
750 }
751 else if (errno != ESRCH) {
752 /* Shouldn't happen. */
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000753 perror_msg("%s", "detach: ptrace(PTRACE_DETACH, ...)");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100754 }
755 else if (my_tkill(tcp->pid, 0) < 0) {
756 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000757 perror_msg("%s", "detach: checking sanity");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100758 }
759 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
760 if (errno != ESRCH)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000761 perror_msg("%s", "detach: stopping child");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100762 }
763 else
764 sigstop_expected = 1;
765 }
766
767 if (sigstop_expected) {
768 for (;;) {
769#ifdef __WALL
770 if (waitpid(tcp->pid, &status, __WALL) < 0) {
771 if (errno == ECHILD) /* Already gone. */
772 break;
773 if (errno != EINVAL) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000774 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100775 break;
776 }
777#endif /* __WALL */
778 /* No __WALL here. */
779 if (waitpid(tcp->pid, &status, 0) < 0) {
780 if (errno != ECHILD) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000781 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100782 break;
783 }
784#ifdef __WCLONE
785 /* If no processes, try clones. */
786 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
787 if (errno != ECHILD)
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000788 perror_msg("%s", "detach: waiting");
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100789 break;
790 }
791#endif /* __WCLONE */
792 }
793#ifdef __WALL
794 }
795#endif
796 if (!WIFSTOPPED(status)) {
797 /* Au revoir, mon ami. */
798 break;
799 }
800 if (WSTOPSIG(status) == SIGSTOP) {
801 ptrace_restart(PTRACE_DETACH, tcp, 0);
802 break;
803 }
804 error = ptrace_restart(PTRACE_CONT, tcp,
805 WSTOPSIG(status) == syscall_trap_sig ? 0
806 : WSTOPSIG(status));
807 if (error < 0)
808 break;
809 }
810 }
811
812 if (!qflag && (tcp->flags & TCB_ATTACHED))
813 fprintf(stderr, "Process %u detached\n", tcp->pid);
814
815 droptcb(tcp);
816
817 return error;
818}
819
820static void
Denys Vlasenko558e5122012-03-12 23:32:16 +0100821process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100822{
823 while (*opt) {
824 /*
825 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
826 * pidof uses space as delim, pgrep uses newline. :(
827 */
828 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100829 char *delim = opt + strcspn(opt, ", \n\t");
830 char c = *delim;
831
832 *delim = '\0';
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000833 pid = string_to_uint(opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100834 if (pid <= 0) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000835 error_msg_and_die("Invalid process id: '%s'", opt);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100836 }
837 if (pid == strace_tracer_pid) {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000838 error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100839 }
840 *delim = c;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100841 alloctcb(pid);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100842 if (c == '\0')
843 break;
844 opt = delim + 1;
845 }
846}
847
Roland McGrath02203312007-06-11 22:06:31 +0000848static void
849startup_attach(void)
850{
851 int tcbi;
852 struct tcb *tcp;
853
854 /*
855 * Block user interruptions as we would leave the traced
856 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200857 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200858 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000859 */
860 if (interactive)
861 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
862
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000863 if (daemonized_tracer) {
864 pid_t pid = fork();
865 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200866 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000867 }
868 if (pid) { /* parent */
869 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200870 * Wait for grandchild to attach to straced process
871 * (grandparent). Grandchild SIGKILLs us after it attached.
872 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000873 * it proceeds to exec the straced program.
874 */
875 pause();
876 _exit(0); /* paranoia */
877 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200878 /* grandchild */
879 /* We will be the tracer process. Remember our new pid: */
880 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000881 }
882
Roland McGrath02203312007-06-11 22:06:31 +0000883 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
884 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200885
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100886 if (!(tcp->flags & TCB_INUSE))
887 continue;
888
Denys Vlasenkod116a732011-09-05 14:01:33 +0200889 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100890 if (tcp->flags & TCB_ATTACHED)
891 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200892
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000893 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000894 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000895 DIR *dir;
896
897 sprintf(procdir, "/proc/%d/task", tcp->pid);
898 dir = opendir(procdir);
899 if (dir != NULL) {
900 unsigned int ntid = 0, nerr = 0;
901 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200902
Roland McGrath02203312007-06-11 22:06:31 +0000903 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200904 struct tcb *cur_tcp;
905 int tid;
906
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000907 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000908 continue;
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000909 /* we trust /proc filesystem */
Roland McGrath02203312007-06-11 22:06:31 +0000910 tid = atoi(de->d_name);
911 if (tid <= 0)
912 continue;
913 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100914 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000915 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100916 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200917 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200918 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200919 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100920 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200921 fprintf(stderr, "attach to pid %d succeeded\n", tid);
922 cur_tcp = tcp;
923 if (tid != tcp->pid)
924 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100925 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100926 newoutf(cur_tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000927 }
928 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200929 if (interactive) {
930 sigprocmask(SIG_SETMASK, &empty_set, NULL);
931 if (interrupted)
932 goto ret;
933 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
934 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000935 ntid -= nerr;
936 if (ntid == 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000937 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000938 droptcb(tcp);
939 continue;
940 }
941 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000942 fprintf(stderr, ntid > 1
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100943? "Process %u attached with %u threads\n"
944: "Process %u attached\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200945 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000946 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100947 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200948 /* -p PID, we failed to attach to PID itself
949 * but did attach to some of its sibling threads.
950 * Drop PID's tcp.
951 */
952 droptcb(tcp);
953 }
Roland McGrath02203312007-06-11 22:06:31 +0000954 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000955 } /* if (opendir worked) */
956 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100957 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000958 perror_msg("%s", "attach: ptrace(PTRACE_ATTACH, ...)");
Roland McGrath02203312007-06-11 22:06:31 +0000959 droptcb(tcp);
960 continue;
961 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100962 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +0100963 newoutf(tcp);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100964 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200965 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000966
967 if (daemonized_tracer) {
968 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000969 * Make parent go away.
970 * Also makes grandparent's wait() unblock.
971 */
972 kill(getppid(), SIGKILL);
973 }
974
Roland McGrath02203312007-06-11 22:06:31 +0000975 if (!qflag)
976 fprintf(stderr,
Denys Vlasenko9c3861d2012-03-16 15:21:49 +0100977 "Process %u attached\n",
Roland McGrath02203312007-06-11 22:06:31 +0000978 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200979 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000980
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200981 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000982 if (interactive)
983 sigprocmask(SIG_SETMASK, &empty_set, NULL);
984}
985
986static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200987startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000988{
989 struct stat statbuf;
990 const char *filename;
991 char pathname[MAXPATHLEN];
992 int pid = 0;
993 struct tcb *tcp;
994
995 filename = argv[0];
996 if (strchr(filename, '/')) {
997 if (strlen(filename) > sizeof pathname - 1) {
998 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200999 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +00001000 }
1001 strcpy(pathname, filename);
1002 }
1003#ifdef USE_DEBUGGING_EXEC
1004 /*
1005 * Debuggers customarily check the current directory
1006 * first regardless of the path but doing that gives
1007 * security geeks a panic attack.
1008 */
1009 else if (stat(filename, &statbuf) == 0)
1010 strcpy(pathname, filename);
1011#endif /* USE_DEBUGGING_EXEC */
1012 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +00001013 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +00001014 int m, n, len;
1015
1016 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +01001017 const char *colon = strchr(path, ':');
1018 if (colon) {
1019 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +00001020 m = n + 1;
1021 }
1022 else
1023 m = n = strlen(path);
1024 if (n == 0) {
1025 if (!getcwd(pathname, MAXPATHLEN))
1026 continue;
1027 len = strlen(pathname);
1028 }
1029 else if (n > sizeof pathname - 1)
1030 continue;
1031 else {
1032 strncpy(pathname, path, n);
1033 len = n;
1034 }
1035 if (len && pathname[len - 1] != '/')
1036 pathname[len++] = '/';
1037 strcpy(pathname + len, filename);
1038 if (stat(pathname, &statbuf) == 0 &&
1039 /* Accept only regular files
1040 with some execute bits set.
1041 XXX not perfect, might still fail */
1042 S_ISREG(statbuf.st_mode) &&
1043 (statbuf.st_mode & 0111))
1044 break;
1045 }
1046 }
1047 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001048 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +00001049 }
Dmitry V. Levina6809652008-11-10 17:14:58 +00001050 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001051 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001052 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001053 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001054 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1055 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001056 ) {
1057 pid = getpid();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001058 if (shared_log != stderr)
1059 close(fileno(shared_log));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001060 if (!daemonized_tracer && !use_seize) {
1061 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001062 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001063 }
Roland McGrath02203312007-06-11 22:06:31 +00001064 }
Roland McGrath02203312007-06-11 22:06:31 +00001065
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001066 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +00001067 uid_t run_euid = run_uid;
1068 gid_t run_egid = run_gid;
1069
1070 if (statbuf.st_mode & S_ISUID)
1071 run_euid = statbuf.st_uid;
1072 if (statbuf.st_mode & S_ISGID)
1073 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +00001074 /*
1075 * It is important to set groups before we
1076 * lose privileges on setuid.
1077 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001078 if (initgroups(username, run_gid) < 0) {
1079 perror_msg_and_die("initgroups");
1080 }
1081 if (setregid(run_gid, run_egid) < 0) {
1082 perror_msg_and_die("setregid");
1083 }
1084 if (setreuid(run_uid, run_euid) < 0) {
1085 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +00001086 }
1087 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001088 else if (geteuid() != 0)
Dmitry V. Levin508279c2012-08-24 17:56:53 +00001089 if (setreuid(run_uid, run_uid) < 0) {
1090 perror_msg_and_die("setreuid");
1091 }
Roland McGrath02203312007-06-11 22:06:31 +00001092
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001093 if (!daemonized_tracer) {
1094 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001095 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001096 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001097 * the immediately following execve syscall.
1098 * Can't do this on NOMMU systems, we are after
1099 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001100 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -04001101 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001102 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001103 } else {
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001104 alarm(3);
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001105 /* we depend on SIGCHLD set to SIG_DFL by init code */
1106 /* if it happens to be SIG_IGN'ed, wait won't block */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001107 wait(NULL);
1108 alarm(0);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001109 }
Roland McGrath02203312007-06-11 22:06:31 +00001110
1111 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001112 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +00001113 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001114
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001115 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +02001116
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001117 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001118 if (!use_seize) {
1119 /* child did PTRACE_TRACEME, nothing to do in parent */
1120 } else {
1121 if (!strace_vforked) {
1122 /* Wait until child stopped itself */
1123 int status;
1124 while (waitpid(pid, &status, WSTOPPED) < 0) {
1125 if (errno == EINTR)
1126 continue;
1127 perror_msg_and_die("waitpid");
1128 }
1129 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001130 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001131 perror_msg_and_die("Unexpected wait status %x", status);
1132 }
1133 }
1134 /* Else: vforked case, we have no way to sync.
1135 * Just attach to it as soon as possible.
1136 * This means that we may miss a few first syscalls...
1137 */
1138
1139 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001140 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001141 perror_msg_and_die("Can't attach to %d", pid);
1142 }
1143 if (!strace_vforked)
1144 kill(pid, SIGCONT);
1145 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001146 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001147 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001148 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001149 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001150 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001151 newoutf(tcp);
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001152 }
1153 else {
1154 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1155 strace_tracer_pid = getpid();
1156 /* The tracee is our parent: */
1157 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +01001158 alloctcb(pid);
1159 /* attaching will be done later, by startup_attach */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001160 /* note: we don't do newoutf(tcp) here either! */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001161 }
Roland McGrath02203312007-06-11 22:06:31 +00001162}
1163
Wang Chaob13c0de2010-11-12 17:25:19 +08001164/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001165 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +08001166 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001167 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +08001168 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001169static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001170test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +08001171{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001172 int pid, expected_grandchild = 0, found_grandchild = 0;
1173 const unsigned int test_options = PTRACE_O_TRACECLONE |
1174 PTRACE_O_TRACEFORK |
1175 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +08001176
Denys Vlasenko5d645812011-08-20 12:48:18 +02001177 pid = fork();
1178 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001179 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +02001180 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001181 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001182 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001183 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1184 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001185 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001186 if (fork() < 0)
1187 perror_msg_and_die("fork");
1188 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +08001189 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001190
1191 while (1) {
1192 int status, tracee_pid;
1193
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001194 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001195 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001196 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001197 if (errno == EINTR)
1198 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001199 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001200 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001201 kill_save_errno(pid, SIGKILL);
1202 perror_msg_and_die("%s: unexpected wait result %d",
1203 __func__, tracee_pid);
1204 }
1205 if (WIFEXITED(status)) {
1206 if (WEXITSTATUS(status)) {
1207 if (tracee_pid != pid)
1208 kill_save_errno(pid, SIGKILL);
1209 error_msg_and_die("%s: unexpected exit status %u",
1210 __func__, WEXITSTATUS(status));
1211 }
1212 continue;
1213 }
1214 if (WIFSIGNALED(status)) {
1215 if (tracee_pid != pid)
1216 kill_save_errno(pid, SIGKILL);
1217 error_msg_and_die("%s: unexpected signal %u",
1218 __func__, WTERMSIG(status));
1219 }
1220 if (!WIFSTOPPED(status)) {
1221 if (tracee_pid != pid)
1222 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001223 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001224 error_msg_and_die("%s: unexpected wait status %x",
1225 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001226 }
1227 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001228 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001229 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1230 kill_save_errno(tracee_pid, SIGKILL);
1231 kill_save_errno(pid, SIGKILL);
1232 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001233 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001234 continue;
1235 }
1236 switch (WSTOPSIG(status)) {
1237 case SIGSTOP:
1238 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1239 && errno != EINVAL && errno != EIO)
1240 perror_msg("PTRACE_SETOPTIONS");
1241 break;
1242 case SIGTRAP:
1243 if (status >> 16 == PTRACE_EVENT_FORK) {
1244 long msg = 0;
1245
1246 if (ptrace(PTRACE_GETEVENTMSG, pid,
1247 NULL, (long) &msg) == 0)
1248 expected_grandchild = msg;
1249 }
1250 break;
1251 }
1252 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1253 kill_save_errno(pid, SIGKILL);
1254 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001255 }
1256 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001257 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001258 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001259 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001260 fprintf(stderr, "ptrace_setoptions = %#x\n",
1261 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001262 return 0;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001263 }
1264 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1265 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001266 return 1;
Wang Chaob13c0de2010-11-12 17:25:19 +08001267}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001268
1269/*
1270 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1271 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1272 * and then see whether it will stop with (SIGTRAP | 0x80).
1273 *
1274 * Use of this option enables correct handling of user-generated SIGTRAPs,
1275 * and SIGTRAPs generated by special instructions such as int3 on x86:
1276 * _start: .globl _start
1277 * int3
1278 * movl $42, %ebx
1279 * movl $1, %eax
1280 * int $0x80
1281 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1282 */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001283static int
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001284test_ptrace_setoptions_for_all(void)
1285{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001286 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1287 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001288 int pid;
1289 int it_worked = 0;
1290
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001291 /* this fork test doesn't work on no-mmu systems */
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001292 /* FIXME: isn't it better to assume we *succeed*? */
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001293 if (strace_vforked)
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001294 return 1;
Mike Frysinger7ff5ed92012-04-05 01:52:25 -04001295
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001296 pid = fork();
1297 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001298 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001299
1300 if (pid == 0) {
1301 pid = getpid();
1302 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001303 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001304 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1305 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001306 kill(pid, SIGSTOP);
1307 _exit(0); /* parent should see entry into this syscall */
1308 }
1309
1310 while (1) {
1311 int status, tracee_pid;
1312
1313 errno = 0;
1314 tracee_pid = wait(&status);
1315 if (tracee_pid <= 0) {
1316 if (errno == EINTR)
1317 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001318 kill_save_errno(pid, SIGKILL);
1319 perror_msg_and_die("%s: unexpected wait result %d",
1320 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001321 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001322 if (WIFEXITED(status)) {
1323 if (WEXITSTATUS(status) == 0)
1324 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001325 error_msg_and_die("%s: unexpected exit status %u",
1326 __func__, WEXITSTATUS(status));
1327 }
1328 if (WIFSIGNALED(status)) {
1329 error_msg_and_die("%s: unexpected signal %u",
1330 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001331 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001332 if (!WIFSTOPPED(status)) {
1333 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001334 error_msg_and_die("%s: unexpected wait status %x",
1335 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001336 }
1337 if (WSTOPSIG(status) == SIGSTOP) {
1338 /*
1339 * We don't check "options aren't accepted" error.
1340 * If it happens, we'll never get (SIGTRAP | 0x80),
1341 * and thus will decide to not use the option.
1342 * IOW: the outcome of the test will be correct.
1343 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001344 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1345 && errno != EINVAL && errno != EIO)
1346 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001347 }
1348 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1349 it_worked = 1;
1350 }
1351 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001352 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001353 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001354 }
1355 }
1356
1357 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001358 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001359 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001360 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001361 fprintf(stderr, "ptrace_setoptions = %#x\n",
1362 ptrace_setoptions);
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001363 return 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001364 }
1365
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001366 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1367 "giving up using this feature.");
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001368 return 1;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001369}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001370
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001371#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001372static void
1373test_ptrace_seize(void)
1374{
1375 int pid;
1376
1377 pid = fork();
1378 if (pid < 0)
1379 perror_msg_and_die("fork");
1380
1381 if (pid == 0) {
1382 pause();
1383 _exit(0);
1384 }
1385
1386 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1387 * attaching tracee continues to run unless a trap condition occurs.
1388 * PTRACE_SEIZE doesn't affect signal or group stop state.
1389 */
Denys Vlasenko26bc0602012-07-10 16:36:32 +02001390 if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001391 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001392 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001393 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1394 }
1395
1396 kill(pid, SIGKILL);
1397
1398 while (1) {
1399 int status, tracee_pid;
1400
1401 errno = 0;
1402 tracee_pid = waitpid(pid, &status, 0);
1403 if (tracee_pid <= 0) {
1404 if (errno == EINTR)
1405 continue;
1406 perror_msg_and_die("%s: unexpected wait result %d",
1407 __func__, tracee_pid);
1408 }
1409 if (WIFSIGNALED(status)) {
1410 return;
1411 }
1412 error_msg_and_die("%s: unexpected wait status %x",
1413 __func__, status);
1414 }
1415}
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001416#else /* !USE_SEIZE */
1417# define test_ptrace_seize() ((void)0)
1418#endif
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001419
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001420static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001421get_os_release(void)
1422{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001423 unsigned rel;
1424 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001425 struct utsname u;
1426 if (uname(&u) < 0)
1427 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001428 /* u.release has this form: "3.2.9[-some-garbage]" */
1429 rel = 0;
1430 p = u.release;
1431 for (;;) {
1432 if (!(*p >= '0' && *p <= '9'))
1433 error_msg_and_die("Bad OS release string: '%s'", u.release);
1434 /* Note: this open-codes KERNEL_VERSION(): */
1435 rel = (rel << 8) | atoi(p);
1436 if (rel >= KERNEL_VERSION(1,0,0))
1437 break;
1438 while (*p >= '0' && *p <= '9')
1439 p++;
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001440 if (*p != '.') {
1441 if (rel >= KERNEL_VERSION(0,1,0)) {
1442 /* "X.Y-something" means "X.Y.0" */
1443 rel <<= 8;
1444 break;
1445 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001446 error_msg_and_die("Bad OS release string: '%s'", u.release);
Dmitry V. Levin0dbc80d2012-05-14 23:42:10 +00001447 }
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001448 p++;
1449 }
1450 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001451}
1452
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001453/*
1454 * Initialization part of main() was eating much stack (~0.5k),
1455 * which was unused after init.
1456 * We can reuse it if we move init code into a separate function.
1457 *
1458 * Don't want main() to inline us and defeat the reason
1459 * we have a separate function.
1460 */
1461static void __attribute__ ((noinline))
1462init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001463{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001464 struct tcb *tcp;
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001465 int c, i;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001466 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001467 struct sigaction sa;
1468
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001469 progname = argv[0] ? argv[0] : "strace";
1470
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001471 /* Make sure SIGCHLD has the default action so that waitpid
1472 definitely works without losing track of children. The user
1473 should not have given us a bogus state to inherit, but he might
1474 have. Arguably we should detect SIG_IGN here and pass it on
1475 to children, but probably noone really needs that. */
1476 signal(SIGCHLD, SIG_DFL);
1477
Denys Vlasenko75422762011-05-27 14:36:01 +02001478 strace_tracer_pid = getpid();
1479
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001480 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001481
Roland McGrathee9d4352002-12-18 04:16:10 +00001482 /* Allocate the initial tcbtab. */
1483 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001484 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001485 if (!tcbtab)
1486 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001487 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001488 if (!tcp)
1489 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001490 for (c = 0; c < tcbtabsize; c++)
1491 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001492
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001493 shared_log = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001494 set_sortby(DEFAULT_SORTBY);
1495 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001496 qualify("trace=all");
1497 qualify("abbrev=all");
1498 qualify("verbose=all");
1499 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001500 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001501 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001502 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001503 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001504 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001505 case 'b':
1506 detach_on_execve = 1;
1507 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001508 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001509 if (cflag == CFLAG_BOTH) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001510 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001511 }
1512 cflag = CFLAG_ONLY_STATS;
1513 break;
1514 case 'C':
1515 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001516 error_msg_and_die("-c and -C are mutually exclusive");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001517 }
1518 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001519 break;
1520 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001521 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001522 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001523 case 'D':
1524 daemonized_tracer = 1;
1525 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001526 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001527 optF = 1;
1528 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001529 case 'f':
1530 followfork++;
1531 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001532 case 'h':
1533 usage(stdout, 0);
1534 break;
1535 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001536 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001537 break;
1538 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001539 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001540 break;
1541 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001542 rflag = 1;
1543 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001544 case 't':
1545 tflag++;
1546 break;
1547 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001548 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001549 break;
1550 case 'x':
1551 xflag++;
1552 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001553 case 'y':
1554 show_fd_path = 1;
1555 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001556 case 'v':
1557 qualify("abbrev=none");
1558 break;
1559 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001560 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001561 exit(0);
1562 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001563 case 'z':
1564 not_failing_only = 1;
1565 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001566 case 'a':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001567 acolumn = string_to_uint(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001568 if (acolumn < 0)
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001569 error_opt_arg(c, optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001570 break;
1571 case 'e':
1572 qualify(optarg);
1573 break;
1574 case 'o':
1575 outfname = strdup(optarg);
1576 break;
1577 case 'O':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001578 i = string_to_uint(optarg);
1579 if (i < 0)
1580 error_opt_arg(c, optarg);
1581 set_overhead(i);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001582 break;
1583 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001584 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001585 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001586 case 'P':
1587 tracing_paths = 1;
1588 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001589 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001590 }
1591 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001592 case 's':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001593 i = string_to_uint(optarg);
1594 if (i < 0)
1595 error_opt_arg(c, optarg);
1596 max_strlen = i;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001597 break;
1598 case 'S':
1599 set_sortby(optarg);
1600 break;
1601 case 'u':
1602 username = strdup(optarg);
1603 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001604 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001605 if (putenv(optarg) < 0)
1606 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001607 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001608 case 'I':
Dmitry V. Levinccee1692012-03-25 21:49:48 +00001609 opt_intr = string_to_uint(optarg);
1610 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1611 error_opt_arg(c, optarg);
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001612 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001613 default:
1614 usage(stderr, 1);
1615 break;
1616 }
1617 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001618 argv += optind;
1619 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001620
Denys Vlasenko102ec492011-08-25 01:27:59 +02001621 acolumn_spaces = malloc(acolumn + 1);
1622 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001623 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001624 memset(acolumn_spaces, ' ', acolumn);
1625 acolumn_spaces[acolumn] = '\0';
1626
Denys Vlasenko837399a2012-01-24 11:37:03 +01001627 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001628 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001629 usage(stderr, 1);
1630
Denys Vlasenkofd883382012-03-09 13:03:41 +01001631 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001632 error_msg_and_die("-D and -p are mutually exclusive");
Wang Chaod322a4b2010-08-05 14:30:11 +08001633 }
1634
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001635 if (!followfork)
1636 followfork = optF;
1637
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001638 if (followfork >= 2 && cflag) {
Denys Vlasenkoc5ccfa42012-03-26 13:10:50 +02001639 error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
Roland McGrathcb9def62006-04-25 07:48:03 +00001640 }
1641
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001642 /* See if they want to run as another user. */
1643 if (username != NULL) {
1644 struct passwd *pent;
1645
1646 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001647 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001648 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001649 pent = getpwnam(username);
1650 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001651 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001652 }
1653 run_uid = pent->pw_uid;
1654 run_gid = pent->pw_gid;
1655 }
1656 else {
1657 run_uid = getuid();
1658 run_gid = getgid();
1659 }
1660
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001661 /*
1662 * On any reasonably recent Linux kernel (circa about 2.5.46)
1663 * need_fork_exec_workarounds should stay 0 after these tests:
1664 */
1665 /*need_fork_exec_workarounds = 0; - already is */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001666 if (followfork)
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001667 need_fork_exec_workarounds = test_ptrace_setoptions_followfork();
1668 need_fork_exec_workarounds |= test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001669 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001670
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001671 /* Check if they want to redirect the output. */
1672 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001673 /* See if they want to pipe the output. */
1674 if (outfname[0] == '|' || outfname[0] == '!') {
1675 /*
1676 * We can't do the <outfname>.PID funny business
1677 * when using popen, so prohibit it.
1678 */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001679 if (followfork >= 2)
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001680 error_msg_and_die("Piping the output and -ff are mutually exclusive");
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001681 shared_log = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001682 }
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001683 else if (followfork < 2)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001684 shared_log = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001685 } else {
1686 /* -ff without -o FILE is the same as single -f */
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001687 if (followfork >= 2)
Denys Vlasenko328bf252012-03-12 23:34:13 +01001688 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001689 }
1690
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001691 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001692 char *buf = malloc(BUFSIZ);
1693 if (!buf)
1694 die_out_of_memory();
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001695 setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001696 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001697 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001698 if (!opt_intr)
1699 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001700 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001701 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001702 if (!opt_intr)
1703 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001704
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001705 /* argv[0] -pPID -oFILE Default interactive setting
1706 * yes 0 0 INTR_WHILE_WAIT
1707 * no 1 0 INTR_WHILE_WAIT
1708 * yes 0 1 INTR_NEVER
1709 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001710 */
1711
1712 /* STARTUP_CHILD must be called before the signal handlers get
1713 installed below as they are inherited into the spawned process.
1714 Also we do not need to be protected by them as during interruption
1715 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001716 if (argv[0]) {
1717 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001718 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001719 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001720
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001721 sigemptyset(&empty_set);
1722 sigemptyset(&blocked_set);
1723 sa.sa_handler = SIG_IGN;
1724 sigemptyset(&sa.sa_mask);
1725 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001726 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1727 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1728 if (opt_intr != INTR_ANYWHERE) {
1729 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1730 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1731 /*
1732 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1733 * fatal signals are blocked while syscall stop is processed,
1734 * and acted on in between, when waiting for new syscall stops.
1735 * In non-interactive mode, signals are ignored.
1736 */
1737 if (opt_intr == INTR_WHILE_WAIT) {
1738 sigaddset(&blocked_set, SIGHUP);
1739 sigaddset(&blocked_set, SIGINT);
1740 sigaddset(&blocked_set, SIGQUIT);
1741 sigaddset(&blocked_set, SIGPIPE);
1742 sigaddset(&blocked_set, SIGTERM);
1743 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001744 }
1745 /* SIG_IGN, or set handler for these */
1746 sigaction(SIGHUP, &sa, NULL);
1747 sigaction(SIGINT, &sa, NULL);
1748 sigaction(SIGQUIT, &sa, NULL);
1749 sigaction(SIGPIPE, &sa, NULL);
1750 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001751 }
Denys Vlasenkofd883382012-03-09 13:03:41 +01001752 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001753 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001754
Denys Vlasenkofd883382012-03-09 13:03:41 +01001755 /* Do we want pids printed in our -o OUTFILE?
1756 * -ff: no (every pid has its own file); or
1757 * -f: yes (there can be more pids in the future); or
1758 * -p PID1,PID2: yes (there are already more than one pid)
1759 */
1760 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001761}
1762
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001763static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001764pid2tcb(int pid)
1765{
1766 int i;
1767
1768 if (pid <= 0)
1769 return NULL;
1770
1771 for (i = 0; i < tcbtabsize; i++) {
1772 struct tcb *tcp = tcbtab[i];
1773 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1774 return tcp;
1775 }
1776
1777 return NULL;
1778}
1779
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001780static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001781cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001782{
1783 int i;
1784 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001785 int fatal_sig;
1786
1787 /* 'interrupted' is a volatile object, fetch it only once */
1788 fatal_sig = interrupted;
1789 if (!fatal_sig)
1790 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001791
Roland McGrathee9d4352002-12-18 04:16:10 +00001792 for (i = 0; i < tcbtabsize; i++) {
1793 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794 if (!(tcp->flags & TCB_INUSE))
1795 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001796 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001797 fprintf(stderr,
1798 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001799 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001800 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001801 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001802 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001803 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804 }
1805 if (cflag)
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001806 call_summary(shared_log);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001807}
1808
1809static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001810interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001811{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001812 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001813}
1814
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001815static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001816trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001817{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001818 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001819 struct rusage *rup = cflag ? &ru : NULL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001820#ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001821 static int wait4_options = __WALL;
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001822#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001823
Roland McGratheb9e2e82009-06-02 16:49:22 -07001824 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001825 int pid;
1826 int wait_errno;
1827 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001828 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001829 struct tcb *tcp;
1830 unsigned event;
1831
Denys Vlasenko222713a2009-03-17 14:29:59 +00001832 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001833 return 0;
1834 if (interactive)
1835 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001836#ifdef __WALL
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001837 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001838 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001839 /* this kernel does not support __WALL */
1840 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001841 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001842 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001843 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001844 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001845 pid = wait4(-1, &status, __WCLONE, rup);
1846 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001847 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001848 }
1849 }
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001850#else
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001851 pid = wait4(-1, &status, 0, rup);
Denys Vlasenko978fbc92012-09-13 10:28:43 +02001852#endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001853 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001854 if (interactive)
1855 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001856
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001857 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001858 switch (wait_errno) {
1859 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001860 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001861 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001862 /*
1863 * We would like to verify this case
1864 * but sometimes a race in Solbourne's
1865 * version of SunOS sometimes reports
1866 * ECHILD before sending us SIGCHILD.
1867 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001868 return 0;
1869 default:
1870 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001871 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001872 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001873 }
1874 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001875 if (pid == popen_pid) {
1876 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001877 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001878 continue;
1879 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001880
1881 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001882 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001883 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001884 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001885 strcpy(buf, "???");
1886 if (WIFSIGNALED(status))
1887#ifdef WCOREDUMP
1888 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1889 WCOREDUMP(status) ? "core," : "",
1890 signame(WTERMSIG(status)));
1891#else
1892 sprintf(buf, "WIFSIGNALED,sig=%s",
1893 signame(WTERMSIG(status)));
1894#endif
1895 if (WIFEXITED(status))
1896 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1897 if (WIFSTOPPED(status))
1898 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001899#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001900 if (WIFCONTINUED(status))
1901 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001902#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001903 evbuf[0] = '\0';
1904 if (event != 0) {
1905 static const char *const event_names[] = {
1906 [PTRACE_EVENT_CLONE] = "CLONE",
1907 [PTRACE_EVENT_FORK] = "FORK",
1908 [PTRACE_EVENT_VFORK] = "VFORK",
1909 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1910 [PTRACE_EVENT_EXEC] = "EXEC",
1911 [PTRACE_EVENT_EXIT] = "EXIT",
1912 };
1913 const char *e;
1914 if (event < ARRAY_SIZE(event_names))
1915 e = event_names[event];
1916 else {
1917 sprintf(buf, "?? (%u)", event);
1918 e = buf;
1919 }
1920 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1921 }
1922 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001923 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001924
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001925 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001926 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001927
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001928 if (!tcp) {
Roland McGrath41c48222008-07-18 00:25:10 +00001929 if (followfork) {
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001930 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001931 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenko3db3b262012-03-16 15:15:14 +01001932 newoutf(tcp);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001933 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001934 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001935 pid);
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001936 } else {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001937 /* This can happen if a clone call used
1938 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001939 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001940 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001941 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001942 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001943 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001944
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001945 clear_regs();
1946 if (WIFSTOPPED(status))
1947 get_regs(pid);
1948
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001949 /* Under Linux, execve changes pid to thread leader's pid,
1950 * and we see this changed pid on EVENT_EXEC and later,
1951 * execve sysexit. Leader "disappears" without exit
1952 * notification. Let user know that, drop leader's tcb,
1953 * and fix up pid in execve thread's tcb.
1954 * Effectively, execve thread's tcb replaces leader's tcb.
1955 *
1956 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1957 * on exit syscall) in multithreaded programs exactly
1958 * in order to handle this case.
1959 *
1960 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1961 * On 2.6 and earlier, it can return garbage.
1962 */
1963 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001964 FILE *fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001965 struct tcb *execve_thread;
1966 long old_pid = 0;
1967
1968 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
1969 goto dont_switch_tcbs;
1970 if (old_pid <= 0 || old_pid == pid)
1971 goto dont_switch_tcbs;
1972 execve_thread = pid2tcb(old_pid);
1973 /* It should be !NULL, but I feel paranoid */
1974 if (!execve_thread)
1975 goto dont_switch_tcbs;
1976
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001977 if (execve_thread->curcol != 0) {
1978 /*
1979 * One case we are here is -ff:
1980 * try "strace -oLOG -ff test/threaded_execve"
1981 */
1982 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001983 /*execve_thread->curcol = 0; - no need, see code below */
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001984 }
1985 /* Swap output FILEs (needed for -ff) */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001986 fp = execve_thread->outf;
1987 execve_thread->outf = tcp->outf;
1988 tcp->outf = fp;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001989 /* And their column positions */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01001990 execve_thread->curcol = tcp->curcol;
1991 tcp->curcol = 0;
Denys Vlasenko8511f2a2012-03-22 09:35:51 +01001992 /* Drop leader, but close execve'd thread outfile (if -ff) */
1993 droptcb(tcp);
1994 /* Switch to the thread, reusing leader's outfile and pid */
1995 tcp = execve_thread;
1996 tcp->pid = pid;
1997 if (cflag != CFLAG_ONLY_STATS) {
1998 printleader(tcp);
1999 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
2000 line_ended();
2001 tcp->flags |= TCB_REPRINT;
2002 }
2003 }
2004 dont_switch_tcbs:
2005
2006 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
2007 if (!skip_startup_execve)
2008 detach(tcp);
2009 /* This was initial execve for "strace PROG". Skip. */
2010 skip_startup_execve = 0;
2011 }
2012
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002013 /* Set current output file */
Denys Vlasenko6764f8f2012-03-22 09:56:20 +01002014 current_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002015
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002016 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002017 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
2018 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002019 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07002020
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002021 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002022 if (pid == strace_child)
2023 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002024 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002025 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2026 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002027#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01002028 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00002029 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002030 WCOREDUMP(status) ? "(core dumped) " : "");
2031#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002032 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002033 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00002034#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002035 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002036 }
2037 droptcb(tcp);
2038 continue;
2039 }
2040 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002041 if (pid == strace_child)
2042 exit_code = WEXITSTATUS(status);
Denys Vlasenkob5e09082012-03-21 14:27:40 +01002043 if (cflag != CFLAG_ONLY_STATS) {
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002044 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01002045 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002046 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002047 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002048 droptcb(tcp);
2049 continue;
2050 }
2051 if (!WIFSTOPPED(status)) {
2052 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2053 droptcb(tcp);
2054 continue;
2055 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002056
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002057 /* Is this the very first time we see this tracee stopped? */
2058 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002059 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002060 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002061 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002062 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002063 /*
2064 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002065 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002066 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002067 if (clearbpt(tcp) < 0) {
2068 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002069 droptcb(tcp);
2070 cleanup();
2071 return -1;
2072 }
2073 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002074 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002075 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002076 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2077 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2078 if (errno != ESRCH) {
2079 /* Should never happen, really */
2080 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002081 }
2082 }
2083 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002084 }
2085
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002086 sig = WSTOPSIG(status);
2087
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002088 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002089 /* Ptrace event */
2090#ifdef USE_SEIZE
Denys Vlasenko26bc0602012-07-10 16:36:32 +02002091 if (event == PTRACE_EVENT_STOP) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002092 /*
2093 * PTRACE_INTERRUPT-stop or group-stop.
2094 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2095 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002096 if (sig == SIGSTOP
2097 || sig == SIGTSTP
2098 || sig == SIGTTIN
2099 || sig == SIGTTOU
2100 ) {
2101 stopped = 1;
2102 goto show_stopsig;
2103 }
2104 }
2105#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002106 goto restart_tracee_with_sig_0;
2107 }
2108
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002109 /* Is this post-attach SIGSTOP?
2110 * Interestingly, the process may stop
2111 * with STOPSIG equal to some other signal
2112 * than SIGSTOP if we happend to attach
2113 * just before the process takes a signal.
2114 */
2115 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002116 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002117 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2118 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002119 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002120 }
2121
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002122 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002123 siginfo_t si;
2124
2125 /* Nonzero (true) if tracee is stopped by signal
2126 * (as opposed to "tracee received signal").
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002127 * TODO: shouldn't we check for errno == EINVAL too?
2128 * We can get ESRCH instead, you know...
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002129 */
2130 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002131#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002132 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002133#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002134 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002135 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002136#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002137 long pc = 0;
2138 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002139
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002140 upeek(tcp, PT_CR_IPSR, &psr);
2141 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002142
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002143# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002144 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002145# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002146# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002147#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002148# define PC_FORMAT_STR ""
2149# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002150#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002151 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002152 if (!stopped) {
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002153 tprintf("--- %s ", signame(sig));
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002154 printsiginfo(&si, verbose(tcp));
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002155 tprintf(PC_FORMAT_STR " ---\n"
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002156 PC_FORMAT_ARG);
2157 } else
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002158 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002159 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002160 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002161 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002162 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002163
2164 if (!stopped)
2165 /* It's signal-delivery-stop. Inject the signal */
2166 goto restart_tracee;
2167
2168 /* It's group-stop */
2169#ifdef USE_SEIZE
2170 if (use_seize) {
2171 /*
2172 * This ends ptrace-stop, but does *not* end group-stop.
2173 * This makes stopping signals work properly on straced process
2174 * (that is, process really stops. It used to continue to run).
2175 */
2176 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2177 cleanup();
2178 return -1;
2179 }
2180 continue;
2181 }
2182 /* We don't have PTRACE_LISTEN support... */
2183#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002184 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002185 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002186
2187 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002188 if (interrupted)
2189 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002190
2191 /* This should be syscall entry or exit.
2192 * (Or it still can be that pesky post-execve SIGTRAP!)
2193 * Handle it.
2194 */
Denys Vlasenko23506752012-03-21 10:32:49 +01002195 if (trace_syscall(tcp) < 0) {
2196 /* ptrace() failed in trace_syscall().
Roland McGratheb9e2e82009-06-02 16:49:22 -07002197 * Likely a result of process disappearing mid-flight.
Denys Vlasenko23506752012-03-21 10:32:49 +01002198 * Observed case: exit_group() or SIGKILL terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002199 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002200 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002201 * We used to detach(tcp) here, but since we no longer
2202 * implement "detach before death" policy/hack,
2203 * we can let this process to report its death to us
2204 * normally, via WIFEXITED or WIFSIGNALED wait status.
2205 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002206 continue;
2207 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002208 restart_tracee_with_sig_0:
2209 sig = 0;
2210 restart_tracee:
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002211 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002212 cleanup();
2213 return -1;
2214 }
2215 }
2216 return 0;
2217}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002218
2219int
2220main(int argc, char *argv[])
2221{
2222 init(argc, argv);
2223
2224 /* Run main tracing loop */
2225 if (trace() < 0)
2226 return 1;
2227
2228 cleanup();
2229 fflush(NULL);
Dmitry V. Levincf534362012-07-12 20:54:46 +00002230 if (shared_log != stderr)
2231 fclose(shared_log);
2232 if (popen_pid) {
2233 while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR)
2234 ;
2235 }
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002236 if (exit_code > 0xff) {
2237 /* Avoid potential core file clobbering. */
2238 struct rlimit rlim = {0, 0};
2239 setrlimit(RLIMIT_CORE, &rlim);
2240
2241 /* Child was killed by a signal, mimic that. */
2242 exit_code &= 0xff;
2243 signal(exit_code, SIG_DFL);
2244 raise(exit_code);
2245 /* Paranoia - what if this signal is not fatal?
2246 Exit with 128 + signo then. */
2247 exit_code += 128;
2248 }
2249
2250 return exit_code;
2251}