blob: 22962a64eca5ae6f620ebe40148fa187960d236d [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.
29 *
30 * $Id$
31 */
32
33#include "defs.h"
34
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020035#include <stdarg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000036#include <sys/param.h>
37#include <fcntl.h>
38#include <sys/resource.h>
39#include <sys/wait.h>
40#include <sys/stat.h>
41#include <pwd.h>
42#include <grp.h>
Roland McGrath70b08532004-04-09 00:25:21 +000043#include <dirent.h>
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +010044#include <sys/utsname.h>
Denys Vlasenko84703742012-02-25 02:38:52 +010045#if defined(IA64)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +000046# include <asm/ptrace_offsets.h>
47#endif
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010048/* In some libc, these aren't declared. Do it ourself: */
Denys Vlasenko96d5a762008-12-29 19:13:27 +000049extern char **environ;
Denys Vlasenko418d66a2009-01-17 01:52:54 +000050extern int optind;
51extern char *optarg;
Denys Vlasenko96d5a762008-12-29 19:13:27 +000052
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010053
54#if defined __NR_tkill
55# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
56#else
57 /* kill() may choose arbitrarily the target task of the process group
58 while we later wait on a that specific TID. PID process waits become
59 TID task specific waits for a process under ptrace(2). */
60# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
61# define my_tkill(tid, sig) kill((tid), (sig))
62#endif
63
64#undef KERNEL_VERSION
65#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
66
67cflag_t cflag = CFLAG_NONE;
68unsigned int followfork = 0;
Denys Vlasenkof44cce42011-06-21 14:34:10 +020069unsigned int ptrace_setoptions = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010070unsigned int xflag = 0;
71bool debug_flag = 0;
72bool Tflag = 0;
73bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020074/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020075static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010076static unsigned int tflag = 0;
77static bool iflag = 0;
78static bool rflag = 0;
79static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010080
81/* -I n */
82enum {
83 INTR_NOT_SET = 0,
84 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
85 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
86 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
87 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
88 NUM_INTR_OPTS
89};
90static int opt_intr;
91/* We play with signal mask only if this mode is active: */
92#define interactive (opt_intr == INTR_WHILE_WAIT)
93
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000094/*
95 * daemonized_tracer supports -D option.
96 * With this option, strace forks twice.
97 * Unlike normal case, with -D *grandparent* process exec's,
98 * becoming a traced process. Child exits (this prevents traced process
99 * from having children it doesn't expect to have), and grandchild
100 * attaches to grandparent similarly to strace -p PID.
101 * This allows for more transparent interaction in cases
102 * when process and its parent are communicating via signals,
103 * wait() etc. Without -D, strace process gets lodged in between,
104 * disrupting parent<->child link.
105 */
106static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000107
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100108#ifdef USE_SEIZE
109static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
110# define use_seize (post_attach_sigstop == 0)
111#else
112# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
113# define use_seize 0
114#endif
115
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000116/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100117bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000118
Grant Edwards8a082772011-04-07 20:25:40 +0000119/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100120bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000121
122/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100123bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000124
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100125static bool detach_on_execve = 0;
126static bool skip_startup_execve = 0;
127
Dmitry V. Levina6809652008-11-10 17:14:58 +0000128static int exit_code = 0;
129static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200130static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700131
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000132static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200133static uid_t run_uid;
134static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000135
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100136unsigned int max_strlen = DEFAULT_STRLEN;
137static unsigned int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200138static char *acolumn_spaces;
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000139static char *outfname = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200140static FILE *outf;
Denys Vlasenko000b6012012-01-28 01:25:03 +0100141struct tcb *printing_tcp = NULL;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100142static unsigned int curcol;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200143static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200144static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200145static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000146
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +0100147static unsigned os_release; /* generated from uname()'s u.release */
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100148
Denys Vlasenko4c196382012-01-04 15:11:09 +0100149static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100150static int trace(void);
151static void cleanup(void);
152static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000153static sigset_t empty_set, blocked_set;
154
155#ifdef HAVE_SIG_ATOMIC_T
156static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100157#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000158static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100159#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000160
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000161static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200162usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000163{
164 fprintf(ofp, "\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100165usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
166 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100167 [-P path] [PROG [ARGS]]\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100168 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100169 [PROG [ARGS]]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000170-c -- count time, calls, and errors for each syscall and report summary\n\
Andreas Schwabb87d30c2010-06-11 15:49:36 +0200171-C -- like -c but also print regular output while processes are running\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100172-d -- enable debug output to stderr\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100173-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000174-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenko3e084ac2012-03-15 13:39:05 +0100175-F -- attempt to follow vforks (deprecated, use -f)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000176-i -- print instruction pointer at time of syscall\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100177-I interruptible\n\
178 1: no signals are blocked\n\
179 2: fatal signals are blocked while decoding syscall (default)\n\
180 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
181 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
182 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000183-q -- suppress messages about attaching, detaching, etc.\n\
184-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100185-T -- print time spent in each syscall\n\
186-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000187-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000188-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100189-h -- print help message\n\
190-V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000191-a column -- alignment COLUMN for printing syscall results (default %d)\n\
192-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
193 options: trace, abbrev, verbose, raw, signal, read, or write\n\
194-o file -- send trace output to FILE instead of stderr\n\
195-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
196-p pid -- trace process with process id PID, may be repeated\n\
197-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
198-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
199-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000200-E var=val -- put var=val in the environment for command\n\
201-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000202-P path -- trace accesses to path\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100203"
204/* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000205-z -- print only succeeding syscalls\n\
Denys Vlasenko61e7aad2012-03-15 13:44:17 +0100206 */
207/* experimental, don't document it yet (option letter may change in the future!)
208-b -- detach on successful execve\n\
209 */
Roland McGrathde6e5332003-01-24 04:31:23 +0000210, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000211 exit(exitval);
212}
213
Denys Vlasenko75422762011-05-27 14:36:01 +0200214static void die(void) __attribute__ ((noreturn));
215static void die(void)
216{
217 if (strace_tracer_pid == getpid()) {
218 cflag = 0;
219 cleanup();
220 }
221 exit(1);
222}
223
224static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200225{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100226 char *msg;
227
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000228 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100229
230 /* We want to print entire message with single fprintf to ensure
231 * message integrity if stderr is shared with other programs.
232 * Thus we use vasprintf + single fprintf.
233 */
234 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100235 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100236 if (err_no)
237 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
238 else
239 fprintf(stderr, "%s: %s\n", progname, msg);
240 free(msg);
241 } else {
242 /* malloc in vasprintf failed, try it without malloc */
243 fprintf(stderr, "%s: ", progname);
244 vfprintf(stderr, fmt, p);
245 if (err_no)
246 fprintf(stderr, ": %s\n", strerror(err_no));
247 else
248 putc('\n', stderr);
249 }
250 /* We don't switch stderr to buffered, thus fprintf(stderr)
251 * always flushes its output and this is not necessary: */
252 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200253}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200254
Denys Vlasenko75422762011-05-27 14:36:01 +0200255void error_msg(const char *fmt, ...)
256{
257 va_list p;
258 va_start(p, fmt);
259 verror_msg(0, fmt, p);
260 va_end(p);
261}
262
263void error_msg_and_die(const char *fmt, ...)
264{
265 va_list p;
266 va_start(p, fmt);
267 verror_msg(0, fmt, p);
268 die();
269}
270
271void perror_msg(const char *fmt, ...)
272{
273 va_list p;
274 va_start(p, fmt);
275 verror_msg(errno, fmt, p);
276 va_end(p);
277}
278
279void perror_msg_and_die(const char *fmt, ...)
280{
281 va_list p;
282 va_start(p, fmt);
283 verror_msg(errno, fmt, p);
284 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200285}
286
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200287void die_out_of_memory(void)
288{
289 static bool recursed = 0;
290 if (recursed)
291 exit(1);
292 recursed = 1;
293 error_msg_and_die("Out of memory");
294}
295
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400296/* Glue for systems without a MMU that cannot provide fork() */
297#ifdef HAVE_FORK
298# define strace_vforked 0
299#else
300# define strace_vforked 1
301# define fork() vfork()
302#endif
303
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100304#ifdef USE_SEIZE
305static int
306ptrace_attach_or_seize(int pid)
307{
308 int r;
309 if (!use_seize)
310 return ptrace(PTRACE_ATTACH, pid, 0, 0);
311 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
312 if (r)
313 return r;
314 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
315 return r;
316}
317#else
318# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
319#endif
320
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200321static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000322set_cloexec_flag(int fd)
323{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200324 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000325
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200326 flags = fcntl(fd, F_GETFD);
327 if (flags < 0) {
328 /* Can happen only if fd is bad.
329 * Should never happen: if it does, we have a bug
330 * in the caller. Therefore we just abort
331 * instead of propagating the error.
332 */
333 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000334 }
335
336 newflags = flags | FD_CLOEXEC;
337 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200338 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000339
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200340 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000341}
342
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100343static void kill_save_errno(pid_t pid, int sig)
344{
345 int saved_errno = errno;
346
347 (void) kill(pid, sig);
348 errno = saved_errno;
349}
350
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100351void
352tprintf(const char *fmt, ...)
353{
354 va_list args;
355
356 va_start(args, fmt);
357 if (outf) {
358 int n = vfprintf(outf, fmt, args);
359 if (n < 0) {
360 if (outf != stderr)
361 perror(outfname == NULL
362 ? "<writing to pipe>" : outfname);
363 } else
364 curcol += n;
365 }
366 va_end(args);
367}
368
369void
370tprints(const char *str)
371{
372 if (outf) {
373 int n = fputs(str, outf);
374 if (n >= 0) {
375 curcol += strlen(str);
376 return;
377 }
378 if (outf != stderr)
379 perror(outfname == NULL
380 ? "<writing to pipe>" : outfname);
381 }
382}
383
384void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100385line_ended(void)
386{
387 curcol = 0;
388 fflush(outf);
389 if (!printing_tcp)
390 return;
391 printing_tcp->curcol = 0;
392 printing_tcp = NULL;
393}
394
395void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100396printleader(struct tcb *tcp)
397{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100398 /* If -ff, "previous tcb we printed" is always the same as current,
399 * because we have per-tcb output files.
400 */
401 if (followfork >= 2)
402 printing_tcp = tcp;
403
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100404 if (printing_tcp) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100405 outf = printing_tcp->outf;
406 curcol = printing_tcp->curcol;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100407 if (printing_tcp->ptrace_errno) {
408 if (printing_tcp->flags & TCB_INSYSCALL) {
409 tprints(" <unavailable>) ");
410 tabto();
411 }
412 tprints("= ? <unavailable>\n");
413 printing_tcp->ptrace_errno = 0;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100414 printing_tcp->curcol = 0;
415 }
416 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
417 /*
418 * case 1: we have a shared log (i.e. not -ff), and last line
419 * wasn't finished (same or different tcb, doesn't matter).
420 * case 2: split log, we are the same tcb, but our last line
421 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
422 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100423 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100424 printing_tcp->flags |= TCB_REPRINT;
425 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100426 }
427 }
428
429 printing_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100430 outf = tcp->outf;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100431 curcol = 0;
432
433 if (print_pid_pfx)
434 tprintf("%-5d ", tcp->pid);
435 else if (nprocs > 1 && !outfname)
436 tprintf("[pid %5u] ", tcp->pid);
437
438 if (tflag) {
439 char str[sizeof("HH:MM:SS")];
440 struct timeval tv, dtv;
441 static struct timeval otv;
442
443 gettimeofday(&tv, NULL);
444 if (rflag) {
445 if (otv.tv_sec == 0)
446 otv = tv;
447 tv_sub(&dtv, &tv, &otv);
448 tprintf("%6ld.%06ld ",
449 (long) dtv.tv_sec, (long) dtv.tv_usec);
450 otv = tv;
451 }
452 else if (tflag > 2) {
453 tprintf("%ld.%06ld ",
454 (long) tv.tv_sec, (long) tv.tv_usec);
455 }
456 else {
457 time_t local = tv.tv_sec;
458 strftime(str, sizeof(str), "%T", localtime(&local));
459 if (tflag > 1)
460 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
461 else
462 tprintf("%s ", str);
463 }
464 }
465 if (iflag)
466 printcall(tcp);
467}
468
469void
470tabto(void)
471{
472 if (curcol < acolumn)
473 tprints(acolumn_spaces + curcol);
474}
475
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000476/*
477 * When strace is setuid executable, we have to swap uids
478 * before and after filesystem and process management operations.
479 */
480static void
481swap_uid(void)
482{
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000483 int euid = geteuid(), uid = getuid();
484
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200485 if (euid != uid && setreuid(euid, uid) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200486 perror_msg_and_die("setreuid");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000487 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000488}
489
Roland McGrath4bfa6262007-07-05 20:03:16 +0000490#if _LFS64_LARGEFILE
491# define fopen_for_output fopen64
492#else
493# define fopen_for_output fopen
494#endif
495
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000496static FILE *
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200497strace_fopen(const char *path)
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000498{
499 FILE *fp;
500
501 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200502 fp = fopen_for_output(path, "w");
503 if (!fp)
504 perror_msg_and_die("Can't fopen '%s'", path);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000505 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200506 set_cloexec_flag(fileno(fp));
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000507 return fp;
508}
509
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200510static int popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000511
512#ifndef _PATH_BSHELL
513# define _PATH_BSHELL "/bin/sh"
514#endif
515
516/*
517 * We cannot use standard popen(3) here because we have to distinguish
518 * popen child process from other processes we trace, and standard popen(3)
519 * does not export its child's pid.
520 */
521static FILE *
522strace_popen(const char *command)
523{
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200524 FILE *fp;
525 int fds[2];
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000526
527 swap_uid();
528 if (pipe(fds) < 0)
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200529 perror_msg_and_die("pipe");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000530
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200531 set_cloexec_flag(fds[1]); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000532
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200533 popen_pid = vfork();
534 if (popen_pid == -1)
535 perror_msg_and_die("vfork");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000536
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200537 if (popen_pid == 0) {
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000538 /* child */
539 close(fds[1]);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200540 if (fds[0] != 0) {
541 if (dup2(fds[0], 0))
542 perror_msg_and_die("dup2");
543 close(fds[0]);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000544 }
545 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200546 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000547 }
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200548
549 /* parent */
550 close(fds[0]);
551 swap_uid();
552 fp = fdopen(fds[1], "w");
553 if (!fp)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200554 die_out_of_memory();
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200555 return fp;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000556}
557
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200558static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000559newoutf(struct tcb *tcp)
560{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100561 if (outfname && followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000562 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000563 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200564 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000565 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000566}
567
Denys Vlasenko558e5122012-03-12 23:32:16 +0100568static void
569process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100570{
571 while (*opt) {
572 /*
573 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
574 * pidof uses space as delim, pgrep uses newline. :(
575 */
576 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100577 char *delim = opt + strcspn(opt, ", \n\t");
578 char c = *delim;
579
580 *delim = '\0';
581 pid = atoi(opt); /* TODO: stricter parsing of the number? */
582 if (pid <= 0) {
583 error_msg("Invalid process id: '%s'", opt);
584 *delim = c;
585 return;
586 }
587 if (pid == strace_tracer_pid) {
588 error_msg("I'm sorry, I can't let you do that, Dave.");
589 *delim = c;
590 return;
591 }
592 *delim = c;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100593 alloc_tcb(pid, 0);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100594 if (c == '\0')
595 break;
596 opt = delim + 1;
597 }
598}
599
Roland McGrath02203312007-06-11 22:06:31 +0000600static void
601startup_attach(void)
602{
603 int tcbi;
604 struct tcb *tcp;
605
606 /*
607 * Block user interruptions as we would leave the traced
608 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200609 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200610 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000611 */
612 if (interactive)
613 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
614
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000615 if (daemonized_tracer) {
616 pid_t pid = fork();
617 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200618 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000619 }
620 if (pid) { /* parent */
621 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200622 * Wait for grandchild to attach to straced process
623 * (grandparent). Grandchild SIGKILLs us after it attached.
624 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000625 * it proceeds to exec the straced program.
626 */
627 pause();
628 _exit(0); /* paranoia */
629 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200630 /* grandchild */
631 /* We will be the tracer process. Remember our new pid: */
632 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000633 }
634
Roland McGrath02203312007-06-11 22:06:31 +0000635 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
636 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200637
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100638 if (!(tcp->flags & TCB_INUSE))
639 continue;
640
Denys Vlasenkod116a732011-09-05 14:01:33 +0200641 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100642 if (tcp->flags & TCB_ATTACHED)
643 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200644
645 /* Reinitialize the output since it may have changed */
Roland McGrath02203312007-06-11 22:06:31 +0000646 tcp->outf = outf;
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200647 newoutf(tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000648
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000649 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000650 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000651 DIR *dir;
652
653 sprintf(procdir, "/proc/%d/task", tcp->pid);
654 dir = opendir(procdir);
655 if (dir != NULL) {
656 unsigned int ntid = 0, nerr = 0;
657 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200658
Roland McGrath02203312007-06-11 22:06:31 +0000659 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200660 struct tcb *cur_tcp;
661 int tid;
662
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000663 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000664 continue;
665 tid = atoi(de->d_name);
666 if (tid <= 0)
667 continue;
668 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100669 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000670 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100671 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200672 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200673 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200674 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100675 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200676 fprintf(stderr, "attach to pid %d succeeded\n", tid);
677 cur_tcp = tcp;
678 if (tid != tcp->pid)
679 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100680 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrath02203312007-06-11 22:06:31 +0000681 }
682 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200683 if (interactive) {
684 sigprocmask(SIG_SETMASK, &empty_set, NULL);
685 if (interrupted)
686 goto ret;
687 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
688 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000689 ntid -= nerr;
690 if (ntid == 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000691 perror("attach: ptrace(PTRACE_ATTACH, ...)");
692 droptcb(tcp);
693 continue;
694 }
695 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000696 fprintf(stderr, ntid > 1
697? "Process %u attached with %u threads - interrupt to quit\n"
698: "Process %u attached - interrupt to quit\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200699 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000700 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100701 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200702 /* -p PID, we failed to attach to PID itself
703 * but did attach to some of its sibling threads.
704 * Drop PID's tcp.
705 */
706 droptcb(tcp);
707 }
Roland McGrath02203312007-06-11 22:06:31 +0000708 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000709 } /* if (opendir worked) */
710 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100711 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000712 perror("attach: ptrace(PTRACE_ATTACH, ...)");
713 droptcb(tcp);
714 continue;
715 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100716 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100717 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200718 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000719
720 if (daemonized_tracer) {
721 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000722 * Make parent go away.
723 * Also makes grandparent's wait() unblock.
724 */
725 kill(getppid(), SIGKILL);
726 }
727
Roland McGrath02203312007-06-11 22:06:31 +0000728 if (!qflag)
729 fprintf(stderr,
730 "Process %u attached - interrupt to quit\n",
731 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200732 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000733
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200734 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000735 if (interactive)
736 sigprocmask(SIG_SETMASK, &empty_set, NULL);
737}
738
739static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200740startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000741{
742 struct stat statbuf;
743 const char *filename;
744 char pathname[MAXPATHLEN];
745 int pid = 0;
746 struct tcb *tcp;
747
748 filename = argv[0];
749 if (strchr(filename, '/')) {
750 if (strlen(filename) > sizeof pathname - 1) {
751 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200752 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000753 }
754 strcpy(pathname, filename);
755 }
756#ifdef USE_DEBUGGING_EXEC
757 /*
758 * Debuggers customarily check the current directory
759 * first regardless of the path but doing that gives
760 * security geeks a panic attack.
761 */
762 else if (stat(filename, &statbuf) == 0)
763 strcpy(pathname, filename);
764#endif /* USE_DEBUGGING_EXEC */
765 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000766 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +0000767 int m, n, len;
768
769 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100770 const char *colon = strchr(path, ':');
771 if (colon) {
772 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +0000773 m = n + 1;
774 }
775 else
776 m = n = strlen(path);
777 if (n == 0) {
778 if (!getcwd(pathname, MAXPATHLEN))
779 continue;
780 len = strlen(pathname);
781 }
782 else if (n > sizeof pathname - 1)
783 continue;
784 else {
785 strncpy(pathname, path, n);
786 len = n;
787 }
788 if (len && pathname[len - 1] != '/')
789 pathname[len++] = '/';
790 strcpy(pathname + len, filename);
791 if (stat(pathname, &statbuf) == 0 &&
792 /* Accept only regular files
793 with some execute bits set.
794 XXX not perfect, might still fail */
795 S_ISREG(statbuf.st_mode) &&
796 (statbuf.st_mode & 0111))
797 break;
798 }
799 }
800 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200801 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +0000802 }
Dmitry V. Levina6809652008-11-10 17:14:58 +0000803 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000804 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200805 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000806 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200807 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
808 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000809 ) {
810 pid = getpid();
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200811 if (outf != stderr)
812 close(fileno(outf));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100813 if (!daemonized_tracer && !use_seize) {
814 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200815 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000816 }
Roland McGrath02203312007-06-11 22:06:31 +0000817 }
Roland McGrath02203312007-06-11 22:06:31 +0000818
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200819 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +0000820 uid_t run_euid = run_uid;
821 gid_t run_egid = run_gid;
822
823 if (statbuf.st_mode & S_ISUID)
824 run_euid = statbuf.st_uid;
825 if (statbuf.st_mode & S_ISGID)
826 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +0000827 /*
828 * It is important to set groups before we
829 * lose privileges on setuid.
830 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200831 if (initgroups(username, run_gid) < 0) {
832 perror_msg_and_die("initgroups");
833 }
834 if (setregid(run_gid, run_egid) < 0) {
835 perror_msg_and_die("setregid");
836 }
837 if (setreuid(run_uid, run_euid) < 0) {
838 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +0000839 }
840 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200841 else if (geteuid() != 0)
Roland McGrath02203312007-06-11 22:06:31 +0000842 setreuid(run_uid, run_uid);
843
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000844 if (!daemonized_tracer) {
845 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200846 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000847 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200848 * the immediately following execve syscall.
849 * Can't do this on NOMMU systems, we are after
850 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000851 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400852 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200853 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000854 } else {
855 struct sigaction sv_sigchld;
856 sigaction(SIGCHLD, NULL, &sv_sigchld);
857 /*
858 * Make sure it is not SIG_IGN, otherwise wait
859 * will not block.
860 */
861 signal(SIGCHLD, SIG_DFL);
862 /*
863 * Wait for grandchild to attach to us.
864 * It kills child after that, and wait() unblocks.
865 */
866 alarm(3);
867 wait(NULL);
868 alarm(0);
869 sigaction(SIGCHLD, &sv_sigchld, NULL);
870 }
Roland McGrath02203312007-06-11 22:06:31 +0000871
872 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200873 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000874 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000875
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200876 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +0200877
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200878 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100879 if (!use_seize) {
880 /* child did PTRACE_TRACEME, nothing to do in parent */
881 } else {
882 if (!strace_vforked) {
883 /* Wait until child stopped itself */
884 int status;
885 while (waitpid(pid, &status, WSTOPPED) < 0) {
886 if (errno == EINTR)
887 continue;
888 perror_msg_and_die("waitpid");
889 }
890 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100891 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100892 perror_msg_and_die("Unexpected wait status %x", status);
893 }
894 }
895 /* Else: vforked case, we have no way to sync.
896 * Just attach to it as soon as possible.
897 * This means that we may miss a few first syscalls...
898 */
899
900 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100901 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100902 perror_msg_and_die("Can't attach to %d", pid);
903 }
904 if (!strace_vforked)
905 kill(pid, SIGCONT);
906 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200907 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200908 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100909 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200910 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100911 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200912 }
913 else {
914 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
915 strace_tracer_pid = getpid();
916 /* The tracee is our parent: */
917 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +0100918 alloctcb(pid);
919 /* attaching will be done later, by startup_attach */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000920 }
Roland McGrath02203312007-06-11 22:06:31 +0000921}
922
Wang Chaob13c0de2010-11-12 17:25:19 +0800923/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000924 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +0800925 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000926 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +0800927 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000928static void
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200929test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +0800930{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000931 int pid, expected_grandchild = 0, found_grandchild = 0;
932 const unsigned int test_options = PTRACE_O_TRACECLONE |
933 PTRACE_O_TRACEFORK |
934 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +0800935
Denys Vlasenko5d645812011-08-20 12:48:18 +0200936 pid = fork();
937 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000938 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +0200939 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000940 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100941 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000942 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
943 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100944 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000945 if (fork() < 0)
946 perror_msg_and_die("fork");
947 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +0800948 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000949
950 while (1) {
951 int status, tracee_pid;
952
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000953 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000954 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000955 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000956 if (errno == EINTR)
957 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100958 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000959 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000960 kill_save_errno(pid, SIGKILL);
961 perror_msg_and_die("%s: unexpected wait result %d",
962 __func__, tracee_pid);
963 }
964 if (WIFEXITED(status)) {
965 if (WEXITSTATUS(status)) {
966 if (tracee_pid != pid)
967 kill_save_errno(pid, SIGKILL);
968 error_msg_and_die("%s: unexpected exit status %u",
969 __func__, WEXITSTATUS(status));
970 }
971 continue;
972 }
973 if (WIFSIGNALED(status)) {
974 if (tracee_pid != pid)
975 kill_save_errno(pid, SIGKILL);
976 error_msg_and_die("%s: unexpected signal %u",
977 __func__, WTERMSIG(status));
978 }
979 if (!WIFSTOPPED(status)) {
980 if (tracee_pid != pid)
981 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100982 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000983 error_msg_and_die("%s: unexpected wait status %x",
984 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000985 }
986 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000987 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000988 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
989 kill_save_errno(tracee_pid, SIGKILL);
990 kill_save_errno(pid, SIGKILL);
991 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +0800992 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000993 continue;
994 }
995 switch (WSTOPSIG(status)) {
996 case SIGSTOP:
997 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
998 && errno != EINVAL && errno != EIO)
999 perror_msg("PTRACE_SETOPTIONS");
1000 break;
1001 case SIGTRAP:
1002 if (status >> 16 == PTRACE_EVENT_FORK) {
1003 long msg = 0;
1004
1005 if (ptrace(PTRACE_GETEVENTMSG, pid,
1006 NULL, (long) &msg) == 0)
1007 expected_grandchild = msg;
1008 }
1009 break;
1010 }
1011 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1012 kill_save_errno(pid, SIGKILL);
1013 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001014 }
1015 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001016 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001017 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001018 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001019 fprintf(stderr, "ptrace_setoptions = %#x\n",
1020 ptrace_setoptions);
1021 return;
1022 }
1023 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1024 "giving up using this feature.");
Wang Chaob13c0de2010-11-12 17:25:19 +08001025}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001026
1027/*
1028 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1029 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1030 * and then see whether it will stop with (SIGTRAP | 0x80).
1031 *
1032 * Use of this option enables correct handling of user-generated SIGTRAPs,
1033 * and SIGTRAPs generated by special instructions such as int3 on x86:
1034 * _start: .globl _start
1035 * int3
1036 * movl $42, %ebx
1037 * movl $1, %eax
1038 * int $0x80
1039 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1040 */
1041static void
1042test_ptrace_setoptions_for_all(void)
1043{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001044 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1045 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001046 int pid;
1047 int it_worked = 0;
1048
1049 pid = fork();
1050 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001051 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001052
1053 if (pid == 0) {
1054 pid = getpid();
1055 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001056 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001057 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1058 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001059 kill(pid, SIGSTOP);
1060 _exit(0); /* parent should see entry into this syscall */
1061 }
1062
1063 while (1) {
1064 int status, tracee_pid;
1065
1066 errno = 0;
1067 tracee_pid = wait(&status);
1068 if (tracee_pid <= 0) {
1069 if (errno == EINTR)
1070 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001071 kill_save_errno(pid, SIGKILL);
1072 perror_msg_and_die("%s: unexpected wait result %d",
1073 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001074 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001075 if (WIFEXITED(status)) {
1076 if (WEXITSTATUS(status) == 0)
1077 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001078 error_msg_and_die("%s: unexpected exit status %u",
1079 __func__, WEXITSTATUS(status));
1080 }
1081 if (WIFSIGNALED(status)) {
1082 error_msg_and_die("%s: unexpected signal %u",
1083 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001084 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001085 if (!WIFSTOPPED(status)) {
1086 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001087 error_msg_and_die("%s: unexpected wait status %x",
1088 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001089 }
1090 if (WSTOPSIG(status) == SIGSTOP) {
1091 /*
1092 * We don't check "options aren't accepted" error.
1093 * If it happens, we'll never get (SIGTRAP | 0x80),
1094 * and thus will decide to not use the option.
1095 * IOW: the outcome of the test will be correct.
1096 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001097 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1098 && errno != EINVAL && errno != EIO)
1099 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001100 }
1101 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1102 it_worked = 1;
1103 }
1104 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001105 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001106 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001107 }
1108 }
1109
1110 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001111 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001112 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001113 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001114 fprintf(stderr, "ptrace_setoptions = %#x\n",
1115 ptrace_setoptions);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001116 return;
1117 }
1118
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001119 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1120 "giving up using this feature.");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001121}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001122
1123# ifdef USE_SEIZE
1124static void
1125test_ptrace_seize(void)
1126{
1127 int pid;
1128
1129 pid = fork();
1130 if (pid < 0)
1131 perror_msg_and_die("fork");
1132
1133 if (pid == 0) {
1134 pause();
1135 _exit(0);
1136 }
1137
1138 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1139 * attaching tracee continues to run unless a trap condition occurs.
1140 * PTRACE_SEIZE doesn't affect signal or group stop state.
1141 */
1142 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1143 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001144 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001145 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1146 }
1147
1148 kill(pid, SIGKILL);
1149
1150 while (1) {
1151 int status, tracee_pid;
1152
1153 errno = 0;
1154 tracee_pid = waitpid(pid, &status, 0);
1155 if (tracee_pid <= 0) {
1156 if (errno == EINTR)
1157 continue;
1158 perror_msg_and_die("%s: unexpected wait result %d",
1159 __func__, tracee_pid);
1160 }
1161 if (WIFSIGNALED(status)) {
1162 return;
1163 }
1164 error_msg_and_die("%s: unexpected wait status %x",
1165 __func__, status);
1166 }
1167}
1168# else /* !USE_SEIZE */
1169# define test_ptrace_seize() ((void)0)
1170# endif
1171
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001172static unsigned
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001173get_os_release(void)
1174{
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001175 unsigned rel;
1176 const char *p;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001177 struct utsname u;
1178 if (uname(&u) < 0)
1179 perror_msg_and_die("uname");
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001180 /* u.release has this form: "3.2.9[-some-garbage]" */
1181 rel = 0;
1182 p = u.release;
1183 for (;;) {
1184 if (!(*p >= '0' && *p <= '9'))
1185 error_msg_and_die("Bad OS release string: '%s'", u.release);
1186 /* Note: this open-codes KERNEL_VERSION(): */
1187 rel = (rel << 8) | atoi(p);
1188 if (rel >= KERNEL_VERSION(1,0,0))
1189 break;
1190 while (*p >= '0' && *p <= '9')
1191 p++;
1192 if (*p != '.')
1193 error_msg_and_die("Bad OS release string: '%s'", u.release);
1194 p++;
1195 }
1196 return rel;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001197}
1198
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001199/*
1200 * Initialization part of main() was eating much stack (~0.5k),
1201 * which was unused after init.
1202 * We can reuse it if we move init code into a separate function.
1203 *
1204 * Don't want main() to inline us and defeat the reason
1205 * we have a separate function.
1206 */
1207static void __attribute__ ((noinline))
1208init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001209{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001210 struct tcb *tcp;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001211 int c;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001212 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001213 struct sigaction sa;
1214
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001215 progname = argv[0] ? argv[0] : "strace";
1216
Denys Vlasenko75422762011-05-27 14:36:01 +02001217 strace_tracer_pid = getpid();
1218
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001219 os_release = get_os_release();
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001220
Roland McGrathee9d4352002-12-18 04:16:10 +00001221 /* Allocate the initial tcbtab. */
1222 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001223 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001224 if (!tcbtab)
1225 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001226 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001227 if (!tcp)
1228 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001229 for (c = 0; c < tcbtabsize; c++)
1230 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001231
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001232 outf = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001233 set_sortby(DEFAULT_SORTBY);
1234 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001235 qualify("trace=all");
1236 qualify("abbrev=all");
1237 qualify("verbose=all");
1238 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001239 while ((c = getopt(argc, argv,
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001240 "+bcCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001241 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001242 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001243 switch (c) {
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001244 case 'b':
1245 detach_on_execve = 1;
1246 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001247 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001248 if (cflag == CFLAG_BOTH) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001249 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001250 }
1251 cflag = CFLAG_ONLY_STATS;
1252 break;
1253 case 'C':
1254 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001255 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001256 }
1257 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001258 break;
1259 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001260 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001261 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001262 case 'D':
1263 daemonized_tracer = 1;
1264 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001265 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001266 optF = 1;
1267 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001268 case 'f':
1269 followfork++;
1270 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001271 case 'h':
1272 usage(stdout, 0);
1273 break;
1274 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001275 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001276 break;
1277 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001278 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001279 break;
1280 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001281 rflag = 1;
1282 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001283 case 't':
1284 tflag++;
1285 break;
1286 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001287 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001288 break;
1289 case 'x':
1290 xflag++;
1291 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001292 case 'y':
1293 show_fd_path = 1;
1294 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001295 case 'v':
1296 qualify("abbrev=none");
1297 break;
1298 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001299 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001300 exit(0);
1301 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001302 case 'z':
1303 not_failing_only = 1;
1304 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001305 case 'a':
1306 acolumn = atoi(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001307 if (acolumn < 0)
1308 error_msg_and_die("Bad column width '%s'", optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001309 break;
1310 case 'e':
1311 qualify(optarg);
1312 break;
1313 case 'o':
1314 outfname = strdup(optarg);
1315 break;
1316 case 'O':
1317 set_overhead(atoi(optarg));
1318 break;
1319 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001320 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001321 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001322 case 'P':
1323 tracing_paths = 1;
1324 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001325 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001326 }
1327 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001328 case 's':
1329 max_strlen = atoi(optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001330 if (max_strlen < 0) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001331 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001332 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001333 break;
1334 case 'S':
1335 set_sortby(optarg);
1336 break;
1337 case 'u':
1338 username = strdup(optarg);
1339 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001340 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001341 if (putenv(optarg) < 0)
1342 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001343 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001344 case 'I':
1345 opt_intr = atoi(optarg);
1346 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1347 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1348 }
1349 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001350 default:
1351 usage(stderr, 1);
1352 break;
1353 }
1354 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001355 argv += optind;
1356 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001357
Denys Vlasenko102ec492011-08-25 01:27:59 +02001358 acolumn_spaces = malloc(acolumn + 1);
1359 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001360 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001361 memset(acolumn_spaces, ' ', acolumn);
1362 acolumn_spaces[acolumn] = '\0';
1363
Denys Vlasenko837399a2012-01-24 11:37:03 +01001364 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001365 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001366 usage(stderr, 1);
1367
Denys Vlasenkofd883382012-03-09 13:03:41 +01001368 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001369 error_msg_and_die("-D and -p are mutually exclusive options");
Wang Chaod322a4b2010-08-05 14:30:11 +08001370 }
1371
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001372 if (!followfork)
1373 followfork = optF;
1374
Roland McGrathcb9def62006-04-25 07:48:03 +00001375 if (followfork > 1 && cflag) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001376 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
Roland McGrathcb9def62006-04-25 07:48:03 +00001377 }
1378
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001379 /* See if they want to run as another user. */
1380 if (username != NULL) {
1381 struct passwd *pent;
1382
1383 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001384 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001385 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001386 pent = getpwnam(username);
1387 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001388 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001389 }
1390 run_uid = pent->pw_uid;
1391 run_gid = pent->pw_gid;
1392 }
1393 else {
1394 run_uid = getuid();
1395 run_gid = getgid();
1396 }
1397
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001398 if (followfork)
1399 test_ptrace_setoptions_followfork();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001400 test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001401 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001402
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001403 /* Check if they want to redirect the output. */
1404 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001405 /* See if they want to pipe the output. */
1406 if (outfname[0] == '|' || outfname[0] == '!') {
1407 /*
1408 * We can't do the <outfname>.PID funny business
1409 * when using popen, so prohibit it.
1410 */
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001411 if (followfork > 1)
1412 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1413 outf = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001414 }
Denys Vlasenko3d5ed412011-06-22 13:17:16 +02001415 else if (followfork <= 1)
1416 outf = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001417 } else {
1418 /* -ff without -o FILE is the same as single -f */
1419 if (followfork > 1)
1420 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001421 }
1422
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001423 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001424 char *buf = malloc(BUFSIZ);
1425 if (!buf)
1426 die_out_of_memory();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001427 setvbuf(outf, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001428 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001429 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001430 if (!opt_intr)
1431 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001432 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001433 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001434 if (!opt_intr)
1435 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001436
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001437 /* argv[0] -pPID -oFILE Default interactive setting
1438 * yes 0 0 INTR_WHILE_WAIT
1439 * no 1 0 INTR_WHILE_WAIT
1440 * yes 0 1 INTR_NEVER
1441 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001442 */
1443
1444 /* STARTUP_CHILD must be called before the signal handlers get
1445 installed below as they are inherited into the spawned process.
1446 Also we do not need to be protected by them as during interruption
1447 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001448 if (argv[0]) {
1449 skip_startup_execve = 1;
Denys Vlasenko837399a2012-01-24 11:37:03 +01001450 startup_child(argv);
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001451 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001452
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001453 sigemptyset(&empty_set);
1454 sigemptyset(&blocked_set);
1455 sa.sa_handler = SIG_IGN;
1456 sigemptyset(&sa.sa_mask);
1457 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001458 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1459 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1460 if (opt_intr != INTR_ANYWHERE) {
1461 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1462 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1463 /*
1464 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1465 * fatal signals are blocked while syscall stop is processed,
1466 * and acted on in between, when waiting for new syscall stops.
1467 * In non-interactive mode, signals are ignored.
1468 */
1469 if (opt_intr == INTR_WHILE_WAIT) {
1470 sigaddset(&blocked_set, SIGHUP);
1471 sigaddset(&blocked_set, SIGINT);
1472 sigaddset(&blocked_set, SIGQUIT);
1473 sigaddset(&blocked_set, SIGPIPE);
1474 sigaddset(&blocked_set, SIGTERM);
1475 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001476 }
1477 /* SIG_IGN, or set handler for these */
1478 sigaction(SIGHUP, &sa, NULL);
1479 sigaction(SIGINT, &sa, NULL);
1480 sigaction(SIGQUIT, &sa, NULL);
1481 sigaction(SIGPIPE, &sa, NULL);
1482 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001483 }
Roland McGrath553a6092002-12-16 20:40:39 +00001484 /* Make sure SIGCHLD has the default action so that waitpid
1485 definitely works without losing track of children. The user
1486 should not have given us a bogus state to inherit, but he might
1487 have. Arguably we should detect SIG_IGN here and pass it on
1488 to children, but probably noone really needs that. */
1489 sa.sa_handler = SIG_DFL;
1490 sigaction(SIGCHLD, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001491
Denys Vlasenkofd883382012-03-09 13:03:41 +01001492 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001493 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001494
Denys Vlasenkofd883382012-03-09 13:03:41 +01001495 /* Do we want pids printed in our -o OUTFILE?
1496 * -ff: no (every pid has its own file); or
1497 * -f: yes (there can be more pids in the future); or
1498 * -p PID1,PID2: yes (there are already more than one pid)
1499 */
1500 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001501}
1502
Denys Vlasenko2b60c352011-06-22 12:45:25 +02001503static void
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001504expand_tcbtab(void)
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001505{
1506 /* Allocate some more TCBs and expand the table.
1507 We don't want to relocate the TCBs because our
1508 callers have pointers and it would be a pain.
1509 So tcbtab is a table of pointers. Since we never
1510 free the TCBs, we allocate a single chunk of many. */
Denys Vlasenko18da2732011-06-22 12:41:57 +02001511 int i = tcbtabsize;
1512 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1513 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001514 if (!newtab || !newtcbs)
1515 die_out_of_memory();
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001516 tcbtabsize *= 2;
1517 tcbtab = newtab;
Denys Vlasenko18da2732011-06-22 12:41:57 +02001518 while (i < tcbtabsize)
1519 tcbtab[i++] = newtcbs++;
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001520}
1521
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001522struct tcb *
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001523alloc_tcb(int pid, int command_options_parsed)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001524{
1525 int i;
1526 struct tcb *tcp;
1527
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001528 if (nprocs == tcbtabsize)
1529 expand_tcbtab();
1530
Roland McGrathee9d4352002-12-18 04:16:10 +00001531 for (i = 0; i < tcbtabsize; i++) {
1532 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001533 if ((tcp->flags & TCB_INUSE) == 0) {
Denys Vlasenko18da2732011-06-22 12:41:57 +02001534 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001535 tcp->pid = pid;
Denys Vlasenko381dbc22011-09-05 13:59:39 +02001536 tcp->flags = TCB_INUSE;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001537 tcp->outf = outf; /* Initialise to current out file */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001538#if SUPPORTED_PERSONALITIES > 1
1539 tcp->currpers = current_personality;
1540#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001541 nprocs++;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001542 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001543 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001544 if (command_options_parsed)
1545 newoutf(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001546 return tcp;
1547 }
1548 }
Denys Vlasenko18da2732011-06-22 12:41:57 +02001549 error_msg_and_die("bug in alloc_tcb");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001550}
1551
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001552static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001553pid2tcb(int pid)
1554{
1555 int i;
1556
1557 if (pid <= 0)
1558 return NULL;
1559
1560 for (i = 0; i < tcbtabsize; i++) {
1561 struct tcb *tcp = tcbtab[i];
1562 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1563 return tcp;
1564 }
1565
1566 return NULL;
1567}
1568
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001569void
Denys Vlasenko12014262011-05-30 14:00:14 +02001570droptcb(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001571{
1572 if (tcp->pid == 0)
1573 return;
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001574
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001575 nprocs--;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001576 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001577 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
Wichert Akkermaneb8ebda2002-04-01 17:48:02 +00001578
Denys Vlasenko3e084ac2012-03-15 13:39:05 +01001579 if (tcp->outf) {
1580 if (outfname && followfork >= 2) {
1581 if (tcp->curcol != 0)
1582 fprintf(tcp->outf, " <detached ...>\n");
1583 fclose(tcp->outf);
1584 if (outf == tcp->outf)
1585 outf = NULL;
1586 } else {
1587 if (printing_tcp == tcp && tcp->curcol != 0)
1588 fprintf(tcp->outf, " <detached ...>\n");
1589 fflush(tcp->outf);
1590 }
1591 }
1592
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001593 if (printing_tcp == tcp)
1594 printing_tcp = NULL;
1595
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001596 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001597}
1598
Roland McGrath0a463882007-07-05 18:43:16 +00001599/* detach traced process; continue with sig
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001600 * Never call DETACH twice on the same process as both unattached and
1601 * attached-unstopped processes give the same ESRCH. For unattached process we
1602 * would SIGSTOP it and wait for its SIGSTOP notification forever.
1603 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604static int
Denys Vlasenko4c196382012-01-04 15:11:09 +01001605detach(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001606{
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001607 int error;
1608 int status, sigstop_expected;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001609
1610 if (tcp->flags & TCB_BPTSET)
Andreas Schwab840d85b2010-01-12 11:16:32 +01001611 clearbpt(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001612
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001613 /*
1614 * Linux wrongly insists the child be stopped
Roland McGrath7bf10472002-12-16 20:42:50 +00001615 * before detaching. Arghh. We go through hoops
1616 * to make a clean break of things.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001617 */
Roland McGrath7bf10472002-12-16 20:42:50 +00001618#if defined(SPARC)
1619#undef PTRACE_DETACH
1620#define PTRACE_DETACH PTRACE_SUNDETACH
1621#endif
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001622
Denys Vlasenko3e084ac2012-03-15 13:39:05 +01001623 error = 0;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001624 sigstop_expected = 0;
1625 if (tcp->flags & TCB_ATTACHED) {
1626 /*
1627 * We attached but possibly didn't see the expected SIGSTOP.
1628 * We must catch exactly one as otherwise the detached process
1629 * would be left stopped (process state T).
1630 */
1631 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1632 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1633 if (error == 0) {
1634 /* On a clear day, you can see forever. */
1635 }
1636 else if (errno != ESRCH) {
1637 /* Shouldn't happen. */
1638 perror("detach: ptrace(PTRACE_DETACH, ...)");
1639 }
1640 else if (my_tkill(tcp->pid, 0) < 0) {
1641 if (errno != ESRCH)
1642 perror("detach: checking sanity");
1643 }
1644 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
1645 if (errno != ESRCH)
1646 perror("detach: stopping child");
1647 }
1648 else
1649 sigstop_expected = 1;
Roland McGrath7bf10472002-12-16 20:42:50 +00001650 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001651
1652 if (sigstop_expected) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001653 for (;;) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001654#ifdef __WALL
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001655 if (waitpid(tcp->pid, &status, __WALL) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001656 if (errno == ECHILD) /* Already gone. */
1657 break;
1658 if (errno != EINVAL) {
Roland McGrath553a6092002-12-16 20:40:39 +00001659 perror("detach: waiting");
Roland McGrath7508cb42002-12-17 10:48:05 +00001660 break;
1661 }
1662#endif /* __WALL */
1663 /* No __WALL here. */
1664 if (waitpid(tcp->pid, &status, 0) < 0) {
1665 if (errno != ECHILD) {
1666 perror("detach: waiting");
1667 break;
1668 }
1669#ifdef __WCLONE
1670 /* If no processes, try clones. */
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001671 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001672 if (errno != ECHILD)
1673 perror("detach: waiting");
1674 break;
1675 }
1676#endif /* __WCLONE */
1677 }
1678#ifdef __WALL
Roland McGrath553a6092002-12-16 20:40:39 +00001679 }
Roland McGrath7508cb42002-12-17 10:48:05 +00001680#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001681 if (!WIFSTOPPED(status)) {
1682 /* Au revoir, mon ami. */
1683 break;
1684 }
1685 if (WSTOPSIG(status) == SIGSTOP) {
Denys Vlasenko4c196382012-01-04 15:11:09 +01001686 ptrace_restart(PTRACE_DETACH, tcp, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001687 break;
1688 }
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001689 error = ptrace_restart(PTRACE_CONT, tcp,
Denys Vlasenko75422762011-05-27 14:36:01 +02001690 WSTOPSIG(status) == syscall_trap_sig ? 0
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001691 : WSTOPSIG(status));
1692 if (error < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001693 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694 }
Denys Vlasenkoef2fbf82009-01-06 21:45:06 +00001695 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001696
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001697 if (!qflag && (tcp->flags & TCB_ATTACHED))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001698 fprintf(stderr, "Process %u detached\n", tcp->pid);
1699
1700 droptcb(tcp);
Roland McGratha08a97e2005-08-03 11:23:46 +00001701
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001702 return error;
1703}
1704
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001705static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001706cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001707{
1708 int i;
1709 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001710 int fatal_sig;
1711
1712 /* 'interrupted' is a volatile object, fetch it only once */
1713 fatal_sig = interrupted;
1714 if (!fatal_sig)
1715 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001716
Roland McGrathee9d4352002-12-18 04:16:10 +00001717 for (i = 0; i < tcbtabsize; i++) {
1718 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001719 if (!(tcp->flags & TCB_INUSE))
1720 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001721 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001722 fprintf(stderr,
1723 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001724 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001725 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001726 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001727 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001728 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001729 }
1730 if (cflag)
1731 call_summary(outf);
1732}
1733
1734static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001735interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001736{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001737 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001738}
1739
1740#ifndef HAVE_STRERROR
1741
Roland McGrath6d2b3492002-12-30 00:51:30 +00001742#if !HAVE_DECL_SYS_ERRLIST
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743extern int sys_nerr;
1744extern char *sys_errlist[];
Roland McGrath6d2b3492002-12-30 00:51:30 +00001745#endif /* HAVE_DECL_SYS_ERRLIST */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001746
1747const char *
Denys Vlasenko12014262011-05-30 14:00:14 +02001748strerror(int err_no)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001749{
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001750 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001751
Denys Vlasenko35aba6a2011-05-25 15:33:26 +02001752 if (err_no < 1 || err_no >= sys_nerr) {
1753 sprintf(buf, "Unknown error %d", err_no);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001754 return buf;
1755 }
Denys Vlasenko35aba6a2011-05-25 15:33:26 +02001756 return sys_errlist[err_no];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001757}
1758
1759#endif /* HAVE_STERRROR */
1760
1761#ifndef HAVE_STRSIGNAL
1762
Roland McGrath8f474e02003-01-14 07:53:33 +00001763#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
Roland McGrath6d2b3492002-12-30 00:51:30 +00001764extern char *sys_siglist[];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765#endif
Roland McGrath8f474e02003-01-14 07:53:33 +00001766#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1767extern char *_sys_siglist[];
1768#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001769
1770const char *
Denys Vlasenko12014262011-05-30 14:00:14 +02001771strsignal(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001772{
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001773 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001774
1775 if (sig < 1 || sig >= NSIG) {
1776 sprintf(buf, "Unknown signal %d", sig);
1777 return buf;
1778 }
1779#ifdef HAVE__SYS_SIGLIST
1780 return _sys_siglist[sig];
1781#else
1782 return sys_siglist[sig];
1783#endif
1784}
1785
1786#endif /* HAVE_STRSIGNAL */
1787
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001788static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001789trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001790{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001791 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001792 struct rusage *rup = cflag ? &ru : NULL;
1793# ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001794 static int wait4_options = __WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001795# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001796
Roland McGratheb9e2e82009-06-02 16:49:22 -07001797 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001798 int pid;
1799 int wait_errno;
1800 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001801 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001802 struct tcb *tcp;
1803 unsigned event;
1804
Denys Vlasenko222713a2009-03-17 14:29:59 +00001805 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001806 return 0;
1807 if (interactive)
1808 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001809# ifdef __WALL
1810 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001811 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001812 /* this kernel does not support __WALL */
1813 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001814 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001815 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001816 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001817 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001818 pid = wait4(-1, &status, __WCLONE, rup);
1819 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001820 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001821 }
1822 }
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001823# else
1824 pid = wait4(-1, &status, 0, rup);
1825# endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001826 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001827 if (interactive)
1828 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001829
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001830 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001831 switch (wait_errno) {
1832 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001833 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001834 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001835 /*
1836 * We would like to verify this case
1837 * but sometimes a race in Solbourne's
1838 * version of SunOS sometimes reports
1839 * ECHILD before sending us SIGCHILD.
1840 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001841 return 0;
1842 default:
1843 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001844 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001845 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001846 }
1847 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001848 if (pid == popen_pid) {
1849 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001850 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001851 continue;
1852 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001853
1854 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001855 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001856 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001857 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001858 strcpy(buf, "???");
1859 if (WIFSIGNALED(status))
1860#ifdef WCOREDUMP
1861 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1862 WCOREDUMP(status) ? "core," : "",
1863 signame(WTERMSIG(status)));
1864#else
1865 sprintf(buf, "WIFSIGNALED,sig=%s",
1866 signame(WTERMSIG(status)));
1867#endif
1868 if (WIFEXITED(status))
1869 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1870 if (WIFSTOPPED(status))
1871 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001872#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001873 if (WIFCONTINUED(status))
1874 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001875#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001876 evbuf[0] = '\0';
1877 if (event != 0) {
1878 static const char *const event_names[] = {
1879 [PTRACE_EVENT_CLONE] = "CLONE",
1880 [PTRACE_EVENT_FORK] = "FORK",
1881 [PTRACE_EVENT_VFORK] = "VFORK",
1882 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1883 [PTRACE_EVENT_EXEC] = "EXEC",
1884 [PTRACE_EVENT_EXIT] = "EXIT",
1885 };
1886 const char *e;
1887 if (event < ARRAY_SIZE(event_names))
1888 e = event_names[event];
1889 else {
1890 sprintf(buf, "?? (%u)", event);
1891 e = buf;
1892 }
1893 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1894 }
1895 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001896 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001897
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001898 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001899 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001900
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001901 /* Under Linux, execve changes pid to thread leader's pid,
1902 * and we see this changed pid on EVENT_EXEC and later,
1903 * execve sysexit. Leader "disappears" without exit
1904 * notification. Let user know that, drop leader's tcb,
1905 * and fix up pid in execve thread's tcb.
1906 * Effectively, execve thread's tcb replaces leader's tcb.
1907 *
1908 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1909 * on exit syscall) in multithreaded programs exactly
1910 * in order to handle this case.
1911 *
1912 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1913 * On 2.6 and earlier, it can return garbage.
1914 */
Denys Vlasenko6e0bfd12012-03-15 14:36:28 +01001915 if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001916 long old_pid = 0;
1917 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1918 && old_pid > 0
1919 && old_pid != pid
1920 ) {
1921 struct tcb *execve_thread = pid2tcb(old_pid);
1922 if (tcp) {
1923 outf = tcp->outf;
1924 curcol = tcp->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001925 if (execve_thread) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001926 if (execve_thread->curcol != 0) {
1927 /*
1928 * One case we are here is -ff:
1929 * try "strace -oLOG -ff test/threaded_execve"
1930 */
1931 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1932 execve_thread->curcol = 0;
1933 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001934 /* swap output FILEs (needed for -ff) */
1935 tcp->outf = execve_thread->outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001936 tcp->curcol = execve_thread->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001937 execve_thread->outf = outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001938 execve_thread->curcol = curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001939 }
1940 droptcb(tcp);
1941 }
1942 tcp = execve_thread;
1943 if (tcp) {
1944 tcp->pid = pid;
1945 tcp->flags |= TCB_REPRINT;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001946 if (!cflag) {
1947 printleader(tcp);
1948 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1949 line_ended();
1950 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001951 }
1952 }
1953 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001954
Denys Vlasenko61e7aad2012-03-15 13:44:17 +01001955 if (event == PTRACE_EVENT_EXEC && detach_on_execve) {
1956 if (!skip_startup_execve)
1957 detach(tcp);
1958 /* This was initial execve for "strace PROG". Skip. */
1959 skip_startup_execve = 0;
1960 }
1961
Denys Vlasenko5d645812011-08-20 12:48:18 +02001962 if (tcp == NULL) {
Roland McGrath41c48222008-07-18 00:25:10 +00001963 if (followfork) {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001964 /* This is needed to go with the CLONE_PTRACE
1965 changes in process.c/util.c: we might see
1966 the child's initial trap before we see the
1967 parent return from the clone syscall.
1968 Leave the child suspended until the parent
1969 returns from its system call. Only then
1970 will we have the association of parent and
1971 child so that we know how to do clearbpt
1972 in the child. */
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001973 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001974 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001975 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001976 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001977 pid);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001978 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001979 else
1980 /* This can happen if a clone call used
1981 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001982 {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001983 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001984 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001985 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001986 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001987 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001988
1989 /* Set current output file */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001990 outf = tcp->outf;
Andreas Schwabccdff482009-10-27 16:27:13 +01001991 curcol = tcp->curcol;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001992
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001993 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001994 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1995 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001996 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07001997
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001998 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001999 if (pid == strace_child)
2000 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002001 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002002 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
2003 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002004#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01002005 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00002006 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002007 WCOREDUMP(status) ? "(core dumped) " : "");
2008#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002009 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02002010 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00002011#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002012 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002013 }
2014 droptcb(tcp);
2015 continue;
2016 }
2017 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00002018 if (pid == strace_child)
2019 exit_code = WEXITSTATUS(status);
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002020 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
2021 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01002022 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002023 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02002024 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002025 droptcb(tcp);
2026 continue;
2027 }
2028 if (!WIFSTOPPED(status)) {
2029 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
2030 droptcb(tcp);
2031 continue;
2032 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002033
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002034 /* Is this the very first time we see this tracee stopped? */
2035 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002036 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002037 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002038 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002039 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002040 /*
2041 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002042 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002043 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002044 if (clearbpt(tcp) < 0) {
2045 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002046 droptcb(tcp);
2047 cleanup();
2048 return -1;
2049 }
2050 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002051 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002052 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002053 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2054 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2055 if (errno != ESRCH) {
2056 /* Should never happen, really */
2057 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002058 }
2059 }
2060 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002061 }
2062
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002063 sig = WSTOPSIG(status);
2064
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002065 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002066 /* Ptrace event */
2067#ifdef USE_SEIZE
2068 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002069 /*
2070 * PTRACE_INTERRUPT-stop or group-stop.
2071 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2072 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002073 if (sig == SIGSTOP
2074 || sig == SIGTSTP
2075 || sig == SIGTTIN
2076 || sig == SIGTTOU
2077 ) {
2078 stopped = 1;
2079 goto show_stopsig;
2080 }
2081 }
2082#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002083 goto restart_tracee_with_sig_0;
2084 }
2085
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002086 /* Is this post-attach SIGSTOP?
2087 * Interestingly, the process may stop
2088 * with STOPSIG equal to some other signal
2089 * than SIGSTOP if we happend to attach
2090 * just before the process takes a signal.
2091 */
2092 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002093 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002094 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2095 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002096 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002097 }
2098
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002099 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002100 siginfo_t si;
2101
2102 /* Nonzero (true) if tracee is stopped by signal
2103 * (as opposed to "tracee received signal").
2104 */
2105 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002106#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002107 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002108#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002109 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002110 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002111#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002112 long pc = 0;
2113 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002114
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002115 upeek(tcp, PT_CR_IPSR, &psr);
2116 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002117
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002118# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002119 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002120# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002121# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002122#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002123# define PC_FORMAT_STR ""
2124# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002125#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002126 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002127 if (!stopped) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002128 tprints("--- ");
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002129 printsiginfo(&si, verbose(tcp));
Denys Vlasenko000b6012012-01-28 01:25:03 +01002130 tprintf(" (%s)" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002131 strsignal(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002132 PC_FORMAT_ARG);
2133 } else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002134 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002135 strsignal(sig),
2136 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002137 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002138 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002139 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002140
2141 if (!stopped)
2142 /* It's signal-delivery-stop. Inject the signal */
2143 goto restart_tracee;
2144
2145 /* It's group-stop */
2146#ifdef USE_SEIZE
2147 if (use_seize) {
2148 /*
2149 * This ends ptrace-stop, but does *not* end group-stop.
2150 * This makes stopping signals work properly on straced process
2151 * (that is, process really stops. It used to continue to run).
2152 */
2153 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2154 cleanup();
2155 return -1;
2156 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002157 tcp->curcol = curcol;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002158 continue;
2159 }
2160 /* We don't have PTRACE_LISTEN support... */
2161#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002162 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002163 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002164
2165 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002166 if (interrupted)
2167 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002168
2169 /* This should be syscall entry or exit.
2170 * (Or it still can be that pesky post-execve SIGTRAP!)
2171 * Handle it.
2172 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07002173 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2174 /* ptrace() failed in trace_syscall() with ESRCH.
2175 * Likely a result of process disappearing mid-flight.
2176 * Observed case: exit_group() terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002177 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002178 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002179 * We used to detach(tcp) here, but since we no longer
2180 * implement "detach before death" policy/hack,
2181 * we can let this process to report its death to us
2182 * normally, via WIFEXITED or WIFSIGNALED wait status.
2183 */
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002184 tcp->curcol = curcol;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002185 continue;
2186 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002187 restart_tracee_with_sig_0:
2188 sig = 0;
2189 restart_tracee:
Andreas Schwabccdff482009-10-27 16:27:13 +01002190 /* Remember current print column before continuing. */
2191 tcp->curcol = curcol;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002192 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002193 cleanup();
2194 return -1;
2195 }
2196 }
2197 return 0;
2198}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002199
2200int
2201main(int argc, char *argv[])
2202{
2203 init(argc, argv);
2204
2205 /* Run main tracing loop */
2206 if (trace() < 0)
2207 return 1;
2208
2209 cleanup();
2210 fflush(NULL);
2211 if (exit_code > 0xff) {
2212 /* Avoid potential core file clobbering. */
2213 struct rlimit rlim = {0, 0};
2214 setrlimit(RLIMIT_CORE, &rlim);
2215
2216 /* Child was killed by a signal, mimic that. */
2217 exit_code &= 0xff;
2218 signal(exit_code, SIG_DFL);
2219 raise(exit_code);
2220 /* Paranoia - what if this signal is not fatal?
2221 Exit with 128 + signo then. */
2222 exit_code += 128;
2223 }
2224
2225 return exit_code;
2226}