blob: f05cf30048481b135807fd2bd3e87f5ca9126f01 [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
Roland McGrath795edb12005-02-02 04:44:57 +000035#include <sys/types.h>
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020036#include <stdarg.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037#include <signal.h>
38#include <errno.h>
39#include <sys/param.h>
40#include <fcntl.h>
41#include <sys/resource.h>
42#include <sys/wait.h>
43#include <sys/stat.h>
44#include <pwd.h>
45#include <grp.h>
46#include <string.h>
Roland McGrath70b08532004-04-09 00:25:21 +000047#include <dirent.h>
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +010048#include <sys/utsname.h>
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010049#include <asm/unistd.h>
Denys Vlasenko84703742012-02-25 02:38:52 +010050#if defined(IA64)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +000051# include <asm/ptrace_offsets.h>
52#endif
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010053/* In some libc, these aren't declared. Do it ourself: */
Denys Vlasenko96d5a762008-12-29 19:13:27 +000054extern char **environ;
Denys Vlasenko418d66a2009-01-17 01:52:54 +000055extern int optind;
56extern char *optarg;
Denys Vlasenko96d5a762008-12-29 19:13:27 +000057
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010058
59#if defined __NR_tkill
60# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
61#else
62 /* kill() may choose arbitrarily the target task of the process group
63 while we later wait on a that specific TID. PID process waits become
64 TID task specific waits for a process under ptrace(2). */
65# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!"
66# define my_tkill(tid, sig) kill((tid), (sig))
67#endif
68
69#undef KERNEL_VERSION
70#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
71
72cflag_t cflag = CFLAG_NONE;
73unsigned int followfork = 0;
Denys Vlasenkof44cce42011-06-21 14:34:10 +020074unsigned int ptrace_setoptions = 0;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010075unsigned int xflag = 0;
76bool debug_flag = 0;
77bool Tflag = 0;
78bool qflag = 0;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +020079/* Which WSTOPSIG(status) value marks syscall traps? */
Denys Vlasenko75422762011-05-27 14:36:01 +020080static unsigned int syscall_trap_sig = SIGTRAP;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010081static unsigned int tflag = 0;
82static bool iflag = 0;
83static bool rflag = 0;
84static bool print_pid_pfx = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +010085
86/* -I n */
87enum {
88 INTR_NOT_SET = 0,
89 INTR_ANYWHERE = 1, /* don't block/ignore any signals */
90 INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */
91 INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */
92 INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
93 NUM_INTR_OPTS
94};
95static int opt_intr;
96/* We play with signal mask only if this mode is active: */
97#define interactive (opt_intr == INTR_WHILE_WAIT)
98
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +000099/*
100 * daemonized_tracer supports -D option.
101 * With this option, strace forks twice.
102 * Unlike normal case, with -D *grandparent* process exec's,
103 * becoming a traced process. Child exits (this prevents traced process
104 * from having children it doesn't expect to have), and grandchild
105 * attaches to grandparent similarly to strace -p PID.
106 * This allows for more transparent interaction in cases
107 * when process and its parent are communicating via signals,
108 * wait() etc. Without -D, strace process gets lodged in between,
109 * disrupting parent<->child link.
110 */
111static bool daemonized_tracer = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000112
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100113#ifdef USE_SEIZE
114static int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
115# define use_seize (post_attach_sigstop == 0)
116#else
117# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
118# define use_seize 0
119#endif
120
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000121/* Sometimes we want to print only succeeding syscalls. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100122bool not_failing_only = 0;
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000123
Grant Edwards8a082772011-04-07 20:25:40 +0000124/* Show path associated with fd arguments */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100125bool show_fd_path = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000126
127/* are we filtering traces based on paths? */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100128bool tracing_paths = 0;
Grant Edwards8a082772011-04-07 20:25:40 +0000129
Dmitry V. Levina6809652008-11-10 17:14:58 +0000130static int exit_code = 0;
131static int strace_child = 0;
Denys Vlasenko75422762011-05-27 14:36:01 +0200132static int strace_tracer_pid = 0;
Roland McGratheb9e2e82009-06-02 16:49:22 -0700133
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000134static char *username = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200135static uid_t run_uid;
136static gid_t run_gid;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000137
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100138unsigned int max_strlen = DEFAULT_STRLEN;
139static unsigned int acolumn = DEFAULT_ACOLUMN;
Denys Vlasenko102ec492011-08-25 01:27:59 +0200140static char *acolumn_spaces;
Dmitry V. Levinb9fe0112006-12-13 16:59:44 +0000141static char *outfname = NULL;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200142static FILE *outf;
Denys Vlasenko000b6012012-01-28 01:25:03 +0100143struct tcb *printing_tcp = NULL;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100144static unsigned int curcol;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200145static struct tcb **tcbtab;
Denys Vlasenko2b60c352011-06-22 12:45:25 +0200146static unsigned int nprocs, tcbtabsize;
Denys Vlasenkoead73bd2011-06-24 22:49:58 +0200147static const char *progname;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000148
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +0100149static char *os_release; /* from uname() */
150
Denys Vlasenko4c196382012-01-04 15:11:09 +0100151static int detach(struct tcb *tcp);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100152static int trace(void);
153static void cleanup(void);
154static void interrupt(int sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000155static sigset_t empty_set, blocked_set;
156
157#ifdef HAVE_SIG_ATOMIC_T
158static volatile sig_atomic_t interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100159#else
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000160static volatile int interrupted;
Denys Vlasenkoa3559252012-01-29 16:43:51 +0100161#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000162
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000163static void
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200164usage(FILE *ofp, int exitval)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000165{
166 fprintf(ofp, "\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100167usage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\
168 [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100169 [-P path] [PROG [ARGS]]\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100170 or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100171 [PROG [ARGS]]\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000172-c -- count time, calls, and errors for each syscall and report summary\n\
Andreas Schwabb87d30c2010-06-11 15:49:36 +0200173-C -- like -c but also print regular output while processes are running\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100174-D -- run tracer process as a detached grandchild, not as parent\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000175-f -- follow forks, -ff -- with output into separate files\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100176-F -- attempt to follow vforks\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000177-i -- print instruction pointer at time of syscall\n\
Denys Vlasenkob51581e2012-01-29 16:53:03 +0100178-I interruptible\n\
179 1: no signals are blocked\n\
180 2: fatal signals are blocked while decoding syscall (default)\n\
181 3: fatal signals are always blocked (default if '-o FILE PROG')\n\
182 4: fatal signals and SIGTSTP (^Z) are always blocked\n\
183 (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000184-q -- suppress messages about attaching, detaching, etc.\n\
185-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100186-T -- print time spent in each syscall\n\
187-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000188-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000189-y -- print paths associated with file descriptor arguments\n\
Denys Vlasenkocdab1be2012-02-03 12:17:57 +0100190-h -- print help message\n\
191-V -- print version\n\
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000192-a column -- alignment COLUMN for printing syscall results (default %d)\n\
193-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
194 options: trace, abbrev, verbose, raw, signal, read, or write\n\
195-o file -- send trace output to FILE instead of stderr\n\
196-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
197-p pid -- trace process with process id PID, may be repeated\n\
198-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
199-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
200-u username -- run command as username handling setuid and/or setgid\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000201-E var=val -- put var=val in the environment for command\n\
202-E var -- remove var from the environment for command\n\
Grant Edwards8a082772011-04-07 20:25:40 +0000203-P path -- trace accesses to path\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000204" /* this is broken, so don't document it
Michal Ludvig17f8fb32002-11-06 13:17:21 +0000205-z -- print only succeeding syscalls\n\
Roland McGrathde6e5332003-01-24 04:31:23 +0000206 */
207, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000208 exit(exitval);
209}
210
Denys Vlasenko75422762011-05-27 14:36:01 +0200211static void die(void) __attribute__ ((noreturn));
212static void die(void)
213{
214 if (strace_tracer_pid == getpid()) {
215 cflag = 0;
216 cleanup();
217 }
218 exit(1);
219}
220
221static void verror_msg(int err_no, const char *fmt, va_list p)
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200222{
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100223 char *msg;
224
Dmitry V. Levin44d05322011-06-09 15:50:41 +0000225 fflush(NULL);
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100226
227 /* We want to print entire message with single fprintf to ensure
228 * message integrity if stderr is shared with other programs.
229 * Thus we use vasprintf + single fprintf.
230 */
231 msg = NULL;
Denys Vlasenkocfad5432012-01-24 12:48:02 +0100232 if (vasprintf(&msg, fmt, p) >= 0) {
Denys Vlasenko82bb78c2012-01-24 10:17:18 +0100233 if (err_no)
234 fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
235 else
236 fprintf(stderr, "%s: %s\n", progname, msg);
237 free(msg);
238 } else {
239 /* malloc in vasprintf failed, try it without malloc */
240 fprintf(stderr, "%s: ", progname);
241 vfprintf(stderr, fmt, p);
242 if (err_no)
243 fprintf(stderr, ": %s\n", strerror(err_no));
244 else
245 putc('\n', stderr);
246 }
247 /* We don't switch stderr to buffered, thus fprintf(stderr)
248 * always flushes its output and this is not necessary: */
249 /* fflush(stderr); */
Denys Vlasenko75422762011-05-27 14:36:01 +0200250}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200251
Denys Vlasenko75422762011-05-27 14:36:01 +0200252void error_msg(const char *fmt, ...)
253{
254 va_list p;
255 va_start(p, fmt);
256 verror_msg(0, fmt, p);
257 va_end(p);
258}
259
260void error_msg_and_die(const char *fmt, ...)
261{
262 va_list p;
263 va_start(p, fmt);
264 verror_msg(0, fmt, p);
265 die();
266}
267
268void perror_msg(const char *fmt, ...)
269{
270 va_list p;
271 va_start(p, fmt);
272 verror_msg(errno, fmt, p);
273 va_end(p);
274}
275
276void perror_msg_and_die(const char *fmt, ...)
277{
278 va_list p;
279 va_start(p, fmt);
280 verror_msg(errno, fmt, p);
281 die();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200282}
283
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200284void die_out_of_memory(void)
285{
286 static bool recursed = 0;
287 if (recursed)
288 exit(1);
289 recursed = 1;
290 error_msg_and_die("Out of memory");
291}
292
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400293/* Glue for systems without a MMU that cannot provide fork() */
294#ifdef HAVE_FORK
295# define strace_vforked 0
296#else
297# define strace_vforked 1
298# define fork() vfork()
299#endif
300
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100301#ifdef USE_SEIZE
302static int
303ptrace_attach_or_seize(int pid)
304{
305 int r;
306 if (!use_seize)
307 return ptrace(PTRACE_ATTACH, pid, 0, 0);
308 r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL);
309 if (r)
310 return r;
311 r = ptrace(PTRACE_INTERRUPT, pid, 0, 0);
312 return r;
313}
314#else
315# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
316#endif
317
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200318static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000319set_cloexec_flag(int fd)
320{
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200321 int flags, newflags;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000322
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200323 flags = fcntl(fd, F_GETFD);
324 if (flags < 0) {
325 /* Can happen only if fd is bad.
326 * Should never happen: if it does, we have a bug
327 * in the caller. Therefore we just abort
328 * instead of propagating the error.
329 */
330 perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000331 }
332
333 newflags = flags | FD_CLOEXEC;
334 if (flags == newflags)
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200335 return;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000336
Denys Vlasenko1f532ab2011-06-22 13:11:23 +0200337 fcntl(fd, F_SETFD, newflags); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000338}
339
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100340static void kill_save_errno(pid_t pid, int sig)
341{
342 int saved_errno = errno;
343
344 (void) kill(pid, sig);
345 errno = saved_errno;
346}
347
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100348void
349tprintf(const char *fmt, ...)
350{
351 va_list args;
352
353 va_start(args, fmt);
354 if (outf) {
355 int n = vfprintf(outf, fmt, args);
356 if (n < 0) {
357 if (outf != stderr)
358 perror(outfname == NULL
359 ? "<writing to pipe>" : outfname);
360 } else
361 curcol += n;
362 }
363 va_end(args);
364}
365
366void
367tprints(const char *str)
368{
369 if (outf) {
370 int n = fputs(str, outf);
371 if (n >= 0) {
372 curcol += strlen(str);
373 return;
374 }
375 if (outf != stderr)
376 perror(outfname == NULL
377 ? "<writing to pipe>" : outfname);
378 }
379}
380
381void
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100382line_ended(void)
383{
384 curcol = 0;
385 fflush(outf);
386 if (!printing_tcp)
387 return;
388 printing_tcp->curcol = 0;
389 printing_tcp = NULL;
390}
391
392void
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100393printleader(struct tcb *tcp)
394{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100395 /* If -ff, "previous tcb we printed" is always the same as current,
396 * because we have per-tcb output files.
397 */
398 if (followfork >= 2)
399 printing_tcp = tcp;
400
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100401 if (printing_tcp) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100402 outf = printing_tcp->outf;
403 curcol = printing_tcp->curcol;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100404 if (printing_tcp->ptrace_errno) {
405 if (printing_tcp->flags & TCB_INSYSCALL) {
406 tprints(" <unavailable>) ");
407 tabto();
408 }
409 tprints("= ? <unavailable>\n");
410 printing_tcp->ptrace_errno = 0;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100411 printing_tcp->curcol = 0;
412 }
413 if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
414 /*
415 * case 1: we have a shared log (i.e. not -ff), and last line
416 * wasn't finished (same or different tcb, doesn't matter).
417 * case 2: split log, we are the same tcb, but our last line
418 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
419 */
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100420 tprints(" <unfinished ...>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100421 printing_tcp->flags |= TCB_REPRINT;
422 printing_tcp->curcol = 0;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100423 }
424 }
425
426 printing_tcp = tcp;
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100427 outf = tcp->outf;
Denys Vlasenko2e856a12012-03-12 23:02:26 +0100428 curcol = 0;
429
430 if (print_pid_pfx)
431 tprintf("%-5d ", tcp->pid);
432 else if (nprocs > 1 && !outfname)
433 tprintf("[pid %5u] ", tcp->pid);
434
435 if (tflag) {
436 char str[sizeof("HH:MM:SS")];
437 struct timeval tv, dtv;
438 static struct timeval otv;
439
440 gettimeofday(&tv, NULL);
441 if (rflag) {
442 if (otv.tv_sec == 0)
443 otv = tv;
444 tv_sub(&dtv, &tv, &otv);
445 tprintf("%6ld.%06ld ",
446 (long) dtv.tv_sec, (long) dtv.tv_usec);
447 otv = tv;
448 }
449 else if (tflag > 2) {
450 tprintf("%ld.%06ld ",
451 (long) tv.tv_sec, (long) tv.tv_usec);
452 }
453 else {
454 time_t local = tv.tv_sec;
455 strftime(str, sizeof(str), "%T", localtime(&local));
456 if (tflag > 1)
457 tprintf("%s.%06ld ", str, (long) tv.tv_usec);
458 else
459 tprintf("%s ", str);
460 }
461 }
462 if (iflag)
463 printcall(tcp);
464}
465
466void
467tabto(void)
468{
469 if (curcol < acolumn)
470 tprints(acolumn_spaces + curcol);
471}
472
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000473/*
474 * When strace is setuid executable, we have to swap uids
475 * before and after filesystem and process management operations.
476 */
477static void
478swap_uid(void)
479{
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000480 int euid = geteuid(), uid = getuid();
481
Denys Vlasenko7b609d52011-06-22 14:32:43 +0200482 if (euid != uid && setreuid(euid, uid) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200483 perror_msg_and_die("setreuid");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000484 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000485}
486
Roland McGrath4bfa6262007-07-05 20:03:16 +0000487#if _LFS64_LARGEFILE
488# define fopen_for_output fopen64
489#else
490# define fopen_for_output fopen
491#endif
492
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000493static FILE *
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200494strace_fopen(const char *path)
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000495{
496 FILE *fp;
497
498 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200499 fp = fopen_for_output(path, "w");
500 if (!fp)
501 perror_msg_and_die("Can't fopen '%s'", path);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000502 swap_uid();
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200503 set_cloexec_flag(fileno(fp));
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000504 return fp;
505}
506
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200507static int popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000508
509#ifndef _PATH_BSHELL
510# define _PATH_BSHELL "/bin/sh"
511#endif
512
513/*
514 * We cannot use standard popen(3) here because we have to distinguish
515 * popen child process from other processes we trace, and standard popen(3)
516 * does not export its child's pid.
517 */
518static FILE *
519strace_popen(const char *command)
520{
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200521 FILE *fp;
522 int fds[2];
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000523
524 swap_uid();
525 if (pipe(fds) < 0)
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200526 perror_msg_and_die("pipe");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000527
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200528 set_cloexec_flag(fds[1]); /* never fails */
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000529
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200530 popen_pid = vfork();
531 if (popen_pid == -1)
532 perror_msg_and_die("vfork");
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000533
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200534 if (popen_pid == 0) {
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000535 /* child */
536 close(fds[1]);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200537 if (fds[0] != 0) {
538 if (dup2(fds[0], 0))
539 perror_msg_and_die("dup2");
540 close(fds[0]);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000541 }
542 execl(_PATH_BSHELL, "sh", "-c", command, NULL);
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200543 perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000544 }
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200545
546 /* parent */
547 close(fds[0]);
548 swap_uid();
549 fp = fdopen(fds[1], "w");
550 if (!fp)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200551 die_out_of_memory();
Denys Vlasenko7dd23382011-06-22 13:03:56 +0200552 return fp;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000553}
554
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200555static void
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000556newoutf(struct tcb *tcp)
557{
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100558 if (outfname && followfork >= 2) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000559 char name[520 + sizeof(int) * 3];
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000560 sprintf(name, "%.512s.%u", outfname, tcp->pid);
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200561 tcp->outf = strace_fopen(name);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000562 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +0000563}
564
Denys Vlasenko558e5122012-03-12 23:32:16 +0100565static void
566process_opt_p_list(char *opt)
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100567{
568 while (*opt) {
569 /*
570 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
571 * pidof uses space as delim, pgrep uses newline. :(
572 */
573 int pid;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100574 char *delim = opt + strcspn(opt, ", \n\t");
575 char c = *delim;
576
577 *delim = '\0';
578 pid = atoi(opt); /* TODO: stricter parsing of the number? */
579 if (pid <= 0) {
580 error_msg("Invalid process id: '%s'", opt);
581 *delim = c;
582 return;
583 }
584 if (pid == strace_tracer_pid) {
585 error_msg("I'm sorry, I can't let you do that, Dave.");
586 *delim = c;
587 return;
588 }
589 *delim = c;
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100590 alloc_tcb(pid, 0);
Denys Vlasenkoe8172b72012-03-09 13:01:04 +0100591 if (c == '\0')
592 break;
593 opt = delim + 1;
594 }
595}
596
Roland McGrath02203312007-06-11 22:06:31 +0000597static void
598startup_attach(void)
599{
600 int tcbi;
601 struct tcb *tcp;
602
603 /*
604 * Block user interruptions as we would leave the traced
605 * process stopped (process state T) if we would terminate in
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200606 * between PTRACE_ATTACH and wait4() on SIGSTOP.
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200607 * We rely on cleanup() from this point on.
Roland McGrath02203312007-06-11 22:06:31 +0000608 */
609 if (interactive)
610 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
611
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000612 if (daemonized_tracer) {
613 pid_t pid = fork();
614 if (pid < 0) {
Denys Vlasenko014ca3a2011-09-02 16:19:30 +0200615 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000616 }
617 if (pid) { /* parent */
618 /*
Denys Vlasenko75422762011-05-27 14:36:01 +0200619 * Wait for grandchild to attach to straced process
620 * (grandparent). Grandchild SIGKILLs us after it attached.
621 * Grandparent's wait() is unblocked by our death,
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000622 * it proceeds to exec the straced program.
623 */
624 pause();
625 _exit(0); /* paranoia */
626 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200627 /* grandchild */
628 /* We will be the tracer process. Remember our new pid: */
629 strace_tracer_pid = getpid();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000630 }
631
Roland McGrath02203312007-06-11 22:06:31 +0000632 for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
633 tcp = tcbtab[tcbi];
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200634
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100635 if (!(tcp->flags & TCB_INUSE))
636 continue;
637
Denys Vlasenkod116a732011-09-05 14:01:33 +0200638 /* Is this a process we should attach to, but not yet attached? */
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100639 if (tcp->flags & TCB_ATTACHED)
640 continue; /* no, we already attached it */
Denys Vlasenkod116a732011-09-05 14:01:33 +0200641
642 /* Reinitialize the output since it may have changed */
Roland McGrath02203312007-06-11 22:06:31 +0000643 tcp->outf = outf;
Denys Vlasenko3d5ed412011-06-22 13:17:16 +0200644 newoutf(tcp);
Roland McGrath02203312007-06-11 22:06:31 +0000645
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000646 if (followfork && !daemonized_tracer) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000647 char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
Roland McGrath02203312007-06-11 22:06:31 +0000648 DIR *dir;
649
650 sprintf(procdir, "/proc/%d/task", tcp->pid);
651 dir = opendir(procdir);
652 if (dir != NULL) {
653 unsigned int ntid = 0, nerr = 0;
654 struct dirent *de;
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200655
Roland McGrath02203312007-06-11 22:06:31 +0000656 while ((de = readdir(dir)) != NULL) {
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200657 struct tcb *cur_tcp;
658 int tid;
659
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000660 if (de->d_fileno == 0)
Roland McGrath02203312007-06-11 22:06:31 +0000661 continue;
662 tid = atoi(de->d_name);
663 if (tid <= 0)
664 continue;
665 ++ntid;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100666 if (ptrace_attach_or_seize(tid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000667 ++nerr;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100668 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200669 fprintf(stderr, "attach to pid %d failed\n", tid);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200670 continue;
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200671 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100672 if (debug_flag)
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200673 fprintf(stderr, "attach to pid %d succeeded\n", tid);
674 cur_tcp = tcp;
675 if (tid != tcp->pid)
676 cur_tcp = alloctcb(tid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100677 cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrath02203312007-06-11 22:06:31 +0000678 }
679 closedir(dir);
Denys Vlasenko381dbc22011-09-05 13:59:39 +0200680 if (interactive) {
681 sigprocmask(SIG_SETMASK, &empty_set, NULL);
682 if (interrupted)
683 goto ret;
684 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
685 }
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000686 ntid -= nerr;
687 if (ntid == 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000688 perror("attach: ptrace(PTRACE_ATTACH, ...)");
689 droptcb(tcp);
690 continue;
691 }
692 if (!qflag) {
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000693 fprintf(stderr, ntid > 1
694? "Process %u attached with %u threads - interrupt to quit\n"
695: "Process %u attached - interrupt to quit\n",
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200696 tcp->pid, ntid);
Roland McGrath02203312007-06-11 22:06:31 +0000697 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100698 if (!(tcp->flags & TCB_ATTACHED)) {
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200699 /* -p PID, we failed to attach to PID itself
700 * but did attach to some of its sibling threads.
701 * Drop PID's tcp.
702 */
703 droptcb(tcp);
704 }
Roland McGrath02203312007-06-11 22:06:31 +0000705 continue;
Denys Vlasenko7a8bf062009-01-29 20:38:20 +0000706 } /* if (opendir worked) */
707 } /* if (-f) */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100708 if (ptrace_attach_or_seize(tcp->pid) < 0) {
Roland McGrath02203312007-06-11 22:06:31 +0000709 perror("attach: ptrace(PTRACE_ATTACH, ...)");
710 droptcb(tcp);
711 continue;
712 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100713 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100714 if (debug_flag)
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200715 fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000716
717 if (daemonized_tracer) {
718 /*
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000719 * Make parent go away.
720 * Also makes grandparent's wait() unblock.
721 */
722 kill(getppid(), SIGKILL);
723 }
724
Roland McGrath02203312007-06-11 22:06:31 +0000725 if (!qflag)
726 fprintf(stderr,
727 "Process %u attached - interrupt to quit\n",
728 tcp->pid);
Denys Vlasenkof95397a2011-06-24 16:51:16 +0200729 } /* for each tcbtab[] */
Roland McGrath02203312007-06-11 22:06:31 +0000730
Denys Vlasenko44f87ef2011-08-17 15:18:21 +0200731 ret:
Roland McGrath02203312007-06-11 22:06:31 +0000732 if (interactive)
733 sigprocmask(SIG_SETMASK, &empty_set, NULL);
734}
735
736static void
Denys Vlasenko12014262011-05-30 14:00:14 +0200737startup_child(char **argv)
Roland McGrath02203312007-06-11 22:06:31 +0000738{
739 struct stat statbuf;
740 const char *filename;
741 char pathname[MAXPATHLEN];
742 int pid = 0;
743 struct tcb *tcp;
744
745 filename = argv[0];
746 if (strchr(filename, '/')) {
747 if (strlen(filename) > sizeof pathname - 1) {
748 errno = ENAMETOOLONG;
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200749 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000750 }
751 strcpy(pathname, filename);
752 }
753#ifdef USE_DEBUGGING_EXEC
754 /*
755 * Debuggers customarily check the current directory
756 * first regardless of the path but doing that gives
757 * security geeks a panic attack.
758 */
759 else if (stat(filename, &statbuf) == 0)
760 strcpy(pathname, filename);
761#endif /* USE_DEBUGGING_EXEC */
762 else {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000763 const char *path;
Roland McGrath02203312007-06-11 22:06:31 +0000764 int m, n, len;
765
766 for (path = getenv("PATH"); path && *path; path += m) {
Denys Vlasenko4f3df072012-01-29 22:38:35 +0100767 const char *colon = strchr(path, ':');
768 if (colon) {
769 n = colon - path;
Roland McGrath02203312007-06-11 22:06:31 +0000770 m = n + 1;
771 }
772 else
773 m = n = strlen(path);
774 if (n == 0) {
775 if (!getcwd(pathname, MAXPATHLEN))
776 continue;
777 len = strlen(pathname);
778 }
779 else if (n > sizeof pathname - 1)
780 continue;
781 else {
782 strncpy(pathname, path, n);
783 len = n;
784 }
785 if (len && pathname[len - 1] != '/')
786 pathname[len++] = '/';
787 strcpy(pathname + len, filename);
788 if (stat(pathname, &statbuf) == 0 &&
789 /* Accept only regular files
790 with some execute bits set.
791 XXX not perfect, might still fail */
792 S_ISREG(statbuf.st_mode) &&
793 (statbuf.st_mode & 0111))
794 break;
795 }
796 }
797 if (stat(pathname, &statbuf) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200798 perror_msg_and_die("Can't stat '%s'", filename);
Roland McGrath02203312007-06-11 22:06:31 +0000799 }
Dmitry V. Levina6809652008-11-10 17:14:58 +0000800 strace_child = pid = fork();
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000801 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200802 perror_msg_and_die("fork");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000803 }
Denys Vlasenko75422762011-05-27 14:36:01 +0200804 if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */
805 || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000806 ) {
807 pid = getpid();
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200808 if (outf != stderr)
809 close(fileno(outf));
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100810 if (!daemonized_tracer && !use_seize) {
811 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200812 perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000813 }
Roland McGrath02203312007-06-11 22:06:31 +0000814 }
Roland McGrath02203312007-06-11 22:06:31 +0000815
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200816 if (username != NULL) {
Roland McGrath02203312007-06-11 22:06:31 +0000817 uid_t run_euid = run_uid;
818 gid_t run_egid = run_gid;
819
820 if (statbuf.st_mode & S_ISUID)
821 run_euid = statbuf.st_uid;
822 if (statbuf.st_mode & S_ISGID)
823 run_egid = statbuf.st_gid;
Roland McGrath02203312007-06-11 22:06:31 +0000824 /*
825 * It is important to set groups before we
826 * lose privileges on setuid.
827 */
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200828 if (initgroups(username, run_gid) < 0) {
829 perror_msg_and_die("initgroups");
830 }
831 if (setregid(run_gid, run_egid) < 0) {
832 perror_msg_and_die("setregid");
833 }
834 if (setreuid(run_uid, run_euid) < 0) {
835 perror_msg_and_die("setreuid");
Roland McGrath02203312007-06-11 22:06:31 +0000836 }
837 }
Denys Vlasenkoab034fb2011-09-01 10:27:42 +0200838 else if (geteuid() != 0)
Roland McGrath02203312007-06-11 22:06:31 +0000839 setreuid(run_uid, run_uid);
840
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000841 if (!daemonized_tracer) {
842 /*
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200843 * Induce a ptrace stop. Tracer (our parent)
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000844 * will resume us with PTRACE_SYSCALL and display
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200845 * the immediately following execve syscall.
846 * Can't do this on NOMMU systems, we are after
847 * vfork: parent is blocked, stopping would deadlock.
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000848 */
Mike Frysingerc1a5b7e2009-10-07 20:41:29 -0400849 if (!strace_vforked)
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200850 kill(pid, SIGSTOP);
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000851 } else {
852 struct sigaction sv_sigchld;
853 sigaction(SIGCHLD, NULL, &sv_sigchld);
854 /*
855 * Make sure it is not SIG_IGN, otherwise wait
856 * will not block.
857 */
858 signal(SIGCHLD, SIG_DFL);
859 /*
860 * Wait for grandchild to attach to us.
861 * It kills child after that, and wait() unblocks.
862 */
863 alarm(3);
864 wait(NULL);
865 alarm(0);
866 sigaction(SIGCHLD, &sv_sigchld, NULL);
867 }
Roland McGrath02203312007-06-11 22:06:31 +0000868
869 execv(pathname, argv);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +0200870 perror_msg_and_die("exec");
Roland McGrath02203312007-06-11 22:06:31 +0000871 }
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000872
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200873 /* We are the tracer */
Denys Vlasenko75422762011-05-27 14:36:01 +0200874
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200875 if (!daemonized_tracer) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100876 if (!use_seize) {
877 /* child did PTRACE_TRACEME, nothing to do in parent */
878 } else {
879 if (!strace_vforked) {
880 /* Wait until child stopped itself */
881 int status;
882 while (waitpid(pid, &status, WSTOPPED) < 0) {
883 if (errno == EINTR)
884 continue;
885 perror_msg_and_die("waitpid");
886 }
887 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100888 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100889 perror_msg_and_die("Unexpected wait status %x", status);
890 }
891 }
892 /* Else: vforked case, we have no way to sync.
893 * Just attach to it as soon as possible.
894 * This means that we may miss a few first syscalls...
895 */
896
897 if (ptrace_attach_or_seize(pid)) {
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100898 kill_save_errno(pid, SIGKILL);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100899 perror_msg_and_die("Can't attach to %d", pid);
900 }
901 if (!strace_vforked)
902 kill(pid, SIGCONT);
903 }
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200904 tcp = alloctcb(pid);
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200905 if (!strace_vforked)
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100906 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop;
Denys Vlasenkof88837a2011-09-05 14:05:46 +0200907 else
Denys Vlasenko75fe85c2012-03-09 15:15:24 +0100908 tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP;
Denys Vlasenko2e968c02011-09-01 10:23:09 +0200909 }
910 else {
911 /* With -D, *we* are child here, IOW: different pid. Fetch it: */
912 strace_tracer_pid = getpid();
913 /* The tracee is our parent: */
914 pid = getppid();
Denys Vlasenkof2025022012-03-09 15:29:45 +0100915 alloctcb(pid);
916 /* attaching will be done later, by startup_attach */
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +0000917 }
Roland McGrath02203312007-06-11 22:06:31 +0000918}
919
Wang Chaob13c0de2010-11-12 17:25:19 +0800920/*
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000921 * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
Wang Chaob13c0de2010-11-12 17:25:19 +0800922 * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000923 * and then see which options are supported by the kernel.
Wang Chaob13c0de2010-11-12 17:25:19 +0800924 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000925static void
Denys Vlasenko3454e4b2011-05-23 21:29:03 +0200926test_ptrace_setoptions_followfork(void)
Wang Chaob13c0de2010-11-12 17:25:19 +0800927{
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000928 int pid, expected_grandchild = 0, found_grandchild = 0;
929 const unsigned int test_options = PTRACE_O_TRACECLONE |
930 PTRACE_O_TRACEFORK |
931 PTRACE_O_TRACEVFORK;
Wang Chaob13c0de2010-11-12 17:25:19 +0800932
Denys Vlasenko5d645812011-08-20 12:48:18 +0200933 pid = fork();
934 if (pid < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000935 perror_msg_and_die("fork");
Denys Vlasenko5d645812011-08-20 12:48:18 +0200936 if (pid == 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000937 pid = getpid();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +0100938 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000939 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
940 __func__);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100941 kill_save_errno(pid, SIGSTOP);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000942 if (fork() < 0)
943 perror_msg_and_die("fork");
944 _exit(0);
Wang Chaob13c0de2010-11-12 17:25:19 +0800945 }
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000946
947 while (1) {
948 int status, tracee_pid;
949
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000950 errno = 0;
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000951 tracee_pid = wait(&status);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000952 if (tracee_pid <= 0) {
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000953 if (errno == EINTR)
954 continue;
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100955 if (errno == ECHILD)
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000956 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000957 kill_save_errno(pid, SIGKILL);
958 perror_msg_and_die("%s: unexpected wait result %d",
959 __func__, tracee_pid);
960 }
961 if (WIFEXITED(status)) {
962 if (WEXITSTATUS(status)) {
963 if (tracee_pid != pid)
964 kill_save_errno(pid, SIGKILL);
965 error_msg_and_die("%s: unexpected exit status %u",
966 __func__, WEXITSTATUS(status));
967 }
968 continue;
969 }
970 if (WIFSIGNALED(status)) {
971 if (tracee_pid != pid)
972 kill_save_errno(pid, SIGKILL);
973 error_msg_and_die("%s: unexpected signal %u",
974 __func__, WTERMSIG(status));
975 }
976 if (!WIFSTOPPED(status)) {
977 if (tracee_pid != pid)
978 kill_save_errno(tracee_pid, SIGKILL);
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100979 kill_save_errno(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000980 error_msg_and_die("%s: unexpected wait status %x",
981 __func__, status);
Dmitry V. Levinb1467442010-12-02 20:56:43 +0000982 }
983 if (tracee_pid != pid) {
Dmitry V. Levin2fabd0e2011-02-19 21:33:50 +0000984 found_grandchild = tracee_pid;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000985 if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
986 kill_save_errno(tracee_pid, SIGKILL);
987 kill_save_errno(pid, SIGKILL);
988 perror_msg_and_die("PTRACE_CONT doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +0800989 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +0000990 continue;
991 }
992 switch (WSTOPSIG(status)) {
993 case SIGSTOP:
994 if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
995 && errno != EINVAL && errno != EIO)
996 perror_msg("PTRACE_SETOPTIONS");
997 break;
998 case SIGTRAP:
999 if (status >> 16 == PTRACE_EVENT_FORK) {
1000 long msg = 0;
1001
1002 if (ptrace(PTRACE_GETEVENTMSG, pid,
1003 NULL, (long) &msg) == 0)
1004 expected_grandchild = msg;
1005 }
1006 break;
1007 }
1008 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
1009 kill_save_errno(pid, SIGKILL);
1010 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Wang Chaob13c0de2010-11-12 17:25:19 +08001011 }
1012 }
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001013 if (expected_grandchild && expected_grandchild == found_grandchild) {
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001014 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001015 if (debug_flag)
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001016 fprintf(stderr, "ptrace_setoptions = %#x\n",
1017 ptrace_setoptions);
1018 return;
1019 }
1020 error_msg("Test for PTRACE_O_TRACECLONE failed, "
1021 "giving up using this feature.");
Wang Chaob13c0de2010-11-12 17:25:19 +08001022}
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001023
1024/*
1025 * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
1026 * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
1027 * and then see whether it will stop with (SIGTRAP | 0x80).
1028 *
1029 * Use of this option enables correct handling of user-generated SIGTRAPs,
1030 * and SIGTRAPs generated by special instructions such as int3 on x86:
1031 * _start: .globl _start
1032 * int3
1033 * movl $42, %ebx
1034 * movl $1, %eax
1035 * int $0x80
1036 * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S")
1037 */
1038static void
1039test_ptrace_setoptions_for_all(void)
1040{
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001041 const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
1042 PTRACE_O_TRACEEXEC;
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001043 int pid;
1044 int it_worked = 0;
1045
1046 pid = fork();
1047 if (pid < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001048 perror_msg_and_die("fork");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001049
1050 if (pid == 0) {
1051 pid = getpid();
1052 if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
Denys Vlasenko75422762011-05-27 14:36:01 +02001053 /* Note: exits with exitcode 1 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001054 perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
1055 __func__);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001056 kill(pid, SIGSTOP);
1057 _exit(0); /* parent should see entry into this syscall */
1058 }
1059
1060 while (1) {
1061 int status, tracee_pid;
1062
1063 errno = 0;
1064 tracee_pid = wait(&status);
1065 if (tracee_pid <= 0) {
1066 if (errno == EINTR)
1067 continue;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001068 kill_save_errno(pid, SIGKILL);
1069 perror_msg_and_die("%s: unexpected wait result %d",
1070 __func__, tracee_pid);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001071 }
Denys Vlasenko75422762011-05-27 14:36:01 +02001072 if (WIFEXITED(status)) {
1073 if (WEXITSTATUS(status) == 0)
1074 break;
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001075 error_msg_and_die("%s: unexpected exit status %u",
1076 __func__, WEXITSTATUS(status));
1077 }
1078 if (WIFSIGNALED(status)) {
1079 error_msg_and_die("%s: unexpected signal %u",
1080 __func__, WTERMSIG(status));
Denys Vlasenko75422762011-05-27 14:36:01 +02001081 }
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001082 if (!WIFSTOPPED(status)) {
1083 kill(pid, SIGKILL);
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001084 error_msg_and_die("%s: unexpected wait status %x",
1085 __func__, status);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001086 }
1087 if (WSTOPSIG(status) == SIGSTOP) {
1088 /*
1089 * We don't check "options aren't accepted" error.
1090 * If it happens, we'll never get (SIGTRAP | 0x80),
1091 * and thus will decide to not use the option.
1092 * IOW: the outcome of the test will be correct.
1093 */
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001094 if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
1095 && errno != EINVAL && errno != EIO)
1096 perror_msg("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001097 }
1098 if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
1099 it_worked = 1;
1100 }
1101 if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001102 kill_save_errno(pid, SIGKILL);
Denys Vlasenko75422762011-05-27 14:36:01 +02001103 perror_msg_and_die("PTRACE_SYSCALL doesn't work");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001104 }
1105 }
1106
1107 if (it_worked) {
Denys Vlasenko75422762011-05-27 14:36:01 +02001108 syscall_trap_sig = (SIGTRAP | 0x80);
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001109 ptrace_setoptions |= test_options;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001110 if (debug_flag)
Denys Vlasenkof44cce42011-06-21 14:34:10 +02001111 fprintf(stderr, "ptrace_setoptions = %#x\n",
1112 ptrace_setoptions);
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001113 return;
1114 }
1115
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001116 error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
1117 "giving up using this feature.");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001118}
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001119
1120# ifdef USE_SEIZE
1121static void
1122test_ptrace_seize(void)
1123{
1124 int pid;
1125
1126 pid = fork();
1127 if (pid < 0)
1128 perror_msg_and_die("fork");
1129
1130 if (pid == 0) {
1131 pause();
1132 _exit(0);
1133 }
1134
1135 /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After
1136 * attaching tracee continues to run unless a trap condition occurs.
1137 * PTRACE_SEIZE doesn't affect signal or group stop state.
1138 */
1139 if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) {
1140 post_attach_sigstop = 0; /* this sets use_seize to 1 */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001141 } else if (debug_flag) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001142 fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
1143 }
1144
1145 kill(pid, SIGKILL);
1146
1147 while (1) {
1148 int status, tracee_pid;
1149
1150 errno = 0;
1151 tracee_pid = waitpid(pid, &status, 0);
1152 if (tracee_pid <= 0) {
1153 if (errno == EINTR)
1154 continue;
1155 perror_msg_and_die("%s: unexpected wait result %d",
1156 __func__, tracee_pid);
1157 }
1158 if (WIFSIGNALED(status)) {
1159 return;
1160 }
1161 error_msg_and_die("%s: unexpected wait status %x",
1162 __func__, status);
1163 }
1164}
1165# else /* !USE_SEIZE */
1166# define test_ptrace_seize() ((void)0)
1167# endif
1168
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001169static void
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001170get_os_release(void)
1171{
1172 struct utsname u;
1173 if (uname(&u) < 0)
1174 perror_msg_and_die("uname");
1175 os_release = strdup(u.release);
1176 if (!os_release)
1177 die_out_of_memory();
1178}
1179
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01001180/*
1181 * Initialization part of main() was eating much stack (~0.5k),
1182 * which was unused after init.
1183 * We can reuse it if we move init code into a separate function.
1184 *
1185 * Don't want main() to inline us and defeat the reason
1186 * we have a separate function.
1187 */
1188static void __attribute__ ((noinline))
1189init(int argc, char *argv[])
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001190{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001191 struct tcb *tcp;
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001192 int c;
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001193 int optF = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001194 struct sigaction sa;
1195
Dmitry V. Levin08b623e2007-10-08 21:04:41 +00001196 progname = argv[0] ? argv[0] : "strace";
1197
Denys Vlasenko75422762011-05-27 14:36:01 +02001198 strace_tracer_pid = getpid();
1199
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001200 get_os_release();
1201
Roland McGrathee9d4352002-12-18 04:16:10 +00001202 /* Allocate the initial tcbtab. */
1203 tcbtabsize = argc; /* Surely enough for all -p args. */
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001204 tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001205 if (!tcbtab)
1206 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001207 tcp = calloc(tcbtabsize, sizeof(*tcp));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001208 if (!tcp)
1209 die_out_of_memory();
Denys Vlasenko4f12af22011-06-23 13:16:23 +02001210 for (c = 0; c < tcbtabsize; c++)
1211 tcbtab[c] = tcp++;
Roland McGrathee9d4352002-12-18 04:16:10 +00001212
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001213 outf = stderr;
Roland McGrath138c6a32006-01-12 09:50:49 +00001214 set_sortby(DEFAULT_SORTBY);
1215 set_personality(DEFAULT_PERSONALITY);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001216 qualify("trace=all");
1217 qualify("abbrev=all");
1218 qualify("verbose=all");
1219 qualify("signal=all");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001220 while ((c = getopt(argc, argv,
Grant Edwards8a082772011-04-07 20:25:40 +00001221 "+cCdfFhiqrtTvVxyz"
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001222 "D"
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001223 "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001224 switch (c) {
1225 case 'c':
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001226 if (cflag == CFLAG_BOTH) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001227 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001228 }
1229 cflag = CFLAG_ONLY_STATS;
1230 break;
1231 case 'C':
1232 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001233 error_msg_and_die("-c and -C are mutually exclusive options");
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001234 }
1235 cflag = CFLAG_BOTH;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001236 break;
1237 case 'd':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001238 debug_flag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001239 break;
Denys Vlasenkoecfe2f12008-12-30 20:51:30 +00001240 case 'D':
1241 daemonized_tracer = 1;
1242 break;
Roland McGrath41c48222008-07-18 00:25:10 +00001243 case 'F':
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001244 optF = 1;
1245 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001246 case 'f':
1247 followfork++;
1248 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001249 case 'h':
1250 usage(stdout, 0);
1251 break;
1252 case 'i':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001253 iflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001254 break;
1255 case 'q':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001256 qflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001257 break;
1258 case 'r':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001259 rflag = 1;
1260 /* fall through to tflag++ */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001261 case 't':
1262 tflag++;
1263 break;
1264 case 'T':
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001265 Tflag = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001266 break;
1267 case 'x':
1268 xflag++;
1269 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001270 case 'y':
1271 show_fd_path = 1;
1272 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001273 case 'v':
1274 qualify("abbrev=none");
1275 break;
1276 case 'V':
Roland McGrath9c9a2532003-02-20 02:56:29 +00001277 printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001278 exit(0);
1279 break;
Michal Ludvig17f8fb32002-11-06 13:17:21 +00001280 case 'z':
1281 not_failing_only = 1;
1282 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001283 case 'a':
1284 acolumn = atoi(optarg);
Denys Vlasenko102ec492011-08-25 01:27:59 +02001285 if (acolumn < 0)
1286 error_msg_and_die("Bad column width '%s'", optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001287 break;
1288 case 'e':
1289 qualify(optarg);
1290 break;
1291 case 'o':
1292 outfname = strdup(optarg);
1293 break;
1294 case 'O':
1295 set_overhead(atoi(optarg));
1296 break;
1297 case 'p':
Denys Vlasenkoe8172b72012-03-09 13:01:04 +01001298 process_opt_p_list(optarg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001299 break;
Grant Edwards8a082772011-04-07 20:25:40 +00001300 case 'P':
1301 tracing_paths = 1;
1302 if (pathtrace_select(optarg)) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001303 error_msg_and_die("Failed to select path '%s'", optarg);
Grant Edwards8a082772011-04-07 20:25:40 +00001304 }
1305 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001306 case 's':
1307 max_strlen = atoi(optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001308 if (max_strlen < 0) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001309 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
Roland McGrathdccec722005-05-09 07:45:47 +00001310 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001311 break;
1312 case 'S':
1313 set_sortby(optarg);
1314 break;
1315 case 'u':
1316 username = strdup(optarg);
1317 break;
Roland McGrathde6e5332003-01-24 04:31:23 +00001318 case 'E':
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001319 if (putenv(optarg) < 0)
1320 die_out_of_memory();
Roland McGrathde6e5332003-01-24 04:31:23 +00001321 break;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001322 case 'I':
1323 opt_intr = atoi(optarg);
1324 if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) {
1325 error_msg_and_die("Invalid -%c argument: '%s'", c, optarg);
1326 }
1327 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001328 default:
1329 usage(stderr, 1);
1330 break;
1331 }
1332 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001333 argv += optind;
1334 /* argc -= optind; - no need, argc is not used below */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001335
Denys Vlasenko102ec492011-08-25 01:27:59 +02001336 acolumn_spaces = malloc(acolumn + 1);
1337 if (!acolumn_spaces)
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001338 die_out_of_memory();
Denys Vlasenko102ec492011-08-25 01:27:59 +02001339 memset(acolumn_spaces, ' ', acolumn);
1340 acolumn_spaces[acolumn] = '\0';
1341
Denys Vlasenko837399a2012-01-24 11:37:03 +01001342 /* Must have PROG [ARGS], or -p PID. Not both. */
Denys Vlasenkofd883382012-03-09 13:03:41 +01001343 if (!argv[0] == !nprocs)
Roland McGrathce0d1542003-11-11 21:24:23 +00001344 usage(stderr, 1);
1345
Denys Vlasenkofd883382012-03-09 13:03:41 +01001346 if (nprocs != 0 && daemonized_tracer) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001347 error_msg_and_die("-D and -p are mutually exclusive options");
Wang Chaod322a4b2010-08-05 14:30:11 +08001348 }
1349
Dmitry V. Levin06350db2008-07-25 15:42:34 +00001350 if (!followfork)
1351 followfork = optF;
1352
Roland McGrathcb9def62006-04-25 07:48:03 +00001353 if (followfork > 1 && cflag) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001354 error_msg_and_die("(-c or -C) and -ff are mutually exclusive options");
Roland McGrathcb9def62006-04-25 07:48:03 +00001355 }
1356
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001357 /* See if they want to run as another user. */
1358 if (username != NULL) {
1359 struct passwd *pent;
1360
1361 if (getuid() != 0 || geteuid() != 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001362 error_msg_and_die("You must be root to use the -u option");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001363 }
Denys Vlasenko5d645812011-08-20 12:48:18 +02001364 pent = getpwnam(username);
1365 if (pent == NULL) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001366 error_msg_and_die("Cannot find user '%s'", username);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001367 }
1368 run_uid = pent->pw_uid;
1369 run_gid = pent->pw_gid;
1370 }
1371 else {
1372 run_uid = getuid();
1373 run_gid = getgid();
1374 }
1375
Dmitry V. Levin04f8b482011-08-16 18:57:29 +00001376 if (followfork)
1377 test_ptrace_setoptions_followfork();
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02001378 test_ptrace_setoptions_for_all();
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001379 test_ptrace_seize();
Dmitry V. Levin8044bc12010-12-07 12:50:49 +00001380
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001381 /* Check if they want to redirect the output. */
1382 if (outfname) {
Roland McGrath37b9a662003-11-07 02:26:54 +00001383 /* See if they want to pipe the output. */
1384 if (outfname[0] == '|' || outfname[0] == '!') {
1385 /*
1386 * We can't do the <outfname>.PID funny business
1387 * when using popen, so prohibit it.
1388 */
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001389 if (followfork > 1)
1390 error_msg_and_die("Piping the output and -ff are mutually exclusive");
1391 outf = strace_popen(outfname + 1);
Roland McGrath37b9a662003-11-07 02:26:54 +00001392 }
Denys Vlasenko3d5ed412011-06-22 13:17:16 +02001393 else if (followfork <= 1)
1394 outf = strace_fopen(outfname);
Denys Vlasenko328bf252012-03-12 23:34:13 +01001395 } else {
1396 /* -ff without -o FILE is the same as single -f */
1397 if (followfork > 1)
1398 followfork = 1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001399 }
1400
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001401 if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
Denys Vlasenkoa677da52012-01-24 11:31:51 +01001402 char *buf = malloc(BUFSIZ);
1403 if (!buf)
1404 die_out_of_memory();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001405 setvbuf(outf, buf, _IOLBF, BUFSIZ);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001406 }
Denys Vlasenko837399a2012-01-24 11:37:03 +01001407 if (outfname && argv[0]) {
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001408 if (!opt_intr)
1409 opt_intr = INTR_NEVER;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001410 qflag = 1;
Roland McGrath36931052003-06-03 01:35:20 +00001411 }
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001412 if (!opt_intr)
1413 opt_intr = INTR_WHILE_WAIT;
Wang Chaob13c0de2010-11-12 17:25:19 +08001414
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001415 /* argv[0] -pPID -oFILE Default interactive setting
1416 * yes 0 0 INTR_WHILE_WAIT
1417 * no 1 0 INTR_WHILE_WAIT
1418 * yes 0 1 INTR_NEVER
1419 * no 1 1 INTR_WHILE_WAIT
Roland McGrath54cc1c82007-11-03 23:34:11 +00001420 */
1421
1422 /* STARTUP_CHILD must be called before the signal handlers get
1423 installed below as they are inherited into the spawned process.
1424 Also we do not need to be protected by them as during interruption
1425 in the STARTUP_CHILD mode we kill the spawned process anyway. */
Denys Vlasenko837399a2012-01-24 11:37:03 +01001426 if (argv[0])
1427 startup_child(argv);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001428
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001429 sigemptyset(&empty_set);
1430 sigemptyset(&blocked_set);
1431 sa.sa_handler = SIG_IGN;
1432 sigemptyset(&sa.sa_mask);
1433 sa.sa_flags = 0;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001434 sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1435 sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1436 if (opt_intr != INTR_ANYWHERE) {
1437 if (opt_intr == INTR_BLOCK_TSTP_TOO)
1438 sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1439 /*
1440 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1441 * fatal signals are blocked while syscall stop is processed,
1442 * and acted on in between, when waiting for new syscall stops.
1443 * In non-interactive mode, signals are ignored.
1444 */
1445 if (opt_intr == INTR_WHILE_WAIT) {
1446 sigaddset(&blocked_set, SIGHUP);
1447 sigaddset(&blocked_set, SIGINT);
1448 sigaddset(&blocked_set, SIGQUIT);
1449 sigaddset(&blocked_set, SIGPIPE);
1450 sigaddset(&blocked_set, SIGTERM);
1451 sa.sa_handler = interrupt;
Denys Vlasenkob51581e2012-01-29 16:53:03 +01001452 }
1453 /* SIG_IGN, or set handler for these */
1454 sigaction(SIGHUP, &sa, NULL);
1455 sigaction(SIGINT, &sa, NULL);
1456 sigaction(SIGQUIT, &sa, NULL);
1457 sigaction(SIGPIPE, &sa, NULL);
1458 sigaction(SIGTERM, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001459 }
Roland McGrath553a6092002-12-16 20:40:39 +00001460 /* Make sure SIGCHLD has the default action so that waitpid
1461 definitely works without losing track of children. The user
1462 should not have given us a bogus state to inherit, but he might
1463 have. Arguably we should detect SIG_IGN here and pass it on
1464 to children, but probably noone really needs that. */
1465 sa.sa_handler = SIG_DFL;
1466 sigaction(SIGCHLD, &sa, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001467
Denys Vlasenkofd883382012-03-09 13:03:41 +01001468 if (nprocs != 0 || daemonized_tracer)
Roland McGrath02203312007-06-11 22:06:31 +00001469 startup_attach();
Roland McGrath02203312007-06-11 22:06:31 +00001470
Denys Vlasenkofd883382012-03-09 13:03:41 +01001471 /* Do we want pids printed in our -o OUTFILE?
1472 * -ff: no (every pid has its own file); or
1473 * -f: yes (there can be more pids in the future); or
1474 * -p PID1,PID2: yes (there are already more than one pid)
1475 */
1476 print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001477}
1478
Denys Vlasenko2b60c352011-06-22 12:45:25 +02001479static void
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001480expand_tcbtab(void)
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001481{
1482 /* Allocate some more TCBs and expand the table.
1483 We don't want to relocate the TCBs because our
1484 callers have pointers and it would be a pain.
1485 So tcbtab is a table of pointers. Since we never
1486 free the TCBs, we allocate a single chunk of many. */
Denys Vlasenko18da2732011-06-22 12:41:57 +02001487 int i = tcbtabsize;
1488 struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
1489 struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
Denys Vlasenko1d46ba52011-08-31 14:00:02 +02001490 if (!newtab || !newtcbs)
1491 die_out_of_memory();
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001492 tcbtabsize *= 2;
1493 tcbtab = newtab;
Denys Vlasenko18da2732011-06-22 12:41:57 +02001494 while (i < tcbtabsize)
1495 tcbtab[i++] = newtcbs++;
Roland McGrath7b54a7a2004-06-04 01:50:45 +00001496}
1497
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001498struct tcb *
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001499alloc_tcb(int pid, int command_options_parsed)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001500{
1501 int i;
1502 struct tcb *tcp;
1503
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001504 if (nprocs == tcbtabsize)
1505 expand_tcbtab();
1506
Roland McGrathee9d4352002-12-18 04:16:10 +00001507 for (i = 0; i < tcbtabsize; i++) {
1508 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001509 if ((tcp->flags & TCB_INUSE) == 0) {
Denys Vlasenko18da2732011-06-22 12:41:57 +02001510 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001511 tcp->pid = pid;
Denys Vlasenko381dbc22011-09-05 13:59:39 +02001512 tcp->flags = TCB_INUSE;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001513 tcp->outf = outf; /* Initialise to current out file */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001514#if SUPPORTED_PERSONALITIES > 1
1515 tcp->currpers = current_personality;
1516#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001517 nprocs++;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001518 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001519 fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001520 if (command_options_parsed)
1521 newoutf(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001522 return tcp;
1523 }
1524 }
Denys Vlasenko18da2732011-06-22 12:41:57 +02001525 error_msg_and_die("bug in alloc_tcb");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001526}
1527
Denys Vlasenkoeebb04d2012-01-27 15:24:48 +01001528static struct tcb *
Roland McGrath54e931f2010-09-14 18:59:20 -07001529pid2tcb(int pid)
1530{
1531 int i;
1532
1533 if (pid <= 0)
1534 return NULL;
1535
1536 for (i = 0; i < tcbtabsize; i++) {
1537 struct tcb *tcp = tcbtab[i];
1538 if (tcp->pid == pid && (tcp->flags & TCB_INUSE))
1539 return tcp;
1540 }
1541
1542 return NULL;
1543}
1544
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001545void
Denys Vlasenko12014262011-05-30 14:00:14 +02001546droptcb(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001547{
1548 if (tcp->pid == 0)
1549 return;
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001550
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001551 nprocs--;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001552 if (debug_flag)
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001553 fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
Wichert Akkermaneb8ebda2002-04-01 17:48:02 +00001554
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001555 if (printing_tcp == tcp)
1556 printing_tcp = NULL;
1557
1558 if (outfname && followfork >= 2 && tcp->outf) {
1559 if (tcp->curcol != 0)
1560 fprintf(tcp->outf, " <detached>\n");
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001561 fclose(tcp->outf);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001562 } else if (tcp->outf) {
1563 fflush(tcp->outf);
1564 }
Wichert Akkermaneb8ebda2002-04-01 17:48:02 +00001565
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001566 memset(tcp, 0, sizeof(*tcp));
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001567}
1568
Roland McGrath0a463882007-07-05 18:43:16 +00001569/* detach traced process; continue with sig
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001570 * Never call DETACH twice on the same process as both unattached and
1571 * attached-unstopped processes give the same ESRCH. For unattached process we
1572 * would SIGSTOP it and wait for its SIGSTOP notification forever.
1573 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001574static int
Denys Vlasenko4c196382012-01-04 15:11:09 +01001575detach(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001576{
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001577 int error;
1578 int status, sigstop_expected;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001579
1580 if (tcp->flags & TCB_BPTSET)
Andreas Schwab840d85b2010-01-12 11:16:32 +01001581 clearbpt(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001582
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001583 /*
1584 * Linux wrongly insists the child be stopped
Roland McGrath7bf10472002-12-16 20:42:50 +00001585 * before detaching. Arghh. We go through hoops
1586 * to make a clean break of things.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001587 */
Roland McGrath7bf10472002-12-16 20:42:50 +00001588#if defined(SPARC)
1589#undef PTRACE_DETACH
1590#define PTRACE_DETACH PTRACE_SUNDETACH
1591#endif
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001592
1593 sigstop_expected = 0;
1594 if (tcp->flags & TCB_ATTACHED) {
1595 /*
1596 * We attached but possibly didn't see the expected SIGSTOP.
1597 * We must catch exactly one as otherwise the detached process
1598 * would be left stopped (process state T).
1599 */
1600 sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
1601 error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
1602 if (error == 0) {
1603 /* On a clear day, you can see forever. */
1604 }
1605 else if (errno != ESRCH) {
1606 /* Shouldn't happen. */
1607 perror("detach: ptrace(PTRACE_DETACH, ...)");
1608 }
1609 else if (my_tkill(tcp->pid, 0) < 0) {
1610 if (errno != ESRCH)
1611 perror("detach: checking sanity");
1612 }
1613 else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
1614 if (errno != ESRCH)
1615 perror("detach: stopping child");
1616 }
1617 else
1618 sigstop_expected = 1;
Roland McGrath7bf10472002-12-16 20:42:50 +00001619 }
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001620
1621 if (sigstop_expected) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001622 for (;;) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001623#ifdef __WALL
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001624 if (waitpid(tcp->pid, &status, __WALL) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001625 if (errno == ECHILD) /* Already gone. */
1626 break;
1627 if (errno != EINVAL) {
Roland McGrath553a6092002-12-16 20:40:39 +00001628 perror("detach: waiting");
Roland McGrath7508cb42002-12-17 10:48:05 +00001629 break;
1630 }
1631#endif /* __WALL */
1632 /* No __WALL here. */
1633 if (waitpid(tcp->pid, &status, 0) < 0) {
1634 if (errno != ECHILD) {
1635 perror("detach: waiting");
1636 break;
1637 }
1638#ifdef __WCLONE
1639 /* If no processes, try clones. */
Denys Vlasenko37ab4b72012-03-09 15:34:16 +01001640 if (waitpid(tcp->pid, &status, __WCLONE) < 0) {
Roland McGrath7508cb42002-12-17 10:48:05 +00001641 if (errno != ECHILD)
1642 perror("detach: waiting");
1643 break;
1644 }
1645#endif /* __WCLONE */
1646 }
1647#ifdef __WALL
Roland McGrath553a6092002-12-16 20:40:39 +00001648 }
Roland McGrath7508cb42002-12-17 10:48:05 +00001649#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001650 if (!WIFSTOPPED(status)) {
1651 /* Au revoir, mon ami. */
1652 break;
1653 }
1654 if (WSTOPSIG(status) == SIGSTOP) {
Denys Vlasenko4c196382012-01-04 15:11:09 +01001655 ptrace_restart(PTRACE_DETACH, tcp, 0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001656 break;
1657 }
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001658 error = ptrace_restart(PTRACE_CONT, tcp,
Denys Vlasenko75422762011-05-27 14:36:01 +02001659 WSTOPSIG(status) == syscall_trap_sig ? 0
Denys Vlasenko732d1bf2008-12-17 19:21:59 +00001660 : WSTOPSIG(status));
1661 if (error < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001662 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001663 }
Denys Vlasenkoef2fbf82009-01-06 21:45:06 +00001664 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001665
Denys Vlasenko75fe85c2012-03-09 15:15:24 +01001666 if (!qflag && (tcp->flags & TCB_ATTACHED))
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001667 fprintf(stderr, "Process %u detached\n", tcp->pid);
1668
1669 droptcb(tcp);
Roland McGratha08a97e2005-08-03 11:23:46 +00001670
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001671 return error;
1672}
1673
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001674static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001675cleanup(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001676{
1677 int i;
1678 struct tcb *tcp;
Denys Vlasenko35218842012-01-29 21:17:56 +01001679 int fatal_sig;
1680
1681 /* 'interrupted' is a volatile object, fetch it only once */
1682 fatal_sig = interrupted;
1683 if (!fatal_sig)
1684 fatal_sig = SIGTERM;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001685
Roland McGrathee9d4352002-12-18 04:16:10 +00001686 for (i = 0; i < tcbtabsize; i++) {
1687 tcp = tcbtab[i];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001688 if (!(tcp->flags & TCB_INUSE))
1689 continue;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001690 if (debug_flag)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001691 fprintf(stderr,
1692 "cleanup: looking at pid %u\n", tcp->pid);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001693 if (tcp->flags & TCB_STRACE_CHILD) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001694 kill(tcp->pid, SIGCONT);
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001695 kill(tcp->pid, fatal_sig);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001696 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001697 detach(tcp);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001698 }
1699 if (cflag)
1700 call_summary(outf);
1701}
1702
1703static void
Denys Vlasenko12014262011-05-30 14:00:14 +02001704interrupt(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001705{
Denys Vlasenkoa3559252012-01-29 16:43:51 +01001706 interrupted = sig;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001707}
1708
1709#ifndef HAVE_STRERROR
1710
Roland McGrath6d2b3492002-12-30 00:51:30 +00001711#if !HAVE_DECL_SYS_ERRLIST
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001712extern int sys_nerr;
1713extern char *sys_errlist[];
Roland McGrath6d2b3492002-12-30 00:51:30 +00001714#endif /* HAVE_DECL_SYS_ERRLIST */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001715
1716const char *
Denys Vlasenko12014262011-05-30 14:00:14 +02001717strerror(int err_no)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001718{
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001719 static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001720
Denys Vlasenko35aba6a2011-05-25 15:33:26 +02001721 if (err_no < 1 || err_no >= sys_nerr) {
1722 sprintf(buf, "Unknown error %d", err_no);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001723 return buf;
1724 }
Denys Vlasenko35aba6a2011-05-25 15:33:26 +02001725 return sys_errlist[err_no];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001726}
1727
1728#endif /* HAVE_STERRROR */
1729
1730#ifndef HAVE_STRSIGNAL
1731
Roland McGrath8f474e02003-01-14 07:53:33 +00001732#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST
Roland McGrath6d2b3492002-12-30 00:51:30 +00001733extern char *sys_siglist[];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001734#endif
Roland McGrath8f474e02003-01-14 07:53:33 +00001735#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST
1736extern char *_sys_siglist[];
1737#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001738
1739const char *
Denys Vlasenko12014262011-05-30 14:00:14 +02001740strsignal(int sig)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001741{
Denys Vlasenko1945ccc2012-02-27 14:37:48 +01001742 static char buf[sizeof("Unknown signal %d") + sizeof(int)*3];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001743
1744 if (sig < 1 || sig >= NSIG) {
1745 sprintf(buf, "Unknown signal %d", sig);
1746 return buf;
1747 }
1748#ifdef HAVE__SYS_SIGLIST
1749 return _sys_siglist[sig];
1750#else
1751 return sys_siglist[sig];
1752#endif
1753}
1754
1755#endif /* HAVE_STRSIGNAL */
1756
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001757static int
Denys Vlasenko12014262011-05-30 14:00:14 +02001758trace(void)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001759{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001760 struct rusage ru;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001761 struct rusage *rup = cflag ? &ru : NULL;
1762# ifdef __WALL
Roland McGratheb9e2e82009-06-02 16:49:22 -07001763 static int wait4_options = __WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001764# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001765
Roland McGratheb9e2e82009-06-02 16:49:22 -07001766 while (nprocs != 0) {
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001767 int pid;
1768 int wait_errno;
1769 int status, sig;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001770 int stopped;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001771 struct tcb *tcp;
1772 unsigned event;
1773
Denys Vlasenko222713a2009-03-17 14:29:59 +00001774 if (interrupted)
Roland McGratheb9e2e82009-06-02 16:49:22 -07001775 return 0;
1776 if (interactive)
1777 sigprocmask(SIG_SETMASK, &empty_set, NULL);
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001778# ifdef __WALL
1779 pid = wait4(-1, &status, wait4_options, rup);
Roland McGrath5bc05552002-12-17 04:50:47 +00001780 if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001781 /* this kernel does not support __WALL */
1782 wait4_options &= ~__WALL;
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001783 pid = wait4(-1, &status, wait4_options, rup);
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001784 }
Roland McGrath5bc05552002-12-17 04:50:47 +00001785 if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) {
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001786 /* most likely a "cloned" process */
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001787 pid = wait4(-1, &status, __WCLONE, rup);
1788 if (pid < 0) {
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001789 perror_msg("wait4(__WCLONE) failed");
Wichert Akkerman2f1d87e2001-03-28 14:40:14 +00001790 }
1791 }
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001792# else
1793 pid = wait4(-1, &status, 0, rup);
1794# endif /* __WALL */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001795 wait_errno = errno;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001796 if (interactive)
1797 sigprocmask(SIG_BLOCK, &blocked_set, NULL);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001798
Denys Vlasenko26d1b1e2011-08-15 12:24:14 +02001799 if (pid < 0) {
Roland McGratheb9e2e82009-06-02 16:49:22 -07001800 switch (wait_errno) {
1801 case EINTR:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001802 continue;
Roland McGratheb9e2e82009-06-02 16:49:22 -07001803 case ECHILD:
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001804 /*
1805 * We would like to verify this case
1806 * but sometimes a race in Solbourne's
1807 * version of SunOS sometimes reports
1808 * ECHILD before sending us SIGCHILD.
1809 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001810 return 0;
1811 default:
1812 errno = wait_errno;
Denys Vlasenko4c65c442012-03-08 11:54:10 +01001813 perror_msg("wait");
Roland McGratheb9e2e82009-06-02 16:49:22 -07001814 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001815 }
1816 }
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001817 if (pid == popen_pid) {
1818 if (WIFEXITED(status) || WIFSIGNALED(status))
Denys Vlasenko7dd23382011-06-22 13:03:56 +02001819 popen_pid = 0;
Dmitry V. Levin10de62b2006-12-13 21:45:31 +00001820 continue;
1821 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001822
1823 event = ((unsigned)status >> 16);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001824 if (debug_flag) {
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001825 char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001826 char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001827 strcpy(buf, "???");
1828 if (WIFSIGNALED(status))
1829#ifdef WCOREDUMP
1830 sprintf(buf, "WIFSIGNALED,%ssig=%s",
1831 WCOREDUMP(status) ? "core," : "",
1832 signame(WTERMSIG(status)));
1833#else
1834 sprintf(buf, "WIFSIGNALED,sig=%s",
1835 signame(WTERMSIG(status)));
1836#endif
1837 if (WIFEXITED(status))
1838 sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
1839 if (WIFSTOPPED(status))
1840 sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001841#ifdef WIFCONTINUED
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001842 if (WIFCONTINUED(status))
1843 strcpy(buf, "WIFCONTINUED");
Denys Vlasenko5bd67c82011-08-15 11:36:09 +02001844#endif
Denys Vlasenko67559ad2012-03-13 12:05:27 +01001845 evbuf[0] = '\0';
1846 if (event != 0) {
1847 static const char *const event_names[] = {
1848 [PTRACE_EVENT_CLONE] = "CLONE",
1849 [PTRACE_EVENT_FORK] = "FORK",
1850 [PTRACE_EVENT_VFORK] = "VFORK",
1851 [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
1852 [PTRACE_EVENT_EXEC] = "EXEC",
1853 [PTRACE_EVENT_EXIT] = "EXIT",
1854 };
1855 const char *e;
1856 if (event < ARRAY_SIZE(event_names))
1857 e = event_names[event];
1858 else {
1859 sprintf(buf, "?? (%u)", event);
1860 e = buf;
1861 }
1862 sprintf(evbuf, ",PTRACE_EVENT_%s", e);
1863 }
1864 fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf);
Denys Vlasenko1d5f12e2011-06-24 16:41:35 +02001865 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001866
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001867 /* Look up 'pid' in our table. */
Denys Vlasenko5d645812011-08-20 12:48:18 +02001868 tcp = pid2tcb(pid);
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001869
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001870 /* Under Linux, execve changes pid to thread leader's pid,
1871 * and we see this changed pid on EVENT_EXEC and later,
1872 * execve sysexit. Leader "disappears" without exit
1873 * notification. Let user know that, drop leader's tcb,
1874 * and fix up pid in execve thread's tcb.
1875 * Effectively, execve thread's tcb replaces leader's tcb.
1876 *
1877 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
1878 * on exit syscall) in multithreaded programs exactly
1879 * in order to handle this case.
1880 *
1881 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
1882 * On 2.6 and earlier, it can return garbage.
1883 */
1884 if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') {
1885 long old_pid = 0;
1886 if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0
1887 && old_pid > 0
1888 && old_pid != pid
1889 ) {
1890 struct tcb *execve_thread = pid2tcb(old_pid);
1891 if (tcp) {
1892 outf = tcp->outf;
1893 curcol = tcp->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001894 if (execve_thread) {
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001895 if (execve_thread->curcol != 0) {
1896 /*
1897 * One case we are here is -ff:
1898 * try "strace -oLOG -ff test/threaded_execve"
1899 */
1900 fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
1901 execve_thread->curcol = 0;
1902 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001903 /* swap output FILEs (needed for -ff) */
1904 tcp->outf = execve_thread->outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001905 tcp->curcol = execve_thread->curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001906 execve_thread->outf = outf;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001907 execve_thread->curcol = curcol;
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001908 }
1909 droptcb(tcp);
1910 }
1911 tcp = execve_thread;
1912 if (tcp) {
1913 tcp->pid = pid;
1914 tcp->flags |= TCB_REPRINT;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001915 if (!cflag) {
1916 printleader(tcp);
1917 tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
1918 line_ended();
1919 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001920 }
1921 }
1922 }
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01001923
Denys Vlasenko5d645812011-08-20 12:48:18 +02001924 if (tcp == NULL) {
Roland McGrath41c48222008-07-18 00:25:10 +00001925 if (followfork) {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001926 /* This is needed to go with the CLONE_PTRACE
1927 changes in process.c/util.c: we might see
1928 the child's initial trap before we see the
1929 parent return from the clone syscall.
1930 Leave the child suspended until the parent
1931 returns from its system call. Only then
1932 will we have the association of parent and
1933 child so that we know how to do clearbpt
1934 in the child. */
Denys Vlasenko418d66a2009-01-17 01:52:54 +00001935 tcp = alloctcb(pid);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01001936 tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001937 if (!qflag)
Denys Vlasenko833fb132011-08-17 11:30:56 +02001938 fprintf(stderr, "Process %d attached\n",
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001939 pid);
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001940 }
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001941 else
1942 /* This can happen if a clone call used
1943 CLONE_PTRACE itself. */
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001944 {
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001945 if (WIFSTOPPED(status))
Denys Vlasenko97c503f2012-03-09 15:11:21 +01001946 ptrace(PTRACE_CONT, pid, (char *) 0, 0);
Denys Vlasenkocb2ad002011-06-23 13:05:29 +02001947 error_msg_and_die("Unknown pid: %u", pid);
Roland McGrathe85bbfe2003-01-09 06:53:31 +00001948 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001949 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001950
1951 /* Set current output file */
Roland McGratheb9e2e82009-06-02 16:49:22 -07001952 outf = tcp->outf;
Andreas Schwabccdff482009-10-27 16:27:13 +01001953 curcol = tcp->curcol;
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001954
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001955 if (cflag) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001956 tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
1957 tcp->stime = ru.ru_stime;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001958 }
Roland McGratheb9e2e82009-06-02 16:49:22 -07001959
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001960 if (WIFSIGNALED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001961 if (pid == strace_child)
1962 exit_code = 0x100 | WTERMSIG(status);
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00001963 if (cflag != CFLAG_ONLY_STATS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001964 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) {
1965 printleader(tcp);
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001966#ifdef WCOREDUMP
Denys Vlasenko000b6012012-01-28 01:25:03 +01001967 tprintf("+++ killed by %s %s+++\n",
Roland McGrath2efe8792004-01-13 09:59:45 +00001968 signame(WTERMSIG(status)),
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001969 WCOREDUMP(status) ? "(core dumped) " : "");
1970#else
Denys Vlasenko000b6012012-01-28 01:25:03 +01001971 tprintf("+++ killed by %s +++\n",
Denys Vlasenko13d22f12011-06-24 23:01:57 +02001972 signame(WTERMSIG(status)));
Roland McGrath2efe8792004-01-13 09:59:45 +00001973#endif
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001974 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001975 }
1976 droptcb(tcp);
1977 continue;
1978 }
1979 if (WIFEXITED(status)) {
Dmitry V. Levina6809652008-11-10 17:14:58 +00001980 if (pid == strace_child)
1981 exit_code = WEXITSTATUS(status);
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001982 if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) {
1983 printleader(tcp);
Denys Vlasenko000b6012012-01-28 01:25:03 +01001984 tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
Denys Vlasenko7de265d2012-03-13 11:44:31 +01001985 line_ended();
Denys Vlasenko19cdada2011-08-17 10:45:32 +02001986 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001987 droptcb(tcp);
1988 continue;
1989 }
1990 if (!WIFSTOPPED(status)) {
1991 fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
1992 droptcb(tcp);
1993 continue;
1994 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001995
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001996 /* Is this the very first time we see this tracee stopped? */
1997 if (tcp->flags & TCB_STARTUP) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001998 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02001999 fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002000 tcp->flags &= ~TCB_STARTUP;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002001 if (tcp->flags & TCB_BPTSET) {
Roland McGrath02203312007-06-11 22:06:31 +00002002 /*
2003 * One example is a breakpoint inherited from
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002004 * parent through fork().
Roland McGrath02203312007-06-11 22:06:31 +00002005 */
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002006 if (clearbpt(tcp) < 0) {
2007 /* Pretty fatal */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002008 droptcb(tcp);
2009 cleanup();
2010 return -1;
2011 }
2012 }
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002013 if (ptrace_setoptions) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002014 if (debug_flag)
Denys Vlasenko44f87ef2011-08-17 15:18:21 +02002015 fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid);
2016 if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
2017 if (errno != ESRCH) {
2018 /* Should never happen, really */
2019 perror_msg_and_die("PTRACE_SETOPTIONS");
Denys Vlasenko3454e4b2011-05-23 21:29:03 +02002020 }
2021 }
2022 }
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002023 }
2024
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002025 sig = WSTOPSIG(status);
2026
Denys Vlasenkof7db5dd2012-01-28 01:16:02 +01002027 if (event != 0) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002028 /* Ptrace event */
2029#ifdef USE_SEIZE
2030 if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) {
Denys Vlasenko67038162012-01-29 16:46:46 +01002031 /*
2032 * PTRACE_INTERRUPT-stop or group-stop.
2033 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
2034 */
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002035 if (sig == SIGSTOP
2036 || sig == SIGTSTP
2037 || sig == SIGTTIN
2038 || sig == SIGTTOU
2039 ) {
2040 stopped = 1;
2041 goto show_stopsig;
2042 }
2043 }
2044#endif
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002045 goto restart_tracee_with_sig_0;
2046 }
2047
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002048 /* Is this post-attach SIGSTOP?
2049 * Interestingly, the process may stop
2050 * with STOPSIG equal to some other signal
2051 * than SIGSTOP if we happend to attach
2052 * just before the process takes a signal.
2053 */
2054 if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002055 if (debug_flag)
Denys Vlasenkof88837a2011-09-05 14:05:46 +02002056 fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2057 tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002058 goto restart_tracee_with_sig_0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002059 }
2060
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002061 if (sig != syscall_trap_sig) {
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002062 siginfo_t si;
2063
2064 /* Nonzero (true) if tracee is stopped by signal
2065 * (as opposed to "tracee received signal").
2066 */
2067 stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
Denys Vlasenko67038162012-01-29 16:46:46 +01002068#ifdef USE_SEIZE
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002069 show_stopsig:
Denys Vlasenko67038162012-01-29 16:46:46 +01002070#endif
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +00002071 if (cflag != CFLAG_ONLY_STATS
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002072 && (qual_flags[sig] & QUAL_SIGNAL)) {
Dmitry V. Levinc15dfc72011-03-10 14:44:45 +00002073#if defined(PT_CR_IPSR) && defined(PT_CR_IIP)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002074 long pc = 0;
2075 long psr = 0;
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002076
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00002077 upeek(tcp, PT_CR_IPSR, &psr);
2078 upeek(tcp, PT_CR_IIP, &pc);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002079
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002080# define PSR_RI 41
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002081 pc += (psr >> PSR_RI) & 0x3;
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002082# define PC_FORMAT_STR " @ %lx"
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002083# define PC_FORMAT_ARG , pc
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002084#else
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002085# define PC_FORMAT_STR ""
2086# define PC_FORMAT_ARG /* nothing */
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00002087#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002088 printleader(tcp);
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002089 if (!stopped) {
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002090 tprints("--- ");
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002091 printsiginfo(&si, verbose(tcp));
Denys Vlasenko000b6012012-01-28 01:25:03 +01002092 tprintf(" (%s)" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002093 strsignal(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002094 PC_FORMAT_ARG);
2095 } else
Denys Vlasenko000b6012012-01-28 01:25:03 +01002096 tprintf("--- %s by %s" PC_FORMAT_STR " ---\n",
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002097 strsignal(sig),
2098 signame(sig)
Dmitry V. Levin6b7a2612011-03-10 21:20:35 +00002099 PC_FORMAT_ARG);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002100 line_ended();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002101 }
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002102
2103 if (!stopped)
2104 /* It's signal-delivery-stop. Inject the signal */
2105 goto restart_tracee;
2106
2107 /* It's group-stop */
2108#ifdef USE_SEIZE
2109 if (use_seize) {
2110 /*
2111 * This ends ptrace-stop, but does *not* end group-stop.
2112 * This makes stopping signals work properly on straced process
2113 * (that is, process really stops. It used to continue to run).
2114 */
2115 if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2116 cleanup();
2117 return -1;
2118 }
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002119 tcp->curcol = curcol;
Denys Vlasenko31fa8a22012-01-29 02:01:44 +01002120 continue;
2121 }
2122 /* We don't have PTRACE_LISTEN support... */
2123#endif
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002124 goto restart_tracee;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002125 }
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002126
2127 /* We handled quick cases, we are permitted to interrupt now. */
Roland McGrath02203312007-06-11 22:06:31 +00002128 if (interrupted)
2129 return 0;
Denys Vlasenko2ecba322011-08-21 17:35:39 +02002130
2131 /* This should be syscall entry or exit.
2132 * (Or it still can be that pesky post-execve SIGTRAP!)
2133 * Handle it.
2134 */
Roland McGratheb9e2e82009-06-02 16:49:22 -07002135 if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) {
2136 /* ptrace() failed in trace_syscall() with ESRCH.
2137 * Likely a result of process disappearing mid-flight.
2138 * Observed case: exit_group() terminating
Denys Vlasenkof1e69032012-01-04 15:15:26 +01002139 * all processes in thread group.
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002140 * We assume that ptrace error was caused by process death.
Denys Vlasenkof2025022012-03-09 15:29:45 +01002141 * We used to detach(tcp) here, but since we no longer
2142 * implement "detach before death" policy/hack,
2143 * we can let this process to report its death to us
2144 * normally, via WIFEXITED or WIFSIGNALED wait status.
2145 */
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002146 tcp->curcol = curcol;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002147 continue;
2148 }
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002149 restart_tracee_with_sig_0:
2150 sig = 0;
2151 restart_tracee:
Andreas Schwabccdff482009-10-27 16:27:13 +01002152 /* Remember current print column before continuing. */
2153 tcp->curcol = curcol;
Denys Vlasenko6cda73f2011-09-02 16:23:53 +02002154 if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002155 cleanup();
2156 return -1;
2157 }
2158 }
2159 return 0;
2160}
Denys Vlasenkoecc8b972012-03-12 23:05:25 +01002161
2162int
2163main(int argc, char *argv[])
2164{
2165 init(argc, argv);
2166
2167 /* Run main tracing loop */
2168 if (trace() < 0)
2169 return 1;
2170
2171 cleanup();
2172 fflush(NULL);
2173 if (exit_code > 0xff) {
2174 /* Avoid potential core file clobbering. */
2175 struct rlimit rlim = {0, 0};
2176 setrlimit(RLIMIT_CORE, &rlim);
2177
2178 /* Child was killed by a signal, mimic that. */
2179 exit_code &= 0xff;
2180 signal(exit_code, SIG_DFL);
2181 raise(exit_code);
2182 /* Paranoia - what if this signal is not fatal?
2183 Exit with 128 + signo then. */
2184 exit_code += 128;
2185 }
2186
2187 return exit_code;
2188}