blob: 6e22e8b0ea384aafab0fe69f7cf75c63406ceb2d [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 Vlasenko2e856a12012-03-12 23:02:26 +0100369void
370tprintf(const char *fmt, ...)
371{
372 va_list args;
373
374 va_start(args, fmt);
375 if (outf) {
376 int n = vfprintf(outf, fmt, args);
377 if (n < 0) {
378 if (outf != stderr)
379 perror(outfname == NULL
380 ? "<writing to pipe>" : outfname);
381 } else
382 curcol += n;
383 }
384 va_end(args);
385}
386
387void
388tprints(const char *str)
389{
390 if (outf) {
391 int n = fputs(str, outf);
392 if (n >= 0) {
393 curcol += strlen(str);
394 return;
395 }
396 if (outf != stderr)
397 perror(outfname == NULL
398 ? "<writing to pipe>" : outfname);
399 }
400}
401
402void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100403line_ended(void)
404{
405 curcol = 0;
406 fflush(outf);
407 if (!printing_tcp)
408 return;
409 printing_tcp->curcol = 0;
410 printing_tcp = NULL;
411}
412
413void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100414printleader(struct tcb *tcp)
415{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100416 /* If -ff, "previous tcb we printed" is always the same as current,
417 * because we have per-tcb output files.
418 */
419 if (followfork >= 2)
420 printing_tcp = tcp;
421
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100422 if (printing_tcp) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100423 outf = printing_tcp->outf;
424 curcol = printing_tcp->curcol;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100425 if (printing_tcp->ptrace_errno) {
426 if (printing_tcp->flags & TCB_INSYSCALL) {
427 tprints(" <unavailable>) ");
428 tabto();
429 }
430 tprints("= ? <unavailable>\n");
431 printing_tcp->ptrace_errno = 0;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100432 printing_tcp->curcol = 0;
433 }
434 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
435 /*
436 * case 1: we have a shared log (i.e. not -ff), and last line
437 * wasn't finished (same or different tcb, doesn't matter).
438 * case 2: split log, we are the same tcb, but our last line
439 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
440 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100441 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100442 printing_tcp->flags |= TCB_REPRINT;
443 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100444 }
445 }
446
447 printing_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100448 outf = tcp->outf;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100449 curcol = 0;
450
451 if (print_pid_pfx)
452 tprintf("%-5d ", tcp->pid);
453 else if (nprocs > 1 && !outfname)
454 tprintf("[pid %5u] ", tcp->pid);
455
456 if (tflag) {
457 char str[sizeof("HH:MM:SS")];
458 struct timeval tv, dtv;
459 static struct timeval otv;
460
461 gettimeofday(&tv, NULL);
462 if (rflag) {
463 if (otv.tv_sec == 0)
464 otv = tv;
465 tv_sub(&dtv, &tv, &otv);
466 tprintf("%6ld.%06ld ",
467 (long) dtv.tv_sec, (long) dtv.tv_usec);
468 otv = tv;
469 }
470 else if (tflag > 2) {
471 tprintf("%ld.%06ld ",
472 (long) tv.tv_sec, (long) tv.tv_usec);
473 }
474 else {
475 time_t local = tv.tv_sec;
476 strftime(str, sizeof(str), "%T", localtime(&local));
477 if (tflag > 1)
478 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
479 else
480 tprintf("%s ", str);
481 }
482 }
483 if (iflag)
484 printcall(tcp);
485}
486
487void
488tabto(void)
489{
490 if (curcol < acolumn)
491 tprints(acolumn_spaces + curcol);
492}
493
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000494/*
495 * When strace is setuid executable, we have to swap uids
496 * before and after filesystem and process management operations.
497 */
498static void
499swap_uid(void)
500{
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000501 int euid = geteuid(), uid = getuid();
502
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200503 if (euid != uid && setreuid(euid, uid) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200504 perror_msg_and_die("setreuid");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000505 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000506}
507
Roland McGrath4bfa6262007-07-05 20:03:16 +0000508#if _LFS64_LARGEFILE
509# define fopen_for_output fopen64
510#else
511# define fopen_for_output fopen
512#endif
513
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000514static FILE *
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200515strace_fopen(const char *path)
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000516{
517 FILE *fp;
518
519 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200520 fp = fopen_for_output(path, "w");
521 if (!fp)
522 perror_msg_and_die("Can't fopen '%s'", path);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000523 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200524 set_cloexec_flag(fileno(fp));
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000525 return fp;
526}
527
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200528static int popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000529
530#ifndef _PATH_BSHELL
531# define _PATH_BSHELL "/bin/sh"
532#endif
533
534/*
535 * We cannot use standard popen(3) here because we have to distinguish
536 * popen child process from other processes we trace, and standard popen(3)
537 * does not export its child's pid.
538 */
539static FILE *
540strace_popen(const char *command)
541{
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200542 FILE *fp;
543 int fds[2];
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000544
545 swap_uid();
546 if (pipe(fds) < 0)
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200547 perror_msg_and_die("pipe");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000548
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200549 set_cloexec_flag(fds[1]); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000550
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200551 popen_pid = vfork();
552 if (popen_pid == -1)
553 perror_msg_and_die("vfork");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000554
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200555 if (popen_pid == 0) {
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000556 /* child */
557 close(fds[1]);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200558 if (fds[0] != 0) {
559 if (dup2(fds[0], 0))
560 perror_msg_and_die("dup2");
561 close(fds[0]);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000562 }
563 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200564 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000565 }
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200566
567 /* parent */
568 close(fds[0]);
569 swap_uid();
570 fp = fdopen(fds[1], "w");
571 if (!fp)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200572 die_out_of_memory();
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200573 return fp;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000574}
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
587process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100588{
589 while (*opt) {
590 /*
591 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
592 * pidof uses space as delim, pgrep uses newline. :(
593 */
594 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100595 char *delim = opt + strcspn(opt, ", \n\t");
596 char c = *delim;
597
598 *delim = '\0';
599 pid = atoi(opt); /* TODO: stricter parsing of the number? */
600 if (pid <= 0) {
601 error_msg("Invalid process id: '%s'", opt);
602 *delim = c;
603 return;
604 }
605 if (pid == strace_tracer_pid) {
606 error_msg("I'm sorry, I can't let you do that, Dave.");
607 *delim = c;
608 return;
609 }
610 *delim = c;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100611 alloc_tcb(pid, 0);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100612 if (c == '\0')
613 break;
614 opt = delim + 1;
615 }
616}
617
Roland McGrath02203312007-06-11 22:06:31 +0000618static void
619startup_attach(void)
620{
621 int tcbi;
622 struct tcb *tcp;
623
624 /*
625 * Block user interruptions as we would leave the traced
626 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200627 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200628 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000629 */
630 if (interactive)
631 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
632
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000633 if (daemonized_tracer) {
634 pid_t pid = fork();
635 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200636 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000637 }
638 if (pid) { /* parent */
639 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200640 * Wait for grandchild to attach to straced process
641 * (grandparent). Grandchild SIGKILLs us after it attached.
642 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000643 * it proceeds to exec the straced program.
644 */
645 pause();
646 _exit(0); /* paranoia */
647 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200648 /* grandchild */
649 /* We will be the tracer process. Remember our new pid: */
650 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000651 }
652
Roland McGrath02203312007-06-11 22:06:31 +0000653 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
654 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200655
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100656 if (!(tcp->flags & TCB_INUSE))
657 continue;
658
Denys Vlasenkod116a732011-09-05 14:01:33 +0200659 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100660 if (tcp->flags & TCB_ATTACHED)
661 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200662
663 /* Reinitialize the output since it may have changed */
Roland McGrath02203312007-06-11 22:06:31 +0000664 tcp->outf = outf;
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200665 newoutf(tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000666
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000667 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000668 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000669 DIR *dir;
670
671 sprintf(procdir, "/proc/%d/task", tcp->pid);
672 dir = opendir(procdir);
673 if (dir != NULL) {
674 unsigned int ntid = 0, nerr = 0;
675 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200676
Roland McGrath02203312007-06-11 22:06:31 +0000677 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200678 struct tcb *cur_tcp;
679 int tid;
680
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000681 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000682 continue;
683 tid = atoi(de->d_name);
684 if (tid <= 0)
685 continue;
686 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100687 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000688 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100689 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200690 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200691 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200692 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100693 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200694 fprintf(stderr, "attach to pid %d succeeded\n", tid);
695 cur_tcp = tcp;
696 if (tid != tcp->pid)
697 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100698 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrath02203312007-06-11 22:06:31 +0000699 }
700 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200701 if (interactive) {
702 sigprocmask(SIG_SETMASK, &empty_set, NULL);
703 if (interrupted)
704 goto ret;
705 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
706 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000707 ntid -= nerr;
708 if (ntid == 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000709 perror("attach: ptrace(PTRACE_ATTACH, ...)");
710 droptcb(tcp);
711 continue;
712 }
713 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000714 fprintf(stderr, ntid > 1
715? "Process %u attached with %u threads - interrupt to quit\n"
716: "Process %u attached - interrupt to quit\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200717 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000718 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100719 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200720 /* -p PID, we failed to attach to PID itself
721 * but did attach to some of its sibling threads.
722 * Drop PID's tcp.
723 */
724 droptcb(tcp);
725 }
Roland McGrath02203312007-06-11 22:06:31 +0000726 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000727 } /* if (opendir worked) */
728 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100729 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000730 perror("attach: ptrace(PTRACE_ATTACH, ...)");
731 droptcb(tcp);
732 continue;
733 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100734 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100735 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200736 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000737
738 if (daemonized_tracer) {
739 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000740 * Make parent go away.
741 * Also makes grandparent's wait() unblock.
742 */
743 kill(getppid(), SIGKILL);
744 }
745
Roland McGrath02203312007-06-11 22:06:31 +0000746 if (!qflag)
747 fprintf(stderr,
748 "Process %u attached - interrupt to quit\n",
749 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200750 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000751
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200752 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000753 if (interactive)
754 sigprocmask(SIG_SETMASK, &empty_set, NULL);
755}
756
757static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200758startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000759{
760 struct stat statbuf;
761 const char *filename;
762 char pathname[MAXPATHLEN];
763 int pid = 0;
764 struct tcb *tcp;
765
766 filename = argv[0];
767 if (strchr(filename, '/')) {
768 if (strlen(filename) > sizeof pathname - 1) {
769 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200770 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000771 }
772 strcpy(pathname, filename);
773 }
774#ifdef USE_DEBUGGING_EXEC
775 /*
776 * Debuggers customarily check the current directory
777 * first regardless of the path but doing that gives
778 * security geeks a panic attack.
779 */
780 else if (stat(filename, &statbuf) == 0)
781 strcpy(pathname, filename);
782#endif /* USE_DEBUGGING_EXEC */
783 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000784 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +0000785 int m, n, len;
786
787 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100788 const char *colon = strchr(path, ':');
789 if (colon) {
790 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +0000791 m = n + 1;
792 }
793 else
794 m = n = strlen(path);
795 if (n == 0) {
796 if (!getcwd(pathname, MAXPATHLEN))
797 continue;
798 len = strlen(pathname);
799 }
800 else if (n > sizeof pathname - 1)
801 continue;
802 else {
803 strncpy(pathname, path, n);
804 len = n;
805 }
806 if (len && pathname[len - 1] != '/')
807 pathname[len++] = '/';
808 strcpy(pathname + len, filename);
809 if (stat(pathname, &statbuf) == 0 &&
810 /* Accept only regular files
811 with some execute bits set.
812 XXX not perfect, might still fail */
813 S_ISREG(statbuf.st_mode) &&
814 (statbuf.st_mode & 0111))
815 break;
816 }
817 }
818 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200819 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +0000820 }
Dmitry V. Levina6809652008-11-10 17:14:58 +0000821 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000822 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200823 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000824 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200825 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
826 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000827 ) {
828 pid = getpid();
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200829 if (outf != stderr)
830 close(fileno(outf));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100831 if (!daemonized_tracer && !use_seize) {
832 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200833 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000834 }
Roland McGrath02203312007-06-11 22:06:31 +0000835 }
Roland McGrath02203312007-06-11 22:06:31 +0000836
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200837 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +0000838 uid_t run_euid = run_uid;
839 gid_t run_egid = run_gid;
840
841 if (statbuf.st_mode & S_ISUID)
842 run_euid = statbuf.st_uid;
843 if (statbuf.st_mode & S_ISGID)
844 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +0000845 /*
846 * It is important to set groups before we
847 * lose privileges on setuid.
848 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200849 if (initgroups(username, run_gid) < 0) {
850 perror_msg_and_die("initgroups");
851 }
852 if (setregid(run_gid, run_egid) < 0) {
853 perror_msg_and_die("setregid");
854 }
855 if (setreuid(run_uid, run_euid) < 0) {
856 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +0000857 }
858 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200859 else if (geteuid() != 0)
Roland McGrath02203312007-06-11 22:06:31 +0000860 setreuid(run_uid, run_uid);
861
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000862 if (!daemonized_tracer) {
863 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200864 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000865 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200866 * the immediately following execve syscall.
867 * Can't do this on NOMMU systems, we are after
868 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000869 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400870 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200871 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000872 } else {
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000873 alarm(3);
Denys Vlasenkoa5090542012-03-15 17:27:49 +0100874 /* we depend on SIGCHLD set to SIG_DFL by init code */
875 /* if it happens to be SIG_IGN'ed, wait won't block */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000876 wait(NULL);
877 alarm(0);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000878 }
Roland McGrath02203312007-06-11 22:06:31 +0000879
880 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200881 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000882 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000883
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200884 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +0200885
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200886 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100887 if (!use_seize) {
888 /* child did PTRACE_TRACEME, nothing to do in parent */
889 } else {
890 if (!strace_vforked) {
891 /* Wait until child stopped itself */
892 int status;
893 while (waitpid(pid, &status, WSTOPPED) < 0) {
894 if (errno == EINTR)
895 continue;
896 perror_msg_and_die("waitpid");
897 }
898 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100899 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100900 perror_msg_and_die("Unexpected wait status %x", status);
901 }
902 }
903 /* Else: vforked case, we have no way to sync.
904 * Just attach to it as soon as possible.
905 * This means that we may miss a few first syscalls...
906 */
907
908 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100909 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100910 perror_msg_and_die("Can't attach to %d", pid);
911 }
912 if (!strace_vforked)
913 kill(pid, SIGCONT);
914 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200915 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200916 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100917 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200918 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100919 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200920 }
921 else {
922 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
923 strace_tracer_pid = getpid();
924 /* The tracee is our parent: */
925 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +0100926 alloctcb(pid);
927 /* attaching will be done later, by startup_attach */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000928 }
Roland McGrath02203312007-06-11 22:06:31 +0000929}
930
Wang Chaob13c0de2010-11-12 17:25:19 +0800931/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000932 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +0800933 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000934 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +0800935 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000936static void
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200937test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +0800938{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000939 int pid, expected_grandchild = 0, found_grandchild = 0;
940 const unsigned int test_options = PTRACE_O_TRACECLONE |
941 PTRACE_O_TRACEFORK |
942 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +0800943
Denys Vlasenko5d645812011-08-20 12:48:18 +0200944 pid = fork();
945 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000946 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +0200947 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000948 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100949 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000950 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
951 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100952 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000953 if (fork() < 0)
954 perror_msg_and_die("fork");
955 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +0800956 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000957
958 while (1) {
959 int status, tracee_pid;
960
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000961 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000962 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000963 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000964 if (errno == EINTR)
965 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100966 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000967 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000968 kill_save_errno(pid, SIGKILL);
969 perror_msg_and_die("%s: unexpected wait result %d",
970 __func__, tracee_pid);
971 }
972 if (WIFEXITED(status)) {
973 if (WEXITSTATUS(status)) {
974 if (tracee_pid != pid)
975 kill_save_errno(pid, SIGKILL);
976 error_msg_and_die("%s: unexpected exit status %u",
977 __func__, WEXITSTATUS(status));
978 }
979 continue;
980 }
981 if (WIFSIGNALED(status)) {
982 if (tracee_pid != pid)
983 kill_save_errno(pid, SIGKILL);
984 error_msg_and_die("%s: unexpected signal %u",
985 __func__, WTERMSIG(status));
986 }
987 if (!WIFSTOPPED(status)) {
988 if (tracee_pid != pid)
989 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100990 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000991 error_msg_and_die("%s: unexpected wait status %x",
992 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000993 }
994 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000995 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000996 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
997 kill_save_errno(tracee_pid, SIGKILL);
998 kill_save_errno(pid, SIGKILL);
999 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001000 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001001 continue;
1002 }
1003 switch (WSTOPSIG(status)) {
1004 case SIGSTOP:
1005 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
1006 && errno != EINVAL && errno != EIO)
1007 perror_msg("PTRACE_SETOPTIONS");
1008 break;
1009 case SIGTRAP:
1010 if (status >> 16 == PTRACE_EVENT_FORK) {
1011 long msg = 0;
1012
1013 if (ptrace(PTRACE_GETEVENTMSG, pid,
1014 NULL, (long) &msg) == 0)
1015 expected_grandchild = msg;
1016 }
1017 break;
1018 }
1019 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1020 kill_save_errno(pid, SIGKILL);
1021 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001022 }
1023 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001024 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001025 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001026 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001027 fprintf(stderr, "ptrace_setoptions = %#x\n",
1028 ptrace_setoptions);
1029 return;
1030 }
1031 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1032 "giving up using this feature.");
Wang Chaob13c0de2010-11-12 17:25:19 +08001033}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001034
1035/*
1036 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1037 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1038 * and then see whether it will stop with (SIGTRAP | 0x80).
1039 *
1040 * Use of this option enables correct handling of user-generated SIGTRAPs,
1041 * and SIGTRAPs generated by special instructions such as int3 on x86:
1042 * _start: .globl _start
1043 * int3
1044 * movl $42, %ebx
1045 * movl $1, %eax
1046 * int $0x80
1047 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1048 */
1049static void
1050test_ptrace_setoptions_for_all(void)
1051{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001052 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1053 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001054 int pid;
1055 int it_worked = 0;
1056
1057 pid = fork();
1058 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001059 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001060
1061 if (pid == 0) {
1062 pid = getpid();
1063 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001064 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001065 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1066 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001067 kill(pid, SIGSTOP);
1068 _exit(0); /* parent should see entry into this syscall */
1069 }
1070
1071 while (1) {
1072 int status, tracee_pid;
1073
1074 errno = 0;
1075 tracee_pid = wait(&status);
1076 if (tracee_pid <= 0) {
1077 if (errno == EINTR)
1078 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001079 kill_save_errno(pid, SIGKILL);
1080 perror_msg_and_die("%s: unexpected wait result %d",
1081 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001082 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001083 if (WIFEXITED(status)) {
1084 if (WEXITSTATUS(status) == 0)
1085 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001086 error_msg_and_die("%s: unexpected exit status %u",
1087 __func__, WEXITSTATUS(status));
1088 }
1089 if (WIFSIGNALED(status)) {
1090 error_msg_and_die("%s: unexpected signal %u",
1091 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001092 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001093 if (!WIFSTOPPED(status)) {
1094 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001095 error_msg_and_die("%s: unexpected wait status %x",
1096 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001097 }
1098 if (WSTOPSIG(status) == SIGSTOP) {
1099 /*
1100 * We don't check "options aren't accepted" error.
1101 * If it happens, we'll never get (SIGTRAP | 0x80),
1102 * and thus will decide to not use the option.
1103 * IOW: the outcome of the test will be correct.
1104 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001105 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1106 && errno != EINVAL && errno != EIO)
1107 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001108 }
1109 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1110 it_worked = 1;
1111 }
1112 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001113 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001114 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001115 }
1116 }
1117
1118 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001119 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001120 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001121 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001122 fprintf(stderr, "ptrace_setoptions = %#x\n",
1123 ptrace_setoptions);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001124 return;
1125 }
1126
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001127 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1128 "giving up using this feature.");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001129}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001130
1131# ifdef USE_SEIZE
1132static void
1133test_ptrace_seize(void)
1134{
1135 int pid;
1136
1137 pid = fork();
1138 if (pid < 0)
1139 perror_msg_and_die("fork");
1140
1141 if (pid == 0) {
1142 pause();
1143 _exit(0);
1144 }
1145
1146 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1147 * attaching tracee continues to run unless a trap condition occurs.
1148 * PTRACE_SEIZE doesn't affect signal or group stop state.
1149 */
1150 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1151 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001152 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001153 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1154 }
1155
1156 kill(pid, SIGKILL);
1157
1158 while (1) {
1159 int status, tracee_pid;
1160
1161 errno = 0;
1162 tracee_pid = waitpid(pid, &status, 0);
1163 if (tracee_pid <= 0) {
1164 if (errno == EINTR)
1165 continue;
1166 perror_msg_and_die("%s: unexpected wait result %d",
1167 __func__, tracee_pid);
1168 }
1169 if (WIFSIGNALED(status)) {
1170 return;
1171 }
1172 error_msg_and_die("%s: unexpected wait status %x",
1173 __func__, status);
1174 }
1175}
1176# else /* !USE_SEIZE */
1177# define test_ptrace_seize() ((void)0)
1178# endif
1179
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001180static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001181get_os_release(void)
1182{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001183 unsigned rel;
1184 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001185 struct utsname u;
1186 if (uname(&u) < 0)
1187 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001188 /* u.release has this form: "3.2.9[-some-garbage]" */
1189 rel = 0;
1190 p = u.release;
1191 for (;;) {
1192 if (!(*p >= '0' && *p <= '9'))
1193 error_msg_and_die("Bad OS release string: '%s'", u.release);
1194 /* Note: this open-codes KERNEL_VERSION(): */
1195 rel = (rel << 8) | atoi(p);
1196 if (rel >= KERNEL_VERSION(1,0,0))
1197 break;
1198 while (*p >= '0' && *p <= '9')
1199 p++;
1200 if (*p != '.')
1201 error_msg_and_die("Bad OS release string: '%s'", u.release);
1202 p++;
1203 }
1204 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001205}
1206
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001207/*
1208 * Initialization part of main() was eating much stack (~0.5k),
1209 * which was unused after init.
1210 * We can reuse it if we move init code into a separate function.
1211 *
1212 * Don't want main() to inline us and defeat the reason
1213 * we have a separate function.
1214 */
1215static void __attribute__ ((noinline))
1216init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001217{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001218 struct tcb *tcp;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001219 int c;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001220 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001221 struct sigaction sa;
1222
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001223 progname = argv[0] ? argv[0] : "strace";
1224
Denys Vlasenkoa5090542012-03-15 17:27:49 +01001225 /* Make sure SIGCHLD has the default action so that waitpid
1226 definitely works without losing track of children. The user
1227 should not have given us a bogus state to inherit, but he might
1228 have. Arguably we should detect SIG_IGN here and pass it on
1229 to children, but probably noone really needs that. */
1230 signal(SIGCHLD, SIG_DFL);
1231
Denys Vlasenko75422762011-05-27 14:36:01 +02001232 strace_tracer_pid = getpid();
1233
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001234 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001235
Roland McGrathee9d4352002-12-18 04:16:10 +00001236 /* Allocate the initial tcbtab. */
1237 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001238 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001239 if (!tcbtab)
1240 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001241 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001242 if (!tcp)
1243 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001244 for (c = 0; c < tcbtabsize; c++)
1245 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001246
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001247 outf = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001248 set_sortby(DEFAULT_SORTBY);
1249 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001250 qualify("trace=all");
1251 qualify("abbrev=all");
1252 qualify("verbose=all");
1253 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001254 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001255 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001256 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001257 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001258 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001259 case 'b':
1260 detach_on_execve = 1;
1261 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001262 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001263 if (cflag == CFLAG_BOTH) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001264 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001265 }
1266 cflag = CFLAG_ONLY_STATS;
1267 break;
1268 case 'C':
1269 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001270 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001271 }
1272 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001273 break;
1274 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001275 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001277 case 'D':
1278 daemonized_tracer = 1;
1279 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001280 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001281 optF = 1;
1282 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001283 case 'f':
1284 followfork++;
1285 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001286 case 'h':
1287 usage(stdout, 0);
1288 break;
1289 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001290 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001291 break;
1292 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001293 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001294 break;
1295 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001296 rflag = 1;
1297 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001298 case 't':
1299 tflag++;
1300 break;
1301 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001302 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001303 break;
1304 case 'x':
1305 xflag++;
1306 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001307 case 'y':
1308 show_fd_path = 1;
1309 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001310 case 'v':
1311 qualify("abbrev=none");
1312 break;
1313 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001314 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001315 exit(0);
1316 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001317 case 'z':
1318 not_failing_only = 1;
1319 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001320 case 'a':
1321 acolumn = atoi(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001322 if (acolumn < 0)
1323 error_msg_and_die("Bad column width '%s'", optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001324 break;
1325 case 'e':
1326 qualify(optarg);
1327 break;
1328 case 'o':
1329 outfname = strdup(optarg);
1330 break;
1331 case 'O':
1332 set_overhead(atoi(optarg));
1333 break;
1334 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001335 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001336 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001337 case 'P':
1338 tracing_paths = 1;
1339 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001340 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001341 }
1342 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001343 case 's':
1344 max_strlen = atoi(optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001345 if (max_strlen < 0) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001346 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001347 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001348 break;
1349 case 'S':
1350 set_sortby(optarg);
1351 break;
1352 case 'u':
1353 username = strdup(optarg);
1354 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001355 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001356 if (putenv(optarg) < 0)
1357 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001358 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001359 case 'I':
1360 opt_intr = atoi(optarg);
1361 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1362 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1363 }
1364 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001365 default:
1366 usage(stderr, 1);
1367 break;
1368 }
1369 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001370 argv += optind;
1371 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001372
Denys Vlasenko102ec492011-08-25 01:27:59 +02001373 acolumn_spaces = malloc(acolumn + 1);
1374 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001375 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001376 memset(acolumn_spaces, ' ', acolumn);
1377 acolumn_spaces[acolumn] = '\0';
1378
Denys Vlasenko837399a2012-01-24 11:37:03 +01001379 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001380 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001381 usage(stderr, 1);
1382
Denys Vlasenkofd883382012-03-09 13:03:41 +01001383 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001384 error_msg_and_die("-D and -p are mutually exclusive options");
Wang Chaod322a4b2010-08-05 14:30:11 +08001385 }
1386
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001387 if (!followfork)
1388 followfork = optF;
1389
Roland McGrathcb9def62006-04-25 07:48:03 +00001390 if (followfork > 1 && cflag) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001391 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
Roland McGrathcb9def62006-04-25 07:48:03 +00001392 }
1393
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001394 /* See if they want to run as another user. */
1395 if (username != NULL) {
1396 struct passwd *pent;
1397
1398 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001399 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001400 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001401 pent = getpwnam(username);
1402 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001403 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001404 }
1405 run_uid = pent->pw_uid;
1406 run_gid = pent->pw_gid;
1407 }
1408 else {
1409 run_uid = getuid();
1410 run_gid = getgid();
1411 }
1412
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001413 if (followfork)
1414 test_ptrace_setoptions_followfork();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001415 test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001416 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001417
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001418 /* Check if they want to redirect the output. */
1419 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001420 /* See if they want to pipe the output. */
1421 if (outfname[0] == '|' || outfname[0] == '!') {
1422 /*
1423 * We can't do the <outfname>.PID funny business
1424 * when using popen, so prohibit it.
1425 */
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001426 if (followfork > 1)
1427 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1428 outf = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001429 }
Denys Vlasenko3d5ed412011-06-22 13:17:16 +02001430 else if (followfork <= 1)
1431 outf = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001432 } else {
1433 /* -ff without -o FILE is the same as single -f */
1434 if (followfork > 1)
1435 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001436 }
1437
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001438 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001439 char *buf = malloc(BUFSIZ);
1440 if (!buf)
1441 die_out_of_memory();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001442 setvbuf(outf, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001443 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001444 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001445 if (!opt_intr)
1446 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001447 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001448 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001449 if (!opt_intr)
1450 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001451
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001452 /* argv[0] -pPID -oFILE Default interactive setting
1453 * yes 0 0 INTR_WHILE_WAIT
1454 * no 1 0 INTR_WHILE_WAIT
1455 * yes 0 1 INTR_NEVER
1456 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001457 */
1458
1459 /* STARTUP_CHILD must be called before the signal handlers get
1460 installed below as they are inherited into the spawned process.
1461 Also we do not need to be protected by them as during interruption
1462 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001463 if (argv[0]) {
1464 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001465 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001466 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001467
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001468 sigemptyset(&empty_set);
1469 sigemptyset(&blocked_set);
1470 sa.sa_handler = SIG_IGN;
1471 sigemptyset(&sa.sa_mask);
1472 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001473 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1474 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1475 if (opt_intr != INTR_ANYWHERE) {
1476 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1477 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1478 /*
1479 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1480 * fatal signals are blocked while syscall stop is processed,
1481 * and acted on in between, when waiting for new syscall stops.
1482 * In non-interactive mode, signals are ignored.
1483 */
1484 if (opt_intr == INTR_WHILE_WAIT) {
1485 sigaddset(&blocked_set, SIGHUP);
1486 sigaddset(&blocked_set, SIGINT);
1487 sigaddset(&blocked_set, SIGQUIT);
1488 sigaddset(&blocked_set, SIGPIPE);
1489 sigaddset(&blocked_set, SIGTERM);
1490 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001491 }
1492 /* SIG_IGN, or set handler for these */
1493 sigaction(SIGHUP, &sa, NULL);
1494 sigaction(SIGINT, &sa, NULL);
1495 sigaction(SIGQUIT, &sa, NULL);
1496 sigaction(SIGPIPE, &sa, NULL);
1497 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001498 }
Denys Vlasenkofd883382012-03-09 13:03:41 +01001499 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001500 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001501
Denys Vlasenkofd883382012-03-09 13:03:41 +01001502 /* Do we want pids printed in our -o OUTFILE?
1503 * -ff: no (every pid has its own file); or
1504 * -f: yes (there can be more pids in the future); or
1505 * -p PID1,PID2: yes (there are already more than one pid)
1506 */
1507 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001508}
1509
Denys Vlasenko2b60c352011-06-22 12:45:25 +02001510static void
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001511expand_tcbtab(void)
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001512{
1513 /* Allocate some more TCBs and expand the table.
1514 We don't want to relocate the TCBs because our
1515 callers have pointers and it would be a pain.
1516 So tcbtab is a table of pointers. Since we never
1517 free the TCBs, we allocate a single chunk of many. */
Denys Vlasenko18da2732011-06-22 12:41:57 +02001518 int i = tcbtabsize;
1519 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1520 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001521 if (!newtab || !newtcbs)
1522 die_out_of_memory();
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001523 tcbtabsize *= 2;
1524 tcbtab = newtab;
Denys Vlasenko18da2732011-06-22 12:41:57 +02001525 while (i < tcbtabsize)
1526 tcbtab[i++] = newtcbs++;
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001527}
1528
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001529struct tcb *
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001530alloc_tcb(int pid, int command_options_parsed)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001531{
1532 int i;
1533 struct tcb *tcp;
1534
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001535 if (nprocs == tcbtabsize)
1536 expand_tcbtab();
1537
Roland McGrathee9d4352002-12-18 04:16:10 +00001538 for (i = 0; i < tcbtabsize; i++) {
1539 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001540 if ((tcp->flags & TCB_INUSE) == 0) {
Denys Vlasenko18da2732011-06-22 12:41:57 +02001541 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001542 tcp->pid = pid;
Denys Vlasenko381dbc22011-09-05 13:59:39 +02001543 tcp->flags = TCB_INUSE;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001544 tcp->outf = outf; /* Initialise to current out file */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001545#if SUPPORTED_PERSONALITIES > 1
1546 tcp->currpers = current_personality;
1547#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001548 nprocs++;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001549 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001550 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001551 if (command_options_parsed)
1552 newoutf(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001553 return tcp;
1554 }
1555 }
Denys Vlasenko18da2732011-06-22 12:41:57 +02001556 error_msg_and_die("bug in alloc_tcb");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001557}
1558
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001559static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001560pid2tcb(int pid)
1561{
1562 int i;
1563
1564 if (pid <= 0)
1565 return NULL;
1566
1567 for (i = 0; i < tcbtabsize; i++) {
1568 struct tcb *tcp = tcbtab[i];
1569 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1570 return tcp;
1571 }
1572
1573 return NULL;
1574}
1575
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001576void
Denys Vlasenko12014262011-05-30 14:00:14 +02001577droptcb(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001578{
1579 if (tcp->pid == 0)
1580 return;
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001581
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001582 nprocs--;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001583 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001584 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
Wichert Akkermaneb8ebda2002-04-01 17:48:02 +00001585
Denys Vlasenko3e084ac2012-03-15 13:39:05 +01001586 if (tcp->outf) {
1587 if (outfname && followfork >= 2) {
1588 if (tcp->curcol != 0)
1589 fprintf(tcp->outf, " <detached ...>\n");
1590 fclose(tcp->outf);
1591 if (outf == tcp->outf)
1592 outf = NULL;
1593 } else {
1594 if (printing_tcp == tcp && tcp->curcol != 0)
1595 fprintf(tcp->outf, " <detached ...>\n");
1596 fflush(tcp->outf);
1597 }
1598 }
1599
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001600 if (printing_tcp == tcp)
1601 printing_tcp = NULL;
1602
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001603 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604}
1605
Roland McGrath0a463882007-07-05 18:43:16 +00001606/* detach traced process; continue with sig
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001607 * Never call DETACH twice on the same process as both unattached and
1608 * attached-unstopped processes give the same ESRCH. For unattached process we
1609 * would SIGSTOP it and wait for its SIGSTOP notification forever.
1610 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001611static int
Denys Vlasenko4c196382012-01-04 15:11:09 +01001612detach(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001613{
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001614 int error;
1615 int status, sigstop_expected;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001616
1617 if (tcp->flags & TCB_BPTSET)
Andreas Schwab840d85b2010-01-12 11:16:32 +01001618 clearbpt(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001619
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001620 /*
1621 * Linux wrongly insists the child be stopped
Roland McGrath7bf10472002-12-16 20:42:50 +00001622 * before detaching. Arghh. We go through hoops
1623 * to make a clean break of things.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001624 */
Roland McGrath7bf10472002-12-16 20:42:50 +00001625#if defined(SPARC)
1626#undef PTRACE_DETACH
1627#define PTRACE_DETACH PTRACE_SUNDETACH
1628#endif
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001629
Denys Vlasenko3e084ac2012-03-15 13:39:05 +01001630 error = 0;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001631 sigstop_expected = 0;
1632 if (tcp->flags & TCB_ATTACHED) {
1633 /*
1634 * We attached but possibly didn't see the expected SIGSTOP.
1635 * We must catch exactly one as otherwise the detached process
1636 * would be left stopped (process state T).
1637 */
1638 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1639 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1640 if (error == 0) {
1641 /* On a clear day, you can see forever. */
1642 }
1643 else if (errno != ESRCH) {
1644 /* Shouldn't happen. */
1645 perror("detach: ptrace(PTRACE_DETACH, ...)");
1646 }
1647 else if (my_tkill(tcp->pid, 0) < 0) {
1648 if (errno != ESRCH)
1649 perror("detach: checking sanity");
1650 }
1651 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
1652 if (errno != ESRCH)
1653 perror("detach: stopping child");
1654 }
1655 else
1656 sigstop_expected = 1;
Roland McGrath7bf10472002-12-16 20:42:50 +00001657 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001658
1659 if (sigstop_expected) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001660 for (;;) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001661#ifdef __WALL
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001662 if (waitpid(tcp->pid, &status, __WALL) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001663 if (errno == ECHILD) /* Already gone. */
1664 break;
1665 if (errno != EINVAL) {
Roland McGrath553a6092002-12-16 20:40:39 +00001666 perror("detach: waiting");
Roland McGrath7508cb42002-12-17 10:48:05 +00001667 break;
1668 }
1669#endif /* __WALL */
1670 /* No __WALL here. */
1671 if (waitpid(tcp->pid, &status, 0) < 0) {
1672 if (errno != ECHILD) {
1673 perror("detach: waiting");
1674 break;
1675 }
1676#ifdef __WCLONE
1677 /* If no processes, try clones. */
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001678 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001679 if (errno != ECHILD)
1680 perror("detach: waiting");
1681 break;
1682 }
1683#endif /* __WCLONE */
1684 }
1685#ifdef __WALL
Roland McGrath553a6092002-12-16 20:40:39 +00001686 }
Roland McGrath7508cb42002-12-17 10:48:05 +00001687#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001688 if (!WIFSTOPPED(status)) {
1689 /* Au revoir, mon ami. */
1690 break;
1691 }
1692 if (WSTOPSIG(status) == SIGSTOP) {
Denys Vlasenko4c196382012-01-04 15:11:09 +01001693 ptrace_restart(PTRACE_DETACH, tcp, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694 break;
1695 }
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001696 error = ptrace_restart(PTRACE_CONT, tcp,
Denys Vlasenko75422762011-05-27 14:36:01 +02001697 WSTOPSIG(status) == syscall_trap_sig ? 0
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001698 : WSTOPSIG(status));
1699 if (error < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001700 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001701 }
Denys Vlasenkoef2fbf82009-01-06 21:45:06 +00001702 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001703
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001704 if (!qflag && (tcp->flags & TCB_ATTACHED))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001705 fprintf(stderr, "Process %u detached\n", tcp->pid);
1706
1707 droptcb(tcp);
Roland McGratha08a97e2005-08-03 11:23:46 +00001708
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001709 return error;
1710}
1711
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001712static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001713cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001714{
1715 int i;
1716 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001717 int fatal_sig;
1718
1719 /* 'interrupted' is a volatile object, fetch it only once */
1720 fatal_sig = interrupted;
1721 if (!fatal_sig)
1722 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001723
Roland McGrathee9d4352002-12-18 04:16:10 +00001724 for (i = 0; i < tcbtabsize; i++) {
1725 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001726 if (!(tcp->flags & TCB_INUSE))
1727 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001728 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001729 fprintf(stderr,
1730 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001731 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001732 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001733 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001734 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001735 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001736 }
1737 if (cflag)
1738 call_summary(outf);
1739}
1740
1741static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001742interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001744 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001745}
1746
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001747static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001748trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001749{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001750 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001751 struct rusage *rup = cflag ? &ru : NULL;
1752# ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001753 static int wait4_options = __WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001754# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001755
Roland McGratheb9e2e82009-06-02 16:49:22 -07001756 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001757 int pid;
1758 int wait_errno;
1759 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001760 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001761 struct tcb *tcp;
1762 unsigned event;
1763
Denys Vlasenko222713a2009-03-17 14:29:59 +00001764 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001765 return 0;
1766 if (interactive)
1767 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001768# ifdef __WALL
1769 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001770 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001771 /* this kernel does not support __WALL */
1772 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001773 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001774 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001775 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001776 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001777 pid = wait4(-1, &status, __WCLONE, rup);
1778 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001779 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001780 }
1781 }
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001782# else
1783 pid = wait4(-1, &status, 0, rup);
1784# endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001785 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001786 if (interactive)
1787 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001789 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001790 switch (wait_errno) {
1791 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001792 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001793 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001794 /*
1795 * We would like to verify this case
1796 * but sometimes a race in Solbourne's
1797 * version of SunOS sometimes reports
1798 * ECHILD before sending us SIGCHILD.
1799 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001800 return 0;
1801 default:
1802 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001803 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001804 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001805 }
1806 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001807 if (pid == popen_pid) {
1808 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001809 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001810 continue;
1811 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001812
1813 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001814 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001815 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001816 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001817 strcpy(buf, "???");
1818 if (WIFSIGNALED(status))
1819#ifdef WCOREDUMP
1820 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1821 WCOREDUMP(status) ? "core," : "",
1822 signame(WTERMSIG(status)));
1823#else
1824 sprintf(buf, "WIFSIGNALED,sig=%s",
1825 signame(WTERMSIG(status)));
1826#endif
1827 if (WIFEXITED(status))
1828 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1829 if (WIFSTOPPED(status))
1830 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001831#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001832 if (WIFCONTINUED(status))
1833 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001834#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001835 evbuf[0] = '\0';
1836 if (event != 0) {
1837 static const char *const event_names[] = {
1838 [PTRACE_EVENT_CLONE] = "CLONE",
1839 [PTRACE_EVENT_FORK] = "FORK",
1840 [PTRACE_EVENT_VFORK] = "VFORK",
1841 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1842 [PTRACE_EVENT_EXEC] = "EXEC",
1843 [PTRACE_EVENT_EXIT] = "EXIT",
1844 };
1845 const char *e;
1846 if (event < ARRAY_SIZE(event_names))
1847 e = event_names[event];
1848 else {
1849 sprintf(buf, "?? (%u)", event);
1850 e = buf;
1851 }
1852 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1853 }
1854 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001855 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001856
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001857 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001858 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001859
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001860 /* Under Linux, execve changes pid to thread leader's pid,
1861 * and we see this changed pid on EVENT_EXEC and later,
1862 * execve sysexit. Leader "disappears" without exit
1863 * notification. Let user know that, drop leader's tcb,
1864 * and fix up pid in execve thread's tcb.
1865 * Effectively, execve thread's tcb replaces leader's tcb.
1866 *
1867 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1868 * on exit syscall) in multithreaded programs exactly
1869 * in order to handle this case.
1870 *
1871 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1872 * On 2.6 and earlier, it can return garbage.
1873 */
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001874 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001875 long old_pid = 0;
1876 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1877 && old_pid > 0
1878 && old_pid != pid
1879 ) {
1880 struct tcb *execve_thread = pid2tcb(old_pid);
1881 if (tcp) {
1882 outf = tcp->outf;
1883 curcol = tcp->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001884 if (execve_thread) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001885 if (execve_thread->curcol != 0) {
1886 /*
1887 * One case we are here is -ff:
1888 * try "strace -oLOG -ff test/threaded_execve"
1889 */
1890 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1891 execve_thread->curcol = 0;
1892 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001893 /* swap output FILEs (needed for -ff) */
1894 tcp->outf = execve_thread->outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001895 tcp->curcol = execve_thread->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001896 execve_thread->outf = outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001897 execve_thread->curcol = curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001898 }
1899 droptcb(tcp);
1900 }
1901 tcp = execve_thread;
1902 if (tcp) {
1903 tcp->pid = pid;
1904 tcp->flags |= TCB_REPRINT;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001905 if (!cflag) {
1906 printleader(tcp);
1907 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1908 line_ended();
1909 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001910 }
1911 }
1912 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001913
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001914 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1915 if (!skip_startup_execve)
1916 detach(tcp);
1917 /* This was initial execve for "strace PROG". Skip. */
1918 skip_startup_execve = 0;
1919 }
1920
Denys Vlasenko5d645812011-08-20 12:48:18 +02001921 if (tcp == NULL) {
Roland McGrath41c48222008-07-18 00:25:10 +00001922 if (followfork) {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001923 /* This is needed to go with the CLONE_PTRACE
1924 changes in process.c/util.c: we might see
1925 the child's initial trap before we see the
1926 parent return from the clone syscall.
1927 Leave the child suspended until the parent
1928 returns from its system call. Only then
1929 will we have the association of parent and
1930 child so that we know how to do clearbpt
1931 in the child. */
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001932 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001933 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001934 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001935 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001936 pid);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001937 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001938 else
1939 /* This can happen if a clone call used
1940 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001941 {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001942 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001943 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001944 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001945 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001946 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001947
1948 /* Set current output file */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001949 outf = tcp->outf;
Andreas Schwabccdff482009-10-27 16:27:13 +01001950 curcol = tcp->curcol;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001951
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001952 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001953 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1954 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001955 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07001956
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001957 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001958 if (pid == strace_child)
1959 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001960 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001961 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1962 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001963#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01001964 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00001965 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001966 WCOREDUMP(status) ? "(core dumped) " : "");
1967#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01001968 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001969 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00001970#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001971 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001972 }
1973 droptcb(tcp);
1974 continue;
1975 }
1976 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001977 if (pid == strace_child)
1978 exit_code = WEXITSTATUS(status);
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001979 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1980 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01001981 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001982 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001983 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001984 droptcb(tcp);
1985 continue;
1986 }
1987 if (!WIFSTOPPED(status)) {
1988 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1989 droptcb(tcp);
1990 continue;
1991 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001992
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001993 /* Is this the very first time we see this tracee stopped? */
1994 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001995 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001996 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001997 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001998 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00001999 /*
2000 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002001 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002002 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002003 if (clearbpt(tcp) < 0) {
2004 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002005 droptcb(tcp);
2006 cleanup();
2007 return -1;
2008 }
2009 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002010 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002011 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002012 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2013 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2014 if (errno != ESRCH) {
2015 /* Should never happen, really */
2016 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002017 }
2018 }
2019 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002020 }
2021
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002022 sig = WSTOPSIG(status);
2023
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002024 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002025 /* Ptrace event */
2026#ifdef USE_SEIZE
2027 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002028 /*
2029 * PTRACE_INTERRUPT-stop or group-stop.
2030 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2031 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002032 if (sig == SIGSTOP
2033 || sig == SIGTSTP
2034 || sig == SIGTTIN
2035 || sig == SIGTTOU
2036 ) {
2037 stopped = 1;
2038 goto show_stopsig;
2039 }
2040 }
2041#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002042 goto restart_tracee_with_sig_0;
2043 }
2044
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002045 /* Is this post-attach SIGSTOP?
2046 * Interestingly, the process may stop
2047 * with STOPSIG equal to some other signal
2048 * than SIGSTOP if we happend to attach
2049 * just before the process takes a signal.
2050 */
2051 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002052 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002053 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2054 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002055 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002056 }
2057
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002058 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002059 siginfo_t si;
2060
2061 /* Nonzero (true) if tracee is stopped by signal
2062 * (as opposed to "tracee received signal").
2063 */
2064 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002065#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002066 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002067#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002068 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002069 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002070#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002071 long pc = 0;
2072 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002073
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002074 upeek(tcp, PT_CR_IPSR, &psr);
2075 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002076
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002077# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002078 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002079# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002080# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002081#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002082# define PC_FORMAT_STR ""
2083# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002084#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002085 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002086 if (!stopped) {
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002087 tprintf("--- %s ", signame(sig));
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002088 printsiginfo(&si, verbose(tcp));
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002089 tprintf(PC_FORMAT_STR " ---\n"
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002090 PC_FORMAT_ARG);
2091 } else
Denys Vlasenko2c4fb902012-03-15 17:24:49 +01002092 tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002093 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002094 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002095 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002096 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002097
2098 if (!stopped)
2099 /* It's signal-delivery-stop. Inject the signal */
2100 goto restart_tracee;
2101
2102 /* It's group-stop */
2103#ifdef USE_SEIZE
2104 if (use_seize) {
2105 /*
2106 * This ends ptrace-stop, but does *not* end group-stop.
2107 * This makes stopping signals work properly on straced process
2108 * (that is, process really stops. It used to continue to run).
2109 */
2110 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2111 cleanup();
2112 return -1;
2113 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002114 tcp->curcol = curcol;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002115 continue;
2116 }
2117 /* We don't have PTRACE_LISTEN support... */
2118#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002119 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002120 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002121
2122 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002123 if (interrupted)
2124 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002125
2126 /* This should be syscall entry or exit.
2127 * (Or it still can be that pesky post-execve SIGTRAP!)
2128 * Handle it.
2129 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07002130 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2131 /* ptrace() failed in trace_syscall() with ESRCH.
2132 * Likely a result of process disappearing mid-flight.
2133 * Observed case: exit_group() terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002134 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002135 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002136 * We used to detach(tcp) here, but since we no longer
2137 * implement "detach before death" policy/hack,
2138 * we can let this process to report its death to us
2139 * normally, via WIFEXITED or WIFSIGNALED wait status.
2140 */
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002141 tcp->curcol = curcol;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002142 continue;
2143 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002144 restart_tracee_with_sig_0:
2145 sig = 0;
2146 restart_tracee:
Andreas Schwabccdff482009-10-27 16:27:13 +01002147 /* Remember current print column before continuing. */
2148 tcp->curcol = curcol;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002149 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002150 cleanup();
2151 return -1;
2152 }
2153 }
2154 return 0;
2155}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002156
2157int
2158main(int argc, char *argv[])
2159{
2160 init(argc, argv);
2161
2162 /* Run main tracing loop */
2163 if (trace() < 0)
2164 return 1;
2165
2166 cleanup();
2167 fflush(NULL);
2168 if (exit_code > 0xff) {
2169 /* Avoid potential core file clobbering. */
2170 struct rlimit rlim = {0, 0};
2171 setrlimit(RLIMIT_CORE, &rlim);
2172
2173 /* Child was killed by a signal, mimic that. */
2174 exit_code &= 0xff;
2175 signal(exit_code, SIG_DFL);
2176 raise(exit_code);
2177 /* Paranoia - what if this signal is not fatal?
2178 Exit with 128 + signo then. */
2179 exit_code += 128;
2180 }
2181
2182 return exit_code;
2183}