blob: 7446b746773f68c812bff5dafc9d7d84fdf078f2 [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). */
57# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
58# 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;
68bool debug_flag = 0;
69bool Tflag = 0;
70bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020071/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020072static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010073static unsigned int tflag = 0;
74static bool iflag = 0;
75static bool rflag = 0;
76static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010077
78/* -I n */
79enum {
80 INTR_NOT_SET = 0,
81 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
82 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
83 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
84 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
85 NUM_INTR_OPTS
86};
87static int opt_intr;
88/* We play with signal mask only if this mode is active: */
89#define interactive (opt_intr == INTR_WHILE_WAIT)
90
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000091/*
92 * daemonized_tracer supports -D option.
93 * With this option, strace forks twice.
94 * Unlike normal case, with -D *grandparent* process exec's,
95 * becoming a traced process. Child exits (this prevents traced process
96 * from having children it doesn't expect to have), and grandchild
97 * attaches to grandparent similarly to strace -p PID.
98 * This allows for more transparent interaction in cases
99 * when process and its parent are communicating via signals,
100 * wait() etc. Without -D, strace process gets lodged in between,
101 * disrupting parent<->child link.
102 */
103static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000104
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100105#ifdef USE_SEIZE
106static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
107# define use_seize (post_attach_sigstop == 0)
108#else
109# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
110# define use_seize 0
111#endif
112
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000113/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100114bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000115
Grant Edwards8a082772011-04-07 20:25:40 +0000116/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100117bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000118
119/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100120bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000121
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100122static bool detach_on_execve = 0;
123static bool skip_startup_execve = 0;
124
Dmitry V. Levina6809652008-11-10 17:14:58 +0000125static int exit_code = 0;
126static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200127static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700128
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000129static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200130static uid_t run_uid;
131static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000132
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100133unsigned int max_strlen = DEFAULT_STRLEN;
134static unsigned int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200135static char *acolumn_spaces;
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000136static char *outfname = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200137static FILE *outf;
Denys Vlasenko000b6012012-01-28 01:25:03 +0100138struct tcb *printing_tcp = NULL;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100139static unsigned int curcol;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200140static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200141static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200142static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000143
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +0100144static unsigned os_release; /* generated from uname()'s u.release */
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100145
Denys Vlasenko4c196382012-01-04 15:11:09 +0100146static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100147static int trace(void);
148static void cleanup(void);
149static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000150static sigset_t empty_set, blocked_set;
151
152#ifdef HAVE_SIG_ATOMIC_T
153static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100154#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000155static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100156#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000157
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100158#ifndef HAVE_STRERROR
159
160#if !HAVE_DECL_SYS_ERRLIST
161extern int sys_nerr;
162extern char *sys_errlist[];
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +0100163#endif
Denys Vlasenko2c4fb902012-03-15 17:24:49 +0100164
165const char *
166strerror(int err_no)
167{
168 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
169
170 if (err_no < 1 || err_no >= sys_nerr) {
171 sprintf(buf, "Unknown error %d", err_no);
172 return buf;
173 }
174 return sys_errlist[err_no];
175}
176
177#endif /* HAVE_STERRROR */
178
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000179static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200180usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000181{
182 fprintf(ofp, "\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100183usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
184 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100185 [-P path] [PROG [ARGS]]\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100186 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100187 [PROG [ARGS]]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000188-c -- count time, calls, and errors for each syscall and report summary\n\
Andreas Schwabb87d30c2010-06-11 15:49:36 +0200189-C -- like -c but also print regular output while processes are running\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100190-d -- enable debug output to stderr\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100191-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000192-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100193-F -- attempt to follow vforks (deprecated, use -f)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000194-i -- print instruction pointer at time of syscall\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100195-I interruptible\n\
196 1: no signals are blocked\n\
197 2: fatal signals are blocked while decoding syscall (default)\n\
198 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
199 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
200 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000201-q -- suppress messages about attaching, detaching, etc.\n\
202-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100203-T -- print time spent in each syscall\n\
204-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000205-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000206-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100207-h -- print help message\n\
208-V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000209-a column -- alignment COLUMN for printing syscall results (default %d)\n\
210-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
211 options: trace, abbrev, verbose, raw, signal, read, or write\n\
212-o file -- send trace output to FILE instead of stderr\n\
213-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
214-p pid -- trace process with process id PID, may be repeated\n\
215-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
216-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
217-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000218-E var=val -- put var=val in the environment for command\n\
219-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000220-P path -- trace accesses to path\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100221"
222/* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000223-z -- print only succeeding syscalls\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100224 */
225/* experimental, don't document it yet (option letter may change in the future!)
226-b -- detach on successful execve\n\
227 */
Roland McGrathde6e5332003-01-24 04:31:23 +0000228, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000229 exit(exitval);
230}
231
Denys Vlasenko75422762011-05-27 14:36:01 +0200232static void die(void) __attribute__ ((noreturn));
233static void die(void)
234{
235 if (strace_tracer_pid == getpid()) {
236 cflag = 0;
237 cleanup();
238 }
239 exit(1);
240}
241
242static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200243{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100244 char *msg;
245
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000246 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100247
248 /* We want to print entire message with single fprintf to ensure
249 * message integrity if stderr is shared with other programs.
250 * Thus we use vasprintf + single fprintf.
251 */
252 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100253 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100254 if (err_no)
255 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
256 else
257 fprintf(stderr, "%s: %s\n", progname, msg);
258 free(msg);
259 } else {
260 /* malloc in vasprintf failed, try it without malloc */
261 fprintf(stderr, "%s: ", progname);
262 vfprintf(stderr, fmt, p);
263 if (err_no)
264 fprintf(stderr, ": %s\n", strerror(err_no));
265 else
266 putc('\n', stderr);
267 }
268 /* We don't switch stderr to buffered, thus fprintf(stderr)
269 * always flushes its output and this is not necessary: */
270 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200271}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200272
Denys Vlasenko75422762011-05-27 14:36:01 +0200273void error_msg(const char *fmt, ...)
274{
275 va_list p;
276 va_start(p, fmt);
277 verror_msg(0, fmt, p);
278 va_end(p);
279}
280
281void error_msg_and_die(const char *fmt, ...)
282{
283 va_list p;
284 va_start(p, fmt);
285 verror_msg(0, fmt, p);
286 die();
287}
288
289void perror_msg(const char *fmt, ...)
290{
291 va_list p;
292 va_start(p, fmt);
293 verror_msg(errno, fmt, p);
294 va_end(p);
295}
296
297void perror_msg_and_die(const char *fmt, ...)
298{
299 va_list p;
300 va_start(p, fmt);
301 verror_msg(errno, fmt, p);
302 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200303}
304
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200305void die_out_of_memory(void)
306{
307 static bool recursed = 0;
308 if (recursed)
309 exit(1);
310 recursed = 1;
311 error_msg_and_die("Out of memory");
312}
313
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400314/* Glue for systems without a MMU that cannot provide fork() */
315#ifdef HAVE_FORK
316# define strace_vforked 0
317#else
318# define strace_vforked 1
319# define fork() vfork()
320#endif
321
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100322#ifdef USE_SEIZE
323static int
324ptrace_attach_or_seize(int pid)
325{
326 int r;
327 if (!use_seize)
328 return ptrace(PTRACE_ATTACH, pid, 0, 0);
329 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
330 if (r)
331 return r;
332 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
333 return r;
334}
335#else
336# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
337#endif
338
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200339static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000340set_cloexec_flag(int fd)
341{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200342 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000343
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200344 flags = fcntl(fd, F_GETFD);
345 if (flags < 0) {
346 /* Can happen only if fd is bad.
347 * Should never happen: if it does, we have a bug
348 * in the caller. Therefore we just abort
349 * instead of propagating the error.
350 */
351 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000352 }
353
354 newflags = flags | FD_CLOEXEC;
355 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200356 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000357
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200358 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000359}
360
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100361static void kill_save_errno(pid_t pid, int sig)
362{
363 int saved_errno = errno;
364
365 (void) kill(pid, sig);
366 errno = saved_errno;
367}
368
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100369/*
370 * When strace is setuid executable, we have to swap uids
371 * before and after filesystem and process management operations.
372 */
373static void
374swap_uid(void)
375{
376 int euid = geteuid(), uid = getuid();
377
378 if (euid != uid && setreuid(euid, uid) < 0) {
379 perror_msg_and_die("setreuid");
380 }
381}
382
383#if _LFS64_LARGEFILE
384# define fopen_for_output fopen64
385#else
386# define fopen_for_output fopen
387#endif
388
389static FILE *
390strace_fopen(const char *path)
391{
392 FILE *fp;
393
394 swap_uid();
395 fp = fopen_for_output(path, "w");
396 if (!fp)
397 perror_msg_and_die("Can't fopen '%s'", path);
398 swap_uid();
399 set_cloexec_flag(fileno(fp));
400 return fp;
401}
402
403static int popen_pid = 0;
404
405#ifndef _PATH_BSHELL
406# define _PATH_BSHELL "/bin/sh"
407#endif
408
409/*
410 * We cannot use standard popen(3) here because we have to distinguish
411 * popen child process from other processes we trace, and standard popen(3)
412 * does not export its child's pid.
413 */
414static FILE *
415strace_popen(const char *command)
416{
417 FILE *fp;
418 int fds[2];
419
420 swap_uid();
421 if (pipe(fds) < 0)
422 perror_msg_and_die("pipe");
423
424 set_cloexec_flag(fds[1]); /* never fails */
425
426 popen_pid = vfork();
427 if (popen_pid == -1)
428 perror_msg_and_die("vfork");
429
430 if (popen_pid == 0) {
431 /* child */
432 close(fds[1]);
433 if (fds[0] != 0) {
434 if (dup2(fds[0], 0))
435 perror_msg_and_die("dup2");
436 close(fds[0]);
437 }
438 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
439 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
440 }
441
442 /* parent */
443 close(fds[0]);
444 swap_uid();
445 fp = fdopen(fds[1], "w");
446 if (!fp)
447 die_out_of_memory();
448 return fp;
449}
450
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100451void
452tprintf(const char *fmt, ...)
453{
454 va_list args;
455
456 va_start(args, fmt);
457 if (outf) {
458 int n = vfprintf(outf, fmt, args);
459 if (n < 0) {
460 if (outf != stderr)
461 perror(outfname == NULL
462 ? "<writing to pipe>" : outfname);
463 } else
464 curcol += n;
465 }
466 va_end(args);
467}
468
469void
470tprints(const char *str)
471{
472 if (outf) {
473 int n = fputs(str, outf);
474 if (n >= 0) {
475 curcol += strlen(str);
476 return;
477 }
478 if (outf != stderr)
479 perror(outfname == NULL
480 ? "<writing to pipe>" : outfname);
481 }
482}
483
484void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100485line_ended(void)
486{
487 curcol = 0;
488 fflush(outf);
489 if (!printing_tcp)
490 return;
491 printing_tcp->curcol = 0;
492 printing_tcp = NULL;
493}
494
495void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100496printleader(struct tcb *tcp)
497{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100498 /* If -ff, "previous tcb we printed" is always the same as current,
499 * because we have per-tcb output files.
500 */
501 if (followfork >= 2)
502 printing_tcp = tcp;
503
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100504 if (printing_tcp) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100505 outf = printing_tcp->outf;
506 curcol = printing_tcp->curcol;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100507 if (printing_tcp->ptrace_errno) {
508 if (printing_tcp->flags & TCB_INSYSCALL) {
509 tprints(" <unavailable>) ");
510 tabto();
511 }
512 tprints("= ? <unavailable>\n");
513 printing_tcp->ptrace_errno = 0;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100514 printing_tcp->curcol = 0;
515 }
516 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
517 /*
518 * case 1: we have a shared log (i.e. not -ff), and last line
519 * wasn't finished (same or different tcb, doesn't matter).
520 * case 2: split log, we are the same tcb, but our last line
521 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
522 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100523 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100524 printing_tcp->flags |= TCB_REPRINT;
525 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100526 }
527 }
528
529 printing_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100530 outf = tcp->outf;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100531 curcol = 0;
532
533 if (print_pid_pfx)
534 tprintf("%-5d ", tcp->pid);
535 else if (nprocs > 1 && !outfname)
536 tprintf("[pid %5u] ", tcp->pid);
537
538 if (tflag) {
539 char str[sizeof("HH:MM:SS")];
540 struct timeval tv, dtv;
541 static struct timeval otv;
542
543 gettimeofday(&tv, NULL);
544 if (rflag) {
545 if (otv.tv_sec == 0)
546 otv = tv;
547 tv_sub(&dtv, &tv, &otv);
548 tprintf("%6ld.%06ld ",
549 (long) dtv.tv_sec, (long) dtv.tv_usec);
550 otv = tv;
551 }
552 else if (tflag > 2) {
553 tprintf("%ld.%06ld ",
554 (long) tv.tv_sec, (long) tv.tv_usec);
555 }
556 else {
557 time_t local = tv.tv_sec;
558 strftime(str, sizeof(str), "%T", localtime(&local));
559 if (tflag > 1)
560 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
561 else
562 tprintf("%s ", str);
563 }
564 }
565 if (iflag)
566 printcall(tcp);
567}
568
569void
570tabto(void)
571{
572 if (curcol < acolumn)
573 tprints(acolumn_spaces + curcol);
574}
575
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200576static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000577newoutf(struct tcb *tcp)
578{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100579 if (outfname && followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000580 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000581 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200582 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000583 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000584}
585
Denys Vlasenko558e5122012-03-12 23:32:16 +0100586static void
Denys Vlasenko800ec8f2012-03-16 15:11:34 +0100587expand_tcbtab(void)
588{
589 /* Allocate some more TCBs and expand the table.
590 We don't want to relocate the TCBs because our
591 callers have pointers and it would be a pain.
592 So tcbtab is a table of pointers. Since we never
593 free the TCBs, we allocate a single chunk of many. */
594 int i = tcbtabsize;
595 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
596 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
597 if (!newtab || !newtcbs)
598 die_out_of_memory();
599 tcbtabsize *= 2;
600 tcbtab = newtab;
601 while (i < tcbtabsize)
602 tcbtab[i++] = newtcbs++;
603}
604
605static struct tcb *
606alloc_tcb(int pid, int command_options_parsed)
607{
608 int i;
609 struct tcb *tcp;
610
611 if (nprocs == tcbtabsize)
612 expand_tcbtab();
613
614 for (i = 0; i < tcbtabsize; i++) {
615 tcp = tcbtab[i];
616 if ((tcp->flags & TCB_INUSE) == 0) {
617 memset(tcp, 0, sizeof(*tcp));
618 tcp->pid = pid;
619 tcp->flags = TCB_INUSE;
620 tcp->outf = outf; /* Initialise to current out file */
621#if SUPPORTED_PERSONALITIES > 1
622 tcp->currpers = current_personality;
623#endif
624 nprocs++;
625 if (debug_flag)
626 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
627 if (command_options_parsed)
628 newoutf(tcp);
629 return tcp;
630 }
631 }
632 error_msg_and_die("bug in alloc_tcb");
633}
634#define alloctcb(pid) alloc_tcb((pid), 1)
635
636static void
637droptcb(struct tcb *tcp)
638{
639 if (tcp->pid == 0)
640 return;
641
642 nprocs--;
643 if (debug_flag)
644 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
645
646 if (tcp->outf) {
647 if (outfname && followfork >= 2) {
648 if (tcp->curcol != 0)
649 fprintf(tcp->outf, " <detached ...>\n");
650 fclose(tcp->outf);
651 if (outf == tcp->outf)
652 outf = NULL;
653 } else {
654 if (printing_tcp == tcp && tcp->curcol != 0)
655 fprintf(tcp->outf, " <detached ...>\n");
656 fflush(tcp->outf);
657 }
658 }
659
660 if (printing_tcp == tcp)
661 printing_tcp = NULL;
662
663 memset(tcp, 0, sizeof(*tcp));
664}
665
666/* detach traced process; continue with sig
667 * Never call DETACH twice on the same process as both unattached and
668 * attached-unstopped processes give the same ESRCH. For unattached process we
669 * would SIGSTOP it and wait for its SIGSTOP notification forever.
670 */
671static int
672detach(struct tcb *tcp)
673{
674 int error;
675 int status, sigstop_expected;
676
677 if (tcp->flags & TCB_BPTSET)
678 clearbpt(tcp);
679
680 /*
681 * Linux wrongly insists the child be stopped
682 * before detaching. Arghh. We go through hoops
683 * to make a clean break of things.
684 */
685#if defined(SPARC)
686#undef PTRACE_DETACH
687#define PTRACE_DETACH PTRACE_SUNDETACH
688#endif
689
690 error = 0;
691 sigstop_expected = 0;
692 if (tcp->flags & TCB_ATTACHED) {
693 /*
694 * We attached but possibly didn't see the expected SIGSTOP.
695 * We must catch exactly one as otherwise the detached process
696 * would be left stopped (process state T).
697 */
698 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
699 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
700 if (error == 0) {
701 /* On a clear day, you can see forever. */
702 }
703 else if (errno != ESRCH) {
704 /* Shouldn't happen. */
705 perror("detach: ptrace(PTRACE_DETACH, ...)");
706 }
707 else if (my_tkill(tcp->pid, 0) < 0) {
708 if (errno != ESRCH)
709 perror("detach: checking sanity");
710 }
711 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
712 if (errno != ESRCH)
713 perror("detach: stopping child");
714 }
715 else
716 sigstop_expected = 1;
717 }
718
719 if (sigstop_expected) {
720 for (;;) {
721#ifdef __WALL
722 if (waitpid(tcp->pid, &status, __WALL) < 0) {
723 if (errno == ECHILD) /* Already gone. */
724 break;
725 if (errno != EINVAL) {
726 perror("detach: waiting");
727 break;
728 }
729#endif /* __WALL */
730 /* No __WALL here. */
731 if (waitpid(tcp->pid, &status, 0) < 0) {
732 if (errno != ECHILD) {
733 perror("detach: waiting");
734 break;
735 }
736#ifdef __WCLONE
737 /* If no processes, try clones. */
738 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
739 if (errno != ECHILD)
740 perror("detach: waiting");
741 break;
742 }
743#endif /* __WCLONE */
744 }
745#ifdef __WALL
746 }
747#endif
748 if (!WIFSTOPPED(status)) {
749 /* Au revoir, mon ami. */
750 break;
751 }
752 if (WSTOPSIG(status) == SIGSTOP) {
753 ptrace_restart(PTRACE_DETACH, tcp, 0);
754 break;
755 }
756 error = ptrace_restart(PTRACE_CONT, tcp,
757 WSTOPSIG(status) == syscall_trap_sig ? 0
758 : WSTOPSIG(status));
759 if (error < 0)
760 break;
761 }
762 }
763
764 if (!qflag && (tcp->flags & TCB_ATTACHED))
765 fprintf(stderr, "Process %u detached\n", tcp->pid);
766
767 droptcb(tcp);
768
769 return error;
770}
771
772static void
Denys Vlasenko558e5122012-03-12 23:32:16 +0100773process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100774{
775 while (*opt) {
776 /*
777 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
778 * pidof uses space as delim, pgrep uses newline. :(
779 */
780 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100781 char *delim = opt + strcspn(opt, ", \n\t");
782 char c = *delim;
783
784 *delim = '\0';
785 pid = atoi(opt); /* TODO: stricter parsing of the number? */
786 if (pid <= 0) {
787 error_msg("Invalid process id: '%s'", opt);
788 *delim = c;
789 return;
790 }
791 if (pid == strace_tracer_pid) {
792 error_msg("I'm sorry, I can't let you do that, Dave.");
793 *delim = c;
794 return;
795 }
796 *delim = c;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100797 alloc_tcb(pid, 0);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100798 if (c == '\0')
799 break;
800 opt = delim + 1;
801 }
802}
803
Roland McGrath02203312007-06-11 22:06:31 +0000804static void
805startup_attach(void)
806{
807 int tcbi;
808 struct tcb *tcp;
809
810 /*
811 * Block user interruptions as we would leave the traced
812 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200813 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200814 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000815 */
816 if (interactive)
817 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
818
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000819 if (daemonized_tracer) {
820 pid_t pid = fork();
821 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200822 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000823 }
824 if (pid) { /* parent */
825 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200826 * Wait for grandchild to attach to straced process
827 * (grandparent). Grandchild SIGKILLs us after it attached.
828 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000829 * it proceeds to exec the straced program.
830 */
831 pause();
832 _exit(0); /* paranoia */
833 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200834 /* grandchild */
835 /* We will be the tracer process. Remember our new pid: */
836 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000837 }
838
Roland McGrath02203312007-06-11 22:06:31 +0000839 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
840 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200841
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100842 if (!(tcp->flags & TCB_INUSE))
843 continue;
844
Denys Vlasenkod116a732011-09-05 14:01:33 +0200845 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100846 if (tcp->flags & TCB_ATTACHED)
847 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200848
849 /* Reinitialize the output since it may have changed */
Roland McGrath02203312007-06-11 22:06:31 +0000850 tcp->outf = outf;
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200851 newoutf(tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000852
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000853 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000854 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000855 DIR *dir;
856
857 sprintf(procdir, "/proc/%d/task", tcp->pid);
858 dir = opendir(procdir);
859 if (dir != NULL) {
860 unsigned int ntid = 0, nerr = 0;
861 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200862
Roland McGrath02203312007-06-11 22:06:31 +0000863 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200864 struct tcb *cur_tcp;
865 int tid;
866
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000867 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000868 continue;
869 tid = atoi(de->d_name);
870 if (tid <= 0)
871 continue;
872 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100873 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000874 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100875 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200876 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200877 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200878 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100879 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200880 fprintf(stderr, "attach to pid %d succeeded\n", tid);
881 cur_tcp = tcp;
882 if (tid != tcp->pid)
883 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100884 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrath02203312007-06-11 22:06:31 +0000885 }
886 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200887 if (interactive) {
888 sigprocmask(SIG_SETMASK, &empty_set, NULL);
889 if (interrupted)
890 goto ret;
891 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
892 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000893 ntid -= nerr;
894 if (ntid == 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000895 perror("attach: ptrace(PTRACE_ATTACH, ...)");
896 droptcb(tcp);
897 continue;
898 }
899 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000900 fprintf(stderr, ntid > 1
901? "Process %u attached with %u threads - interrupt to quit\n"
902: "Process %u attached - interrupt to quit\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200903 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000904 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100905 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200906 /* -p PID, we failed to attach to PID itself
907 * but did attach to some of its sibling threads.
908 * Drop PID's tcp.
909 */
910 droptcb(tcp);
911 }
Roland McGrath02203312007-06-11 22:06:31 +0000912 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000913 } /* if (opendir worked) */
914 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100915 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000916 perror("attach: ptrace(PTRACE_ATTACH, ...)");
917 droptcb(tcp);
918 continue;
919 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100920 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100921 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200922 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000923
924 if (daemonized_tracer) {
925 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000926 * Make parent go away.
927 * Also makes grandparent's wait() unblock.
928 */
929 kill(getppid(), SIGKILL);
930 }
931
Roland McGrath02203312007-06-11 22:06:31 +0000932 if (!qflag)
933 fprintf(stderr,
934 "Process %u attached - interrupt to quit\n",
935 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200936 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000937
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200938 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000939 if (interactive)
940 sigprocmask(SIG_SETMASK, &empty_set, NULL);
941}
942
943static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200944startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000945{
946 struct stat statbuf;
947 const char *filename;
948 char pathname[MAXPATHLEN];
949 int pid = 0;
950 struct tcb *tcp;
951
952 filename = argv[0];
953 if (strchr(filename, '/')) {
954 if (strlen(filename) > sizeof pathname - 1) {
955 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200956 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000957 }
958 strcpy(pathname, filename);
959 }
960#ifdef USE_DEBUGGING_EXEC
961 /*
962 * Debuggers customarily check the current directory
963 * first regardless of the path but doing that gives
964 * security geeks a panic attack.
965 */
966 else if (stat(filename, &statbuf) == 0)
967 strcpy(pathname, filename);
968#endif /* USE_DEBUGGING_EXEC */
969 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000970 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +0000971 int m, n, len;
972
973 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100974 const char *colon = strchr(path, ':');
975 if (colon) {
976 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +0000977 m = n + 1;
978 }
979 else
980 m = n = strlen(path);
981 if (n == 0) {
982 if (!getcwd(pathname, MAXPATHLEN))
983 continue;
984 len = strlen(pathname);
985 }
986 else if (n > sizeof pathname - 1)
987 continue;
988 else {
989 strncpy(pathname, path, n);
990 len = n;
991 }
992 if (len && pathname[len - 1] != '/')
993 pathname[len++] = '/';
994 strcpy(pathname + len, filename);
995 if (stat(pathname, &statbuf) == 0 &&
996 /* Accept only regular files
997 with some execute bits set.
998 XXX not perfect, might still fail */
999 S_ISREG(statbuf.st_mode) &&
1000 (statbuf.st_mode & 0111))
1001 break;
1002 }
1003 }
1004 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001005 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +00001006 }
Dmitry V. Levina6809652008-11-10 17:14:58 +00001007 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001008 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001009 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001010 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001011 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
1012 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001013 ) {
1014 pid = getpid();
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001015 if (outf != stderr)
1016 close(fileno(outf));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001017 if (!daemonized_tracer && !use_seize) {
1018 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001019 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001020 }
Roland McGrath02203312007-06-11 22:06:31 +00001021 }
Roland McGrath02203312007-06-11 22:06:31 +00001022
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001023 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +00001024 uid_t run_euid = run_uid;
1025 gid_t run_egid = run_gid;
1026
1027 if (statbuf.st_mode & S_ISUID)
1028 run_euid = statbuf.st_uid;
1029 if (statbuf.st_mode & S_ISGID)
1030 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +00001031 /*
1032 * It is important to set groups before we
1033 * lose privileges on setuid.
1034 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001035 if (initgroups(username, run_gid) < 0) {
1036 perror_msg_and_die("initgroups");
1037 }
1038 if (setregid(run_gid, run_egid) < 0) {
1039 perror_msg_and_die("setregid");
1040 }
1041 if (setreuid(run_uid, run_euid) < 0) {
1042 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +00001043 }
1044 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +02001045 else if (geteuid() != 0)
Roland McGrath02203312007-06-11 22:06:31 +00001046 setreuid(run_uid, run_uid);
1047
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001048 if (!daemonized_tracer) {
1049 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001050 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001051 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001052 * the immediately following execve syscall.
1053 * Can't do this on NOMMU systems, we are after
1054 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001055 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -04001056 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001057 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001058 } else {
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001059 alarm(3);
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001060 /* we depend on SIGCHLD set to SIG_DFL by init code */
1061 /* if it happens to be SIG_IGN'ed, wait won't block */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001062 wait(NULL);
1063 alarm(0);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001064 }
Roland McGrath02203312007-06-11 22:06:31 +00001065
1066 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001067 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +00001068 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001069
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001070 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +02001071
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001072 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001073 if (!use_seize) {
1074 /* child did PTRACE_TRACEME, nothing to do in parent */
1075 } else {
1076 if (!strace_vforked) {
1077 /* Wait until child stopped itself */
1078 int status;
1079 while (waitpid(pid, &status, WSTOPPED) < 0) {
1080 if (errno == EINTR)
1081 continue;
1082 perror_msg_and_die("waitpid");
1083 }
1084 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001085 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001086 perror_msg_and_die("Unexpected wait status %x", status);
1087 }
1088 }
1089 /* Else: vforked case, we have no way to sync.
1090 * Just attach to it as soon as possible.
1091 * This means that we may miss a few first syscalls...
1092 */
1093
1094 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001095 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001096 perror_msg_and_die("Can't attach to %d", pid);
1097 }
1098 if (!strace_vforked)
1099 kill(pid, SIGCONT);
1100 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001101 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001102 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001103 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001104 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001105 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko2e968c02011-09-01 10:23:09 +02001106 }
1107 else {
1108 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
1109 strace_tracer_pid = getpid();
1110 /* The tracee is our parent: */
1111 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +01001112 alloctcb(pid);
1113 /* attaching will be done later, by startup_attach */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001114 }
Roland McGrath02203312007-06-11 22:06:31 +00001115}
1116
Wang Chaob13c0de2010-11-12 17:25:19 +08001117/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001118 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +08001119 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001120 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +08001121 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001122static void
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001123test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +08001124{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001125 int pid, expected_grandchild = 0, found_grandchild = 0;
1126 const unsigned int test_options = PTRACE_O_TRACECLONE |
1127 PTRACE_O_TRACEFORK |
1128 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +08001129
Denys Vlasenko5d645812011-08-20 12:48:18 +02001130 pid = fork();
1131 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001132 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +02001133 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001134 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001135 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001136 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1137 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001138 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001139 if (fork() < 0)
1140 perror_msg_and_die("fork");
1141 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +08001142 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001143
1144 while (1) {
1145 int status, tracee_pid;
1146
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001147 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001148 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001149 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001150 if (errno == EINTR)
1151 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001152 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001153 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001154 kill_save_errno(pid, SIGKILL);
1155 perror_msg_and_die("%s: unexpected wait result %d",
1156 __func__, tracee_pid);
1157 }
1158 if (WIFEXITED(status)) {
1159 if (WEXITSTATUS(status)) {
1160 if (tracee_pid != pid)
1161 kill_save_errno(pid, SIGKILL);
1162 error_msg_and_die("%s: unexpected exit status %u",
1163 __func__, WEXITSTATUS(status));
1164 }
1165 continue;
1166 }
1167 if (WIFSIGNALED(status)) {
1168 if (tracee_pid != pid)
1169 kill_save_errno(pid, SIGKILL);
1170 error_msg_and_die("%s: unexpected signal %u",
1171 __func__, WTERMSIG(status));
1172 }
1173 if (!WIFSTOPPED(status)) {
1174 if (tracee_pid != pid)
1175 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001176 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001177 error_msg_and_die("%s: unexpected wait status %x",
1178 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +00001179 }
1180 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +00001181 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001182 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
1183 kill_save_errno(tracee_pid, SIGKILL);
1184 kill_save_errno(pid, SIGKILL);
1185 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001186 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001187 continue;
1188 }
1189 switch (WSTOPSIG(status)) {
1190 case SIGSTOP:
1191 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1192 && errno != EINVAL && errno != EIO)
1193 perror_msg("PTRACE_SETOPTIONS");
1194 break;
1195 case SIGTRAP:
1196 if (status >> 16 == PTRACE_EVENT_FORK) {
1197 long msg = 0;
1198
1199 if (ptrace(PTRACE_GETEVENTMSG, pid,
1200 NULL, (long) &msg) == 0)
1201 expected_grandchild = msg;
1202 }
1203 break;
1204 }
1205 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1206 kill_save_errno(pid, SIGKILL);
1207 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001208 }
1209 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001210 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001211 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001212 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001213 fprintf(stderr, "ptrace_setoptions = %#x\n",
1214 ptrace_setoptions);
1215 return;
1216 }
1217 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1218 "giving up using this feature.");
Wang Chaob13c0de2010-11-12 17:25:19 +08001219}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001220
1221/*
1222 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1223 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1224 * and then see whether it will stop with (SIGTRAP | 0x80).
1225 *
1226 * Use of this option enables correct handling of user-generated SIGTRAPs,
1227 * and SIGTRAPs generated by special instructions such as int3 on x86:
1228 * _start: .globl _start
1229 * int3
1230 * movl $42, %ebx
1231 * movl $1, %eax
1232 * int $0x80
1233 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1234 */
1235static void
1236test_ptrace_setoptions_for_all(void)
1237{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001238 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1239 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001240 int pid;
1241 int it_worked = 0;
1242
1243 pid = fork();
1244 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001245 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001246
1247 if (pid == 0) {
1248 pid = getpid();
1249 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001250 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001251 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1252 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001253 kill(pid, SIGSTOP);
1254 _exit(0); /* parent should see entry into this syscall */
1255 }
1256
1257 while (1) {
1258 int status, tracee_pid;
1259
1260 errno = 0;
1261 tracee_pid = wait(&status);
1262 if (tracee_pid <= 0) {
1263 if (errno == EINTR)
1264 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001265 kill_save_errno(pid, SIGKILL);
1266 perror_msg_and_die("%s: unexpected wait result %d",
1267 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001268 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001269 if (WIFEXITED(status)) {
1270 if (WEXITSTATUS(status) == 0)
1271 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001272 error_msg_and_die("%s: unexpected exit status %u",
1273 __func__, WEXITSTATUS(status));
1274 }
1275 if (WIFSIGNALED(status)) {
1276 error_msg_and_die("%s: unexpected signal %u",
1277 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001278 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001279 if (!WIFSTOPPED(status)) {
1280 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001281 error_msg_and_die("%s: unexpected wait status %x",
1282 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001283 }
1284 if (WSTOPSIG(status) == SIGSTOP) {
1285 /*
1286 * We don't check "options aren't accepted" error.
1287 * If it happens, we'll never get (SIGTRAP | 0x80),
1288 * and thus will decide to not use the option.
1289 * IOW: the outcome of the test will be correct.
1290 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001291 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1292 && errno != EINVAL && errno != EIO)
1293 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001294 }
1295 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1296 it_worked = 1;
1297 }
1298 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001299 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001300 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001301 }
1302 }
1303
1304 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001305 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001306 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001307 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001308 fprintf(stderr, "ptrace_setoptions = %#x\n",
1309 ptrace_setoptions);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001310 return;
1311 }
1312
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001313 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1314 "giving up using this feature.");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001315}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001316
1317# ifdef USE_SEIZE
1318static void
1319test_ptrace_seize(void)
1320{
1321 int pid;
1322
1323 pid = fork();
1324 if (pid < 0)
1325 perror_msg_and_die("fork");
1326
1327 if (pid == 0) {
1328 pause();
1329 _exit(0);
1330 }
1331
1332 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1333 * attaching tracee continues to run unless a trap condition occurs.
1334 * PTRACE_SEIZE doesn't affect signal or group stop state.
1335 */
1336 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1337 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001338 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001339 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1340 }
1341
1342 kill(pid, SIGKILL);
1343
1344 while (1) {
1345 int status, tracee_pid;
1346
1347 errno = 0;
1348 tracee_pid = waitpid(pid, &status, 0);
1349 if (tracee_pid <= 0) {
1350 if (errno == EINTR)
1351 continue;
1352 perror_msg_and_die("%s: unexpected wait result %d",
1353 __func__, tracee_pid);
1354 }
1355 if (WIFSIGNALED(status)) {
1356 return;
1357 }
1358 error_msg_and_die("%s: unexpected wait status %x",
1359 __func__, status);
1360 }
1361}
1362# else /* !USE_SEIZE */
1363# define test_ptrace_seize() ((void)0)
1364# endif
1365
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001366static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001367get_os_release(void)
1368{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001369 unsigned rel;
1370 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001371 struct utsname u;
1372 if (uname(&u) < 0)
1373 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001374 /* u.release has this form: "3.2.9[-some-garbage]" */
1375 rel = 0;
1376 p = u.release;
1377 for (;;) {
1378 if (!(*p >= '0' && *p <= '9'))
1379 error_msg_and_die("Bad OS release string: '%s'", u.release);
1380 /* Note: this open-codes KERNEL_VERSION(): */
1381 rel = (rel << 8) | atoi(p);
1382 if (rel >= KERNEL_VERSION(1,0,0))
1383 break;
1384 while (*p >= '0' && *p <= '9')
1385 p++;
1386 if (*p != '.')
1387 error_msg_and_die("Bad OS release string: '%s'", u.release);
1388 p++;
1389 }
1390 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001391}
1392
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001393/*
1394 * Initialization part of main() was eating much stack (~0.5k),
1395 * which was unused after init.
1396 * We can reuse it if we move init code into a separate function.
1397 *
1398 * Don't want main() to inline us and defeat the reason
1399 * we have a separate function.
1400 */
1401static void __attribute__ ((noinline))
1402init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001403{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001404 struct tcb *tcp;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001405 int c;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001406 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001407 struct sigaction sa;
1408
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001409 progname = argv[0] ? argv[0] : "strace";
1410
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001411 /* Make sure SIGCHLD has the default action so that waitpid
1412 definitely works without losing track of children. The user
1413 should not have given us a bogus state to inherit, but he might
1414 have. Arguably we should detect SIG_IGN here and pass it on
1415 to children, but probably noone really needs that. */
1416 signal(SIGCHLD, SIG_DFL);
1417
Denys Vlasenko75422762011-05-27 14:36:01 +02001418 strace_tracer_pid = getpid();
1419
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001420 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001421
Roland McGrathee9d4352002-12-18 04:16:10 +00001422 /* Allocate the initial tcbtab. */
1423 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001424 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001425 if (!tcbtab)
1426 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001427 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001428 if (!tcp)
1429 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001430 for (c = 0; c < tcbtabsize; c++)
1431 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001432
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001433 outf = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001434 set_sortby(DEFAULT_SORTBY);
1435 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001436 qualify("trace=all");
1437 qualify("abbrev=all");
1438 qualify("verbose=all");
1439 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001440 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001441 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001442 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001443 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001444 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001445 case 'b':
1446 detach_on_execve = 1;
1447 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001448 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001449 if (cflag == CFLAG_BOTH) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001450 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001451 }
1452 cflag = CFLAG_ONLY_STATS;
1453 break;
1454 case 'C':
1455 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001456 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001457 }
1458 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001459 break;
1460 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001461 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001462 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001463 case 'D':
1464 daemonized_tracer = 1;
1465 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001466 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001467 optF = 1;
1468 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001469 case 'f':
1470 followfork++;
1471 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001472 case 'h':
1473 usage(stdout, 0);
1474 break;
1475 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001476 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001477 break;
1478 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001479 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001480 break;
1481 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001482 rflag = 1;
1483 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001484 case 't':
1485 tflag++;
1486 break;
1487 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001488 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001489 break;
1490 case 'x':
1491 xflag++;
1492 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001493 case 'y':
1494 show_fd_path = 1;
1495 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001496 case 'v':
1497 qualify("abbrev=none");
1498 break;
1499 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001500 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001501 exit(0);
1502 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001503 case 'z':
1504 not_failing_only = 1;
1505 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001506 case 'a':
1507 acolumn = atoi(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001508 if (acolumn < 0)
1509 error_msg_and_die("Bad column width '%s'", optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001510 break;
1511 case 'e':
1512 qualify(optarg);
1513 break;
1514 case 'o':
1515 outfname = strdup(optarg);
1516 break;
1517 case 'O':
1518 set_overhead(atoi(optarg));
1519 break;
1520 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001521 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001522 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001523 case 'P':
1524 tracing_paths = 1;
1525 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001526 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001527 }
1528 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001529 case 's':
1530 max_strlen = atoi(optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001531 if (max_strlen < 0) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001532 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001533 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001534 break;
1535 case 'S':
1536 set_sortby(optarg);
1537 break;
1538 case 'u':
1539 username = strdup(optarg);
1540 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001541 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001542 if (putenv(optarg) < 0)
1543 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001544 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001545 case 'I':
1546 opt_intr = atoi(optarg);
1547 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1548 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1549 }
1550 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001551 default:
1552 usage(stderr, 1);
1553 break;
1554 }
1555 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001556 argv += optind;
1557 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001558
Denys Vlasenko102ec492011-08-25 01:27:59 +02001559 acolumn_spaces = malloc(acolumn + 1);
1560 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001561 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001562 memset(acolumn_spaces, ' ', acolumn);
1563 acolumn_spaces[acolumn] = '\0';
1564
Denys Vlasenko837399a2012-01-24 11:37:03 +01001565 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001566 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001567 usage(stderr, 1);
1568
Denys Vlasenkofd883382012-03-09 13:03:41 +01001569 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001570 error_msg_and_die("-D and -p are mutually exclusive options");
Wang Chaod322a4b2010-08-05 14:30:11 +08001571 }
1572
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001573 if (!followfork)
1574 followfork = optF;
1575
Roland McGrathcb9def62006-04-25 07:48:03 +00001576 if (followfork > 1 && cflag) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001577 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
Roland McGrathcb9def62006-04-25 07:48:03 +00001578 }
1579
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001580 /* See if they want to run as another user. */
1581 if (username != NULL) {
1582 struct passwd *pent;
1583
1584 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001585 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001586 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001587 pent = getpwnam(username);
1588 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001589 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001590 }
1591 run_uid = pent->pw_uid;
1592 run_gid = pent->pw_gid;
1593 }
1594 else {
1595 run_uid = getuid();
1596 run_gid = getgid();
1597 }
1598
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001599 if (followfork)
1600 test_ptrace_setoptions_followfork();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001601 test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001602 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001603
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604 /* Check if they want to redirect the output. */
1605 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001606 /* See if they want to pipe the output. */
1607 if (outfname[0] == '|' || outfname[0] == '!') {
1608 /*
1609 * We can't do the <outfname>.PID funny business
1610 * when using popen, so prohibit it.
1611 */
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001612 if (followfork > 1)
1613 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1614 outf = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001615 }
Denys Vlasenko3d5ed412011-06-22 13:17:16 +02001616 else if (followfork <= 1)
1617 outf = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001618 } else {
1619 /* -ff without -o FILE is the same as single -f */
1620 if (followfork > 1)
1621 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001622 }
1623
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001624 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001625 char *buf = malloc(BUFSIZ);
1626 if (!buf)
1627 die_out_of_memory();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001628 setvbuf(outf, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001629 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001630 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001631 if (!opt_intr)
1632 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001633 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001634 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001635 if (!opt_intr)
1636 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001637
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001638 /* argv[0] -pPID -oFILE Default interactive setting
1639 * yes 0 0 INTR_WHILE_WAIT
1640 * no 1 0 INTR_WHILE_WAIT
1641 * yes 0 1 INTR_NEVER
1642 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001643 */
1644
1645 /* STARTUP_CHILD must be called before the signal handlers get
1646 installed below as they are inherited into the spawned process.
1647 Also we do not need to be protected by them as during interruption
1648 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001649 if (argv[0]) {
1650 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001651 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001652 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001653
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001654 sigemptyset(&empty_set);
1655 sigemptyset(&blocked_set);
1656 sa.sa_handler = SIG_IGN;
1657 sigemptyset(&sa.sa_mask);
1658 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001659 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1660 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1661 if (opt_intr != INTR_ANYWHERE) {
1662 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1663 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1664 /*
1665 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1666 * fatal signals are blocked while syscall stop is processed,
1667 * and acted on in between, when waiting for new syscall stops.
1668 * In non-interactive mode, signals are ignored.
1669 */
1670 if (opt_intr == INTR_WHILE_WAIT) {
1671 sigaddset(&blocked_set, SIGHUP);
1672 sigaddset(&blocked_set, SIGINT);
1673 sigaddset(&blocked_set, SIGQUIT);
1674 sigaddset(&blocked_set, SIGPIPE);
1675 sigaddset(&blocked_set, SIGTERM);
1676 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001677 }
1678 /* SIG_IGN, or set handler for these */
1679 sigaction(SIGHUP, &sa, NULL);
1680 sigaction(SIGINT, &sa, NULL);
1681 sigaction(SIGQUIT, &sa, NULL);
1682 sigaction(SIGPIPE, &sa, NULL);
1683 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001684 }
Denys Vlasenkofd883382012-03-09 13:03:41 +01001685 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001686 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001687
Denys Vlasenkofd883382012-03-09 13:03:41 +01001688 /* Do we want pids printed in our -o OUTFILE?
1689 * -ff: no (every pid has its own file); or
1690 * -f: yes (there can be more pids in the future); or
1691 * -p PID1,PID2: yes (there are already more than one pid)
1692 */
1693 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694}
1695
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001696static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001697pid2tcb(int pid)
1698{
1699 int i;
1700
1701 if (pid <= 0)
1702 return NULL;
1703
1704 for (i = 0; i < tcbtabsize; i++) {
1705 struct tcb *tcp = tcbtab[i];
1706 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1707 return tcp;
1708 }
1709
1710 return NULL;
1711}
1712
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001713static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001714cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001715{
1716 int i;
1717 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001718 int fatal_sig;
1719
1720 /* 'interrupted' is a volatile object, fetch it only once */
1721 fatal_sig = interrupted;
1722 if (!fatal_sig)
1723 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001724
Roland McGrathee9d4352002-12-18 04:16:10 +00001725 for (i = 0; i < tcbtabsize; i++) {
1726 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001727 if (!(tcp->flags & TCB_INUSE))
1728 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001729 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001730 fprintf(stderr,
1731 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001732 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001733 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001734 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001735 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001736 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001737 }
1738 if (cflag)
1739 call_summary(outf);
1740}
1741
1742static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001743interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001744{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001745 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746}
1747
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001748static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001749trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001750{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001751 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001752 struct rusage *rup = cflag ? &ru : NULL;
1753# ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001754 static int wait4_options = __WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001755# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001756
Roland McGratheb9e2e82009-06-02 16:49:22 -07001757 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001758 int pid;
1759 int wait_errno;
1760 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001761 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001762 struct tcb *tcp;
1763 unsigned event;
1764
Denys Vlasenko222713a2009-03-17 14:29:59 +00001765 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001766 return 0;
1767 if (interactive)
1768 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001769# ifdef __WALL
1770 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001771 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001772 /* this kernel does not support __WALL */
1773 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001774 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001775 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001776 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001777 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001778 pid = wait4(-1, &status, __WCLONE, rup);
1779 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001780 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001781 }
1782 }
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001783# else
1784 pid = wait4(-1, &status, 0, rup);
1785# endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001786 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001787 if (interactive)
1788 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001789
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001790 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001791 switch (wait_errno) {
1792 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001793 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001794 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001795 /*
1796 * We would like to verify this case
1797 * but sometimes a race in Solbourne's
1798 * version of SunOS sometimes reports
1799 * ECHILD before sending us SIGCHILD.
1800 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001801 return 0;
1802 default:
1803 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001804 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001805 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001806 }
1807 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001808 if (pid == popen_pid) {
1809 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001810 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001811 continue;
1812 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001813
1814 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001815 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001816 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001817 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001818 strcpy(buf, "???");
1819 if (WIFSIGNALED(status))
1820#ifdef WCOREDUMP
1821 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1822 WCOREDUMP(status) ? "core," : "",
1823 signame(WTERMSIG(status)));
1824#else
1825 sprintf(buf, "WIFSIGNALED,sig=%s",
1826 signame(WTERMSIG(status)));
1827#endif
1828 if (WIFEXITED(status))
1829 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1830 if (WIFSTOPPED(status))
1831 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001832#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001833 if (WIFCONTINUED(status))
1834 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001835#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001836 evbuf[0] = '\0';
1837 if (event != 0) {
1838 static const char *const event_names[] = {
1839 [PTRACE_EVENT_CLONE] = "CLONE",
1840 [PTRACE_EVENT_FORK] = "FORK",
1841 [PTRACE_EVENT_VFORK] = "VFORK",
1842 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1843 [PTRACE_EVENT_EXEC] = "EXEC",
1844 [PTRACE_EVENT_EXIT] = "EXIT",
1845 };
1846 const char *e;
1847 if (event < ARRAY_SIZE(event_names))
1848 e = event_names[event];
1849 else {
1850 sprintf(buf, "?? (%u)", event);
1851 e = buf;
1852 }
1853 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1854 }
1855 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001856 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001857
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001858 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001859 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001860
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001861 /* Under Linux, execve changes pid to thread leader's pid,
1862 * and we see this changed pid on EVENT_EXEC and later,
1863 * execve sysexit. Leader "disappears" without exit
1864 * notification. Let user know that, drop leader's tcb,
1865 * and fix up pid in execve thread's tcb.
1866 * Effectively, execve thread's tcb replaces leader's tcb.
1867 *
1868 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1869 * on exit syscall) in multithreaded programs exactly
1870 * in order to handle this case.
1871 *
1872 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1873 * On 2.6 and earlier, it can return garbage.
1874 */
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001875 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001876 long old_pid = 0;
1877 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1878 && old_pid > 0
1879 && old_pid != pid
1880 ) {
1881 struct tcb *execve_thread = pid2tcb(old_pid);
1882 if (tcp) {
1883 outf = tcp->outf;
1884 curcol = tcp->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001885 if (execve_thread) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001886 if (execve_thread->curcol != 0) {
1887 /*
1888 * One case we are here is -ff:
1889 * try "strace -oLOG -ff test/threaded_execve"
1890 */
1891 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1892 execve_thread->curcol = 0;
1893 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001894 /* swap output FILEs (needed for -ff) */
1895 tcp->outf = execve_thread->outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001896 tcp->curcol = execve_thread->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001897 execve_thread->outf = outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001898 execve_thread->curcol = curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001899 }
1900 droptcb(tcp);
1901 }
1902 tcp = execve_thread;
1903 if (tcp) {
1904 tcp->pid = pid;
1905 tcp->flags |= TCB_REPRINT;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001906 if (!cflag) {
1907 printleader(tcp);
1908 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1909 line_ended();
1910 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001911 }
1912 }
1913 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001914
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001915 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1916 if (!skip_startup_execve)
1917 detach(tcp);
1918 /* This was initial execve for "strace PROG". Skip. */
1919 skip_startup_execve = 0;
1920 }
1921
Denys Vlasenko5d645812011-08-20 12:48:18 +02001922 if (tcp == NULL) {
Roland McGrath41c48222008-07-18 00:25:10 +00001923 if (followfork) {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001924 /* This is needed to go with the CLONE_PTRACE
1925 changes in process.c/util.c: we might see
1926 the child's initial trap before we see the
1927 parent return from the clone syscall.
1928 Leave the child suspended until the parent
1929 returns from its system call. Only then
1930 will we have the association of parent and
1931 child so that we know how to do clearbpt
1932 in the child. */
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001933 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001934 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001935 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001936 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001937 pid);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001938 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001939 else
1940 /* This can happen if a clone call used
1941 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001942 {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001943 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001944 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001945 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001946 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001947 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001948
1949 /* Set current output file */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001950 outf = tcp->outf;
Andreas Schwabccdff482009-10-27 16:27:13 +01001951 curcol = tcp->curcol;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001952
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001953 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001954 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1955 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001956 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07001957
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001958 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001959 if (pid == strace_child)
1960 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001961 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001962 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1963 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001964#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01001965 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00001966 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001967 WCOREDUMP(status) ? "(core dumped) " : "");
1968#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01001969 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001970 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00001971#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001972 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001973 }
1974 droptcb(tcp);
1975 continue;
1976 }
1977 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001978 if (pid == strace_child)
1979 exit_code = WEXITSTATUS(status);
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001980 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1981 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01001982 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001983 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001984 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001985 droptcb(tcp);
1986 continue;
1987 }
1988 if (!WIFSTOPPED(status)) {
1989 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1990 droptcb(tcp);
1991 continue;
1992 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001993
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001994 /* Is this the very first time we see this tracee stopped? */
1995 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001996 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001997 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001998 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001999 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002000 /*
2001 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002002 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002003 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002004 if (clearbpt(tcp) < 0) {
2005 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002006 droptcb(tcp);
2007 cleanup();
2008 return -1;
2009 }
2010 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002011 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002012 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002013 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2014 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2015 if (errno != ESRCH) {
2016 /* Should never happen, really */
2017 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002018 }
2019 }
2020 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002021 }
2022
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002023 sig = WSTOPSIG(status);
2024
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002025 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002026 /* Ptrace event */
2027#ifdef USE_SEIZE
2028 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002029 /*
2030 * PTRACE_INTERRUPT-stop or group-stop.
2031 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2032 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002033 if (sig == SIGSTOP
2034 || sig == SIGTSTP
2035 || sig == SIGTTIN
2036 || sig == SIGTTOU
2037 ) {
2038 stopped = 1;
2039 goto show_stopsig;
2040 }
2041 }
2042#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002043 goto restart_tracee_with_sig_0;
2044 }
2045
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002046 /* Is this post-attach SIGSTOP?
2047 * Interestingly, the process may stop
2048 * with STOPSIG equal to some other signal
2049 * than SIGSTOP if we happend to attach
2050 * just before the process takes a signal.
2051 */
2052 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002053 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002054 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2055 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002056 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002057 }
2058
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002059 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002060 siginfo_t si;
2061
2062 /* Nonzero (true) if tracee is stopped by signal
2063 * (as opposed to "tracee received signal").
2064 */
2065 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002066#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002067 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002068#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002069 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002070 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002071#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002072 long pc = 0;
2073 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002074
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002075 upeek(tcp, PT_CR_IPSR, &psr);
2076 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002077
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002078# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002079 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002080# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002081# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002082#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002083# define PC_FORMAT_STR ""
2084# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002085#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002086 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002087 if (!stopped) {
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002088 tprintf("--- %s ", signame(sig));
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002089 printsiginfo(&si, verbose(tcp));
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002090 tprintf(PC_FORMAT_STR " ---\n"
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002091 PC_FORMAT_ARG);
2092 } else
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002093 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002094 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002095 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002096 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002097 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002098
2099 if (!stopped)
2100 /* It's signal-delivery-stop. Inject the signal */
2101 goto restart_tracee;
2102
2103 /* It's group-stop */
2104#ifdef USE_SEIZE
2105 if (use_seize) {
2106 /*
2107 * This ends ptrace-stop, but does *not* end group-stop.
2108 * This makes stopping signals work properly on straced process
2109 * (that is, process really stops. It used to continue to run).
2110 */
2111 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2112 cleanup();
2113 return -1;
2114 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002115 tcp->curcol = curcol;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002116 continue;
2117 }
2118 /* We don't have PTRACE_LISTEN support... */
2119#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002120 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002121 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002122
2123 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002124 if (interrupted)
2125 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002126
2127 /* This should be syscall entry or exit.
2128 * (Or it still can be that pesky post-execve SIGTRAP!)
2129 * Handle it.
2130 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07002131 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2132 /* ptrace() failed in trace_syscall() with ESRCH.
2133 * Likely a result of process disappearing mid-flight.
2134 * Observed case: exit_group() terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002135 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002136 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002137 * We used to detach(tcp) here, but since we no longer
2138 * implement "detach before death" policy/hack,
2139 * we can let this process to report its death to us
2140 * normally, via WIFEXITED or WIFSIGNALED wait status.
2141 */
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002142 tcp->curcol = curcol;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002143 continue;
2144 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002145 restart_tracee_with_sig_0:
2146 sig = 0;
2147 restart_tracee:
Andreas Schwabccdff482009-10-27 16:27:13 +01002148 /* Remember current print column before continuing. */
2149 tcp->curcol = curcol;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002150 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002151 cleanup();
2152 return -1;
2153 }
2154 }
2155 return 0;
2156}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002157
2158int
2159main(int argc, char *argv[])
2160{
2161 init(argc, argv);
2162
2163 /* Run main tracing loop */
2164 if (trace() < 0)
2165 return 1;
2166
2167 cleanup();
2168 fflush(NULL);
2169 if (exit_code > 0xff) {
2170 /* Avoid potential core file clobbering. */
2171 struct rlimit rlim = {0, 0};
2172 setrlimit(RLIMIT_CORE, &rlim);
2173
2174 /* Child was killed by a signal, mimic that. */
2175 exit_code &= 0xff;
2176 signal(exit_code, SIG_DFL);
2177 raise(exit_code);
2178 /* Paranoia - what if this signal is not fatal?
2179 Exit with 128 + signo then. */
2180 exit_code += 128;
2181 }
2182
2183 return exit_code;
2184}