176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/*
276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved.
776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without
976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions
1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met:
1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright
1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer.
1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright
1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    notice, this list of conditions and the following disclaimer in the
1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    documentation and/or other materials provided with the distribution.
1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products
1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *    derived from this software without specific prior written permission.
1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman *
1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */
3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h"
323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko#include <stdarg.h>
3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h>
3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h>
3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h>
3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h>
3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h>
3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h>
3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h>
4070b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath#include <dirent.h>
41f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#include <sys/utsname.h>
42882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#ifdef HAVE_PRCTL
43882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin# include <sys/prctl.h>
44882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#endif
458470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if defined(IA64)
467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h>
477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif
48a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko/* In some libc, these aren't declared. Do it ourself: */
4996d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkoextern char **environ;
50418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern int optind;
51418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern char *optarg;
5296d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko
53327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND
54327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi/* if this is true do the stack trace for every system call */
55327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementibool stack_trace_enabled = false;
56327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif
57a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko
58a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#if defined __NR_tkill
59a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig))
60a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#else
61a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko   /* kill() may choose arbitrarily the target task of the process group
62a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko      while we later wait on a that specific TID.  PID process waits become
63a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko      TID task specific waits for a process under ptrace(2).  */
64978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# warning "tkill(2) not available, risk of strace hangs!"
65a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) kill((tid), (sig))
66a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#endif
67a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko
685c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko/* Glue for systems without a MMU that cannot provide fork() */
695c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if !defined(HAVE_FORK)
705c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# undef NOMMU_SYSTEM
715c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# define NOMMU_SYSTEM 1
725c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#endif
735c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if NOMMU_SYSTEM
745c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# define fork() vfork()
755c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#endif
765c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko
77a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkocflag_t cflag = CFLAG_NONE;
78a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int followfork = 0;
79f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0;
80a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int xflag = 0;
818d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkobool need_fork_exec_workarounds = 0;
82a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool debug_flag = 0;
83a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool Tflag = 0;
84a34deadbb3419909d691de514a298f6b748f2d95Anton Blanchardbool iflag = 0;
85e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hillsbool count_wallclock = 0;
8601997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrangeunsigned int qflag = 0;
873454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */
8875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP;
89a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic unsigned int tflag = 0;
90a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool rflag = 0;
91a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool print_pid_pfx = 0;
92b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko
93b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* -I n */
94b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkoenum {
95b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    INTR_NOT_SET        = 0,
96b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    INTR_ANYWHERE       = 1, /* don't block/ignore any signals */
97b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    INTR_WHILE_WAIT     = 2, /* block fatal signals while decoding syscall. default */
98b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    INTR_NEVER          = 3, /* block fatal signals. default if '-o FILE PROG' */
99b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */
100b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko    NUM_INTR_OPTS
101b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko};
102b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkostatic int opt_intr;
103b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* We play with signal mask only if this mode is active: */
104b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko#define interactive (opt_intr == INTR_WHILE_WAIT)
105b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko
106ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/*
107ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option.
108ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice.
109ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's,
110ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process
111ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild
112ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID.
113ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases
114ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals,
115ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between,
116ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link.
117ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */
118ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0;
11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1205c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE
12131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP;
12231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize (post_attach_sigstop == 0)
12331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else
12431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP
12531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize 0
12631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif
12731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
12817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */
129a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool not_failing_only = 0;
13017f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig
1318a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */
132a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool show_fd_path = 0;
1338a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards
13461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenkostatic bool detach_on_execve = 0;
1352a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko/* Are we "strace PROG" and need to skip detach on first execve? */
1362a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenkostatic bool skip_one_b_execve = 0;
1372a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko/* Are we "strace PROG" and need to hide everything until execve? */
1382a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenkobool hide_log_until_execve = 0;
13961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko
140a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0;
141a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0;
14275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0;
143eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath
144b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL;
145ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid;
146ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid;
14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
148a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int max_strlen = DEFAULT_STRLEN;
149ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinstatic int acolumn = DEFAULT_ACOLUMN;
150102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic char *acolumn_spaces;
1516764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko
152b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL;
1536764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko/* If -ff, points to stderr. Else, it's our common output log */
1546764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenkostatic FILE *shared_log;
1556764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko
156000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenkostruct tcb *printing_tcp = NULL;
1576764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenkostatic struct tcb *current_tcp;
1586764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko
159ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab;
1602b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize;
161ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname;
16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
163eec8d5d6b028665a73169fda96e4e873cb8351f0Denys Vlasenkounsigned os_release; /* generated from uname()'s u.release */
164f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
1654a9ba989e65c12c50286a8423196236e6bac529dDenys Vlasenkostatic void detach(struct tcb *tcp);
166e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void);
167e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig);
16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set;
16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T
17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted;
172a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#else
17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted;
174a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#endif
17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1762c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#ifndef HAVE_STRERROR
1772c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko
1782c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#if !HAVE_DECL_SYS_ERRLIST
1792c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern int sys_nerr;
1802c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern char *sys_errlist[];
181a6d91ded3f2d5401e09a9c2fa442aabfbfe593a8Denys Vlasenko#endif
1822c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko
1832c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoconst char *
1842c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkostrerror(int err_no)
1852c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko{
1862c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko	static char buf[sizeof("Unknown error %d") + sizeof(int)*3];
1872c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko
1882c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko	if (err_no < 1 || err_no >= sys_nerr) {
1892c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko		sprintf(buf, "Unknown error %d", err_no);
1902c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko		return buf;
1912c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko	}
1922c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko	return sys_errlist[err_no];
1932c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko}
1942c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko
1952c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#endif /* HAVE_STERRROR */
1962c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko
19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void
198cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval)
19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	fprintf(ofp, "\
201c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenkousage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\
202c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko              [-a column] [-o file] [-s strsize] [-P path]...\n\
203c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
204c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko   or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\
205c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko              -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\
20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\
207c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-C -- like -c but also print regular output\n\
208e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills-w -- summarise syscall latency (default is system time)\n\
2093e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-d -- enable debug output to stderr\n\
210b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\
21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\
21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\
21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\
21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\
215cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-T -- print time spent in each syscall\n\
216cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\
21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\
2188a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\
219c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-h -- print help message, -V -- print version\n\
22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\
22122efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko-b execve -- detach on this syscall\n\
22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\
22338e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko   options: trace, abbrev, verbose, raw, signal, read, write\n\
224c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-I interruptible --\n\
225c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko   1: no signals are blocked\n\
226c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko   2: fatal signals are blocked while decoding syscall (default)\n\
227c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko   3: fatal signals are always blocked (default if '-o FILE PROG')\n\
228c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko   4: fatal signals and SIGTSTP (^Z) are always blocked\n\
229c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko      (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\
23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\
23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\
23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\
23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\
23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\
23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\
236de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\
237de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\
2388a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\
23961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko"
240327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND
2412734a7010fb24dbcad3c55565d08c5c9b81f8624Dmitry V. Levin"-k obtain stack trace between each syscall (experimental)\n\
242327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi"
243327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif
24438e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko/* ancient, no one should use it
24538e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko-F -- attempt to follow vforks (deprecated, use -f)\n\
24638e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko */
24761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* this is broken, so don't document it
24817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\
24961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */
250de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY);
25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	exit(exitval);
25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn));
25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void)
25675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{
25775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	if (strace_tracer_pid == getpid()) {
25875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		cflag = 0;
25975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		cleanup();
26075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	}
26175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	exit(1);
26275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko}
26375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
26475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p)
2653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{
26682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	char *msg;
26782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko
26844d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin	fflush(NULL);
26982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko
27082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	/* We want to print entire message with single fprintf to ensure
27182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	 * message integrity if stderr is shared with other programs.
27282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	 * Thus we use vasprintf + single fprintf.
27382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	 */
27482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	msg = NULL;
275cfad543087d98c5313fd7f006c0de69a1d87dc8eDenys Vlasenko	if (vasprintf(&msg, fmt, p) >= 0) {
27682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		if (err_no)
27782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko			fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no));
27882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		else
27982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko			fprintf(stderr, "%s: %s\n", progname, msg);
28082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		free(msg);
28182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	} else {
28282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		/* malloc in vasprintf failed, try it without malloc */
28382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		fprintf(stderr, "%s: ", progname);
28482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		vfprintf(stderr, fmt, p);
28582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		if (err_no)
28682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko			fprintf(stderr, ": %s\n", strerror(err_no));
28782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko		else
28882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko			putc('\n', stderr);
28982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	}
29082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	/* We don't switch stderr to buffered, thus fprintf(stderr)
29182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	 * always flushes its output and this is not necessary: */
29282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko	/* fflush(stderr); */
29375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko}
29475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
29575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...)
29675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{
29775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_list p;
29875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_start(p, fmt);
29975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	verror_msg(0, fmt, p);
3003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	va_end(p);
30175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko}
3023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
30375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...)
30475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{
30575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_list p;
30675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_start(p, fmt);
30775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	verror_msg(0, fmt, p);
30875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	die();
30975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko}
31075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
31175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...)
31275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{
31375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_list p;
31475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_start(p, fmt);
31575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	verror_msg(errno, fmt, p);
31675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_end(p);
31775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko}
31875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
31975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...)
32075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{
32175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_list p;
32275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	va_start(p, fmt);
32375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	verror_msg(errno, fmt, p);
32475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	die();
3253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko}
3263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
3271d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void)
3281d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{
3291d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	static bool recursed = 0;
3301d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	if (recursed)
3311d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		exit(1);
3321d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	recursed = 1;
3331d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	error_msg_and_die("Out of memory");
3341d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko}
3351d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko
336ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinstatic void
337ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinerror_opt_arg(int opt, const char *arg)
338ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin{
339ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin	error_msg_and_die("Invalid -%c argument: '%s'", opt, arg);
340ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin}
341ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin
3425c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE
34331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int
34431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkoptrace_attach_or_seize(int pid)
34531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{
34631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	int r;
34731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	if (!use_seize)
348c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko		return ptrace(PTRACE_ATTACH, pid, 0L, 0L);
349c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko	r = ptrace(PTRACE_SEIZE, pid, 0L, (unsigned long)ptrace_setoptions);
35031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	if (r)
35131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		return r;
352c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko	r = ptrace(PTRACE_INTERRUPT, pid, 0L, 0L);
35331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	return r;
35431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko}
35531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else
35631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0)
35731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif
35831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
359852f98a3824f6b8359df744af5772306410341abDenys Vlasenko/*
360852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Used when we want to unblock stopped traced process.
361852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL.
362852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Returns 0 on success or if error was ESRCH
363852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * (presumably process was killed while we talk to it).
364852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Otherwise prints error message and returns -1.
365852f98a3824f6b8359df744af5772306410341abDenys Vlasenko */
366852f98a3824f6b8359df744af5772306410341abDenys Vlasenkostatic int
367852f98a3824f6b8359df744af5772306410341abDenys Vlasenkoptrace_restart(int op, struct tcb *tcp, int sig)
368852f98a3824f6b8359df744af5772306410341abDenys Vlasenko{
369852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	int err;
370852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	const char *msg;
371852f98a3824f6b8359df744af5772306410341abDenys Vlasenko
372852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	errno = 0;
373852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	ptrace(op, tcp->pid, (void *) 0, (long) sig);
374852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	err = errno;
375235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	if (!err)
376852f98a3824f6b8359df744af5772306410341abDenys Vlasenko		return 0;
377852f98a3824f6b8359df744af5772306410341abDenys Vlasenko
378852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	msg = "SYSCALL";
379852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	if (op == PTRACE_CONT)
380852f98a3824f6b8359df744af5772306410341abDenys Vlasenko		msg = "CONT";
381852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	if (op == PTRACE_DETACH)
382852f98a3824f6b8359df744af5772306410341abDenys Vlasenko		msg = "DETACH";
383852f98a3824f6b8359df744af5772306410341abDenys Vlasenko#ifdef PTRACE_LISTEN
384852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	if (op == PTRACE_LISTEN)
385852f98a3824f6b8359df744af5772306410341abDenys Vlasenko		msg = "LISTEN";
386852f98a3824f6b8359df744af5772306410341abDenys Vlasenko#endif
387235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	/*
388235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 * Why curcol != 0? Otherwise sometimes we get this:
389235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 *
390235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 * 10252 kill(10253, SIGKILL)              = 0
391235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 *  <ptrace(SYSCALL,10252):No such process>10253 ...next decode...
392235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 *
393235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 * 10252 died after we retrieved syscall exit data,
394235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 * but before we tried to restart it. Log looks ugly.
395235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	 */
3966764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp && current_tcp->curcol != 0) {
397235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko		tprintf(" <ptrace(%s):%s>\n", msg, strerror(err));
398235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko		line_ended();
399235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	}
400235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	if (err == ESRCH)
401235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko		return 0;
402235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko	errno = err;
403852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig);
404852f98a3824f6b8359df744af5772306410341abDenys Vlasenko	return -1;
405852f98a3824f6b8359df744af5772306410341abDenys Vlasenko}
406852f98a3824f6b8359df744af5772306410341abDenys Vlasenko
4071f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void
40810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd)
40910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{
4101f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko	int flags, newflags;
4111f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko
4121f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko	flags = fcntl(fd, F_GETFD);
4131f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko	if (flags < 0) {
4141f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		/* Can happen only if fd is bad.
4151f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		 * Should never happen: if it does, we have a bug
4161f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		 * in the caller. Therefore we just abort
4171f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		 * instead of propagating the error.
4181f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		 */
4191f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		perror_msg_and_die("fcntl(%d, F_GETFD)", fd);
42010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin	}
42110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
42210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin	newflags = flags | FD_CLOEXEC;
42310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin	if (flags == newflags)
4241f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko		return;
42510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
4261f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko	fcntl(fd, F_SETFD, newflags); /* never fails */
42710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin}
42810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
42975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenkostatic void kill_save_errno(pid_t pid, int sig)
43075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko{
43175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko	int saved_errno = errno;
43275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko
43375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko	(void) kill(pid, sig);
43475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko	errno = saved_errno;
43575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko}
43675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko
437800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko/*
438800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * When strace is setuid executable, we have to swap uids
439800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * before and after filesystem and process management operations.
440800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */
441800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void
442800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkoswap_uid(void)
443800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{
444800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	int euid = geteuid(), uid = getuid();
445800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
446800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (euid != uid && setreuid(euid, uid) < 0) {
447800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		perror_msg_and_die("setreuid");
448800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	}
449800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko}
450800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
4510506f0f430c15677c7724f9c4500093e0e7e15d3Dmitry V. Levin#ifdef _LARGEFILE64_SOURCE
452d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# ifdef HAVE_FOPEN64
453d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#  define fopen_for_output fopen64
454d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# else
455d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#  define fopen_for_output fopen
456d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# endif
457c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_stat struct stat64
458c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define stat_file stat64
459c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_dirent struct dirent64
460c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define read_dir readdir64
461c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_rlimit struct rlimit64
462c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define set_rlimit setrlimit64
463800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#else
464800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko# define fopen_for_output fopen
465c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_stat struct stat
466c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define stat_file stat
467c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_dirent struct dirent
468c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define read_dir readdir
469c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_rlimit struct rlimit
470c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define set_rlimit setrlimit
471800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif
472800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
473800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic FILE *
474800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostrace_fopen(const char *path)
475800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{
476800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	FILE *fp;
477800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
478800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	swap_uid();
479800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	fp = fopen_for_output(path, "w");
480800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (!fp)
481800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		perror_msg_and_die("Can't fopen '%s'", path);
482800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	swap_uid();
483800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	set_cloexec_flag(fileno(fp));
484800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	return fp;
485800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko}
486800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
487800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic int popen_pid = 0;
488800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
489800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#ifndef _PATH_BSHELL
490800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko# define _PATH_BSHELL "/bin/sh"
491800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif
492800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
493800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko/*
494800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * We cannot use standard popen(3) here because we have to distinguish
495800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * popen child process from other processes we trace, and standard popen(3)
496800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * does not export its child's pid.
497800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */
498800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic FILE *
499800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostrace_popen(const char *command)
500800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{
501800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	FILE *fp;
502519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko	int pid;
503800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	int fds[2];
504800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
505800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	swap_uid();
506800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (pipe(fds) < 0)
507800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		perror_msg_and_die("pipe");
508800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
509800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	set_cloexec_flag(fds[1]); /* never fails */
510800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
511519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko	pid = vfork();
512519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko	if (pid < 0)
513800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		perror_msg_and_die("vfork");
514800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
515519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko	if (pid == 0) {
516800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		/* child */
517800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		close(fds[1]);
518800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		if (fds[0] != 0) {
519800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			if (dup2(fds[0], 0))
520800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko				perror_msg_and_die("dup2");
521800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			close(fds[0]);
522800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		}
523800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		execl(_PATH_BSHELL, "sh", "-c", command, NULL);
524800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL);
525800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	}
526800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
527800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	/* parent */
528519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko	popen_pid = pid;
529800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	close(fds[0]);
530800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	swap_uid();
531800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	fp = fdopen(fds[1], "w");
532800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (!fp)
533800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		die_out_of_memory();
534800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	return fp;
535800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko}
536800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
5372e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid
5382e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprintf(const char *fmt, ...)
5392e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{
5402e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	va_list args;
5412e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
5422e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	va_start(args, fmt);
5436764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp) {
5446e4f3c1fa41851cb72230432db4be8e0c2993c7dDenys Vlasenko		int n = strace_vfprintf(current_tcp->outf, fmt, args);
5452e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		if (n < 0) {
5466764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			if (current_tcp->outf != stderr)
5479a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin				perror_msg("%s", outfname);
5482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		} else
5496764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			current_tcp->curcol += n;
5502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	}
5512e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	va_end(args);
5522e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko}
5532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
554d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#ifndef HAVE_FPUTS_UNLOCKED
555d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# define fputs_unlocked fputs
556d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#endif
557d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin
5582e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid
5592e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprints(const char *str)
5602e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{
5616764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp) {
562142aee0a593ea9b42aa98347d998176b8a4e2489Denys Vlasenko		int n = fputs_unlocked(str, current_tcp->outf);
5632e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		if (n >= 0) {
5646764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			current_tcp->curcol += strlen(str);
5652e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			return;
5662e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		}
5676764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		if (current_tcp->outf != stderr)
5689a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin			perror_msg("%s", outfname);
5692e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	}
5702e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko}
5712e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
5722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid
5737de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkoline_ended(void)
5747de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko{
5756764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp) {
5766764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		current_tcp->curcol = 0;
5776764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		fflush(current_tcp->outf);
5786764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	}
5796764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (printing_tcp) {
5806764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		printing_tcp->curcol = 0;
5816764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		printing_tcp = NULL;
5826764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	}
5837de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko}
5847de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko
5857de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkovoid
5862e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkoprintleader(struct tcb *tcp)
5872e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{
5887de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko	/* If -ff, "previous tcb we printed" is always the same as current,
5897de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko	 * because we have per-tcb output files.
5907de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko	 */
5917de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko	if (followfork >= 2)
5927de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko		printing_tcp = tcp;
5937de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko
5942e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	if (printing_tcp) {
5956764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		current_tcp = printing_tcp;
5967de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko		if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) {
5977de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			/*
5987de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 * case 1: we have a shared log (i.e. not -ff), and last line
5997de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 * wasn't finished (same or different tcb, doesn't matter).
6007de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 * case 2: split log, we are the same tcb, but our last line
6017de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 * didn't finish ("SIGKILL nuked us after syscall entry" etc).
6027de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 */
6032e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			tprints(" <unfinished ...>\n");
6047de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			printing_tcp->curcol = 0;
6052e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		}
6062e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	}
6072e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6082e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	printing_tcp = tcp;
6096764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	current_tcp = tcp;
6106764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	current_tcp->curcol = 0;
6112e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6122e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	if (print_pid_pfx)
6132e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		tprintf("%-5d ", tcp->pid);
6142e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	else if (nprocs > 1 && !outfname)
6152e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		tprintf("[pid %5u] ", tcp->pid);
6162e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6172e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	if (tflag) {
6182e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		char str[sizeof("HH:MM:SS")];
6192e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		struct timeval tv, dtv;
6202e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		static struct timeval otv;
6212e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6222e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		gettimeofday(&tv, NULL);
6232e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		if (rflag) {
6242e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			if (otv.tv_sec == 0)
6252e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko				otv = tv;
6262e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			tv_sub(&dtv, &tv, &otv);
6272e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			tprintf("%6ld.%06ld ",
6282e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko				(long) dtv.tv_sec, (long) dtv.tv_usec);
6292e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			otv = tv;
6302e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		}
6312e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		else if (tflag > 2) {
6322e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			tprintf("%ld.%06ld ",
6332e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko				(long) tv.tv_sec, (long) tv.tv_usec);
6342e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		}
6352e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		else {
6362e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			time_t local = tv.tv_sec;
6372e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			strftime(str, sizeof(str), "%T", localtime(&local));
6382e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			if (tflag > 1)
6392e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko				tprintf("%s.%06ld ", str, (long) tv.tv_usec);
6402e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko			else
6412e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko				tprintf("%s ", str);
6422e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko		}
6432e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	}
6442e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko	if (iflag)
6455a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko		print_pc(tcp);
6462e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko}
6472e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid
6492e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotabto(void)
6502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{
6516764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp->curcol < acolumn)
6526764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		tprints(acolumn_spaces + current_tcp->curcol);
6532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko}
6542e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko
6553db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko/* Should be only called directly *after successful attach* to a tracee.
6563db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>"
6573db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko * may create bogus empty FILE.<nonexistant_pid>, and then die.
6583db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko */
65910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void
660800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkonewoutf(struct tcb *tcp)
66110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{
6626764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	tcp->outf = shared_log; /* if not -ff mode, the same file is for all */
6633db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko	if (followfork >= 2) {
664800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		char name[520 + sizeof(int) * 3];
665800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		sprintf(name, "%.512s.%u", outfname, tcp->pid);
666800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		tcp->outf = strace_fopen(name);
66710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin	}
66810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin}
66910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
670800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void
671800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkoexpand_tcbtab(void)
672800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{
673800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	/* Allocate some more TCBs and expand the table.
674800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	   We don't want to relocate the TCBs because our
675800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	   callers have pointers and it would be a pain.
676800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	   So tcbtab is a table of pointers.  Since we never
677800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	   free the TCBs, we allocate a single chunk of many.  */
678800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	int i = tcbtabsize;
679800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0]));
680800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0]));
681800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (!newtab || !newtcbs)
682800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		die_out_of_memory();
683800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	tcbtabsize *= 2;
684800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	tcbtab = newtab;
685800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	while (i < tcbtabsize)
686800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		tcbtab[i++] = newtcbs++;
687800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko}
6884bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath
689800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic struct tcb *
6903db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenkoalloctcb(int pid)
69110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{
692800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	int i;
693800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	struct tcb *tcp;
69410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
695800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (nprocs == tcbtabsize)
696800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		expand_tcbtab();
697800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
698800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	for (i = 0; i < tcbtabsize; i++) {
699800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		tcp = tcbtab[i];
700fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko		if (!tcp->pid) {
701800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			memset(tcp, 0, sizeof(*tcp));
702800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			tcp->pid = pid;
703800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1
704800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			tcp->currpers = current_personality;
705800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif
706327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi
707327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND
708327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi			if (stack_trace_enabled)
7096141392856a170c9297783e6bfbd9fd970f76fdfMasatake YAMATO				unwind_tcb_init(tcp);
710327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif
711327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi
712800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			nprocs++;
713800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			if (debug_flag)
714800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko				fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs);
715800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			return tcp;
716800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		}
717800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	}
7183db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko	error_msg_and_die("bug in alloctcb");
71910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin}
72010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
721800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void
722800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkodroptcb(struct tcb *tcp)
723800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{
724800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (tcp->pid == 0)
725800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		return;
72610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
7272b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO#ifdef USE_LIBUNWIND
7282b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO	if (stack_trace_enabled) {
7292b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO		unwind_tcb_fin(tcp);
7302b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO	}
7312b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO#endif
7322b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO
733800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	nprocs--;
734800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (debug_flag)
735800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs);
73610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
737800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (tcp->outf) {
7388511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko		if (followfork >= 2) {
739800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			if (tcp->curcol != 0)
740800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko				fprintf(tcp->outf, " <detached ...>\n");
741800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			fclose(tcp->outf);
742800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		} else {
743800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			if (printing_tcp == tcp && tcp->curcol != 0)
744800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko				fprintf(tcp->outf, " <detached ...>\n");
745800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko			fflush(tcp->outf);
746800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		}
747800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	}
748800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
7496764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	if (current_tcp == tcp)
7506764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		current_tcp = NULL;
751800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (printing_tcp == tcp)
752800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		printing_tcp = NULL;
753800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
754800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	memset(tcp, 0, sizeof(*tcp));
755800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko}
756800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko
757f1669e7975cb8d67448d52d9ae7dde3301d27273Denys Vlasenko/* Detach traced process.
758800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * Never call DETACH twice on the same process as both unattached and
759800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * attached-unstopped processes give the same ESRCH.  For unattached process we
760800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * would SIGSTOP it and wait for its SIGSTOP notification forever.
76110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */
7624a9ba989e65c12c50286a8423196236e6bac529dDenys Vlasenkostatic void
763800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkodetach(struct tcb *tcp)
76410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{
765800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	int error;
766e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	int status;
76710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
768800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (tcp->flags & TCB_BPTSET)
769800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		clearbpt(tcp);
77010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
771800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	/*
772800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	 * Linux wrongly insists the child be stopped
773800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	 * before detaching.  Arghh.  We go through hoops
774800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	 * to make a clean break of things.
775800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	 */
776800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#if defined(SPARC)
777978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# undef PTRACE_DETACH
778978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# define PTRACE_DETACH PTRACE_SUNDETACH
779800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif
78010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
781e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (!(tcp->flags & TCB_ATTACHED))
782e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		goto drop;
783e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko
784e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	/* We attached but possibly didn't see the expected SIGSTOP.
785e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 * We must catch exactly one as otherwise the detached process
786e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 * would be left stopped (process state T).
787e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 */
788e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)
789e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		goto wait_loop;
790e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko
791e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	error = ptrace(PTRACE_DETACH, tcp->pid, 0, 0);
792e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (!error) {
793e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* On a clear day, you can see forever. */
794e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		goto drop;
795e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	}
796e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (errno != ESRCH) {
797e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* Shouldn't happen. */
798e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		perror_msg("detach: ptrace(PTRACE_DETACH,%u)", tcp->pid);
799e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		goto drop;
800e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	}
801e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	/* ESRCH: process is either not stopped or doesn't exist. */
802e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (my_tkill(tcp->pid, 0) < 0) {
803e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (errno != ESRCH)
804e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/* Shouldn't happen. */
805e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			perror_msg("detach: tkill(%u,0)", tcp->pid);
806e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* else: process doesn't exist. */
807e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		goto drop;
808e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	}
809e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	/* Process is not stopped, need to stop it. */
810e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	if (use_seize) {
811800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		/*
812e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		 * With SEIZE, tracee can be in group-stop already.
813e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		 * In this state sending it another SIGSTOP does nothing.
814e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		 * Need to use INTERRUPT.
815e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		 * Testcase: trying to ^C a "strace -p <stopped_process>".
816800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		 */
817e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		error = ptrace(PTRACE_INTERRUPT, tcp->pid, 0, 0);
818e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (!error)
819a2de9dacec47b7902b19f37edcc564faff346816Denys Vlasenko			goto wait_loop;
820e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (errno != ESRCH)
821e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			perror_msg("detach: ptrace(PTRACE_INTERRUPT,%u)", tcp->pid);
822800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	}
823e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	else {
824e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		error = my_tkill(tcp->pid, SIGSTOP);
825e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (!error)
826e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			goto wait_loop;
827e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (errno != ESRCH)
828e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			perror_msg("detach: tkill(%u,SIGSTOP)", tcp->pid);
829e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	}
830e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	/* Either process doesn't exist, or some weird error. */
831e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	goto drop;
83210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
833a2de9dacec47b7902b19f37edcc564faff346816Denys Vlasenko wait_loop:
834e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	/* We end up here in three cases:
835e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 * 1. We sent PTRACE_INTERRUPT (use_seize case)
836e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 * 2. We sent SIGSTOP (!use_seize)
837e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 * 3. Attach SIGSTOP was already pending (TCB_IGNORE_ONE_SIGSTOP set)
838e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	 */
839e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko	for (;;) {
840e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		int sig;
841e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (waitpid(tcp->pid, &status, __WALL) < 0) {
842e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			if (errno == EINTR)
843e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				continue;
844e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/*
845e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * if (errno == ECHILD) break;
846e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * ^^^  WRONG! We expect this PID to exist,
847e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * and want to emit a message otherwise:
848e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 */
849e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			perror_msg("detach: waitpid(%u)", tcp->pid);
850e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			break;
851e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		}
852e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (!WIFSTOPPED(status)) {
853e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/*
854e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * Tracee exited or was killed by signal.
855e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * We shouldn't normally reach this place:
856e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * we don't want to consume exit status.
857e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * Consider "strace -p PID" being ^C-ed:
858e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * we want merely to detach from PID.
859e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 *
860e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * However, we _can_ end up here if tracee
861e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * was SIGKILLed.
862e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 */
863e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			break;
864e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		}
865e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		sig = WSTOPSIG(status);
866e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (debug_flag)
867e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			fprintf(stderr, "detach wait: event:%d sig:%d\n",
868e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko					(unsigned)status >> 16, sig);
869e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (use_seize) {
870e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			unsigned event = (unsigned)status >> 16;
871e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			if (event == PTRACE_EVENT_STOP /*&& sig == SIGTRAP*/) {
87269e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko				/*
873e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				 * sig == SIGTRAP: PTRACE_INTERRUPT stop.
874e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				 * sig == other: process was already stopped
875e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				 * with this stopping sig (see tests/detach-stopped).
876e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				 * Looks like re-injecting this sig is not necessary
877e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				 * in DETACH for the tracee to remain stopped.
87869e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko				 */
879e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko				sig = 0;
88069e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko			}
881e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/*
882e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * PTRACE_INTERRUPT is not guaranteed to produce
883e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * the above event if other ptrace-stop is pending.
884e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * See tests/detach-sleeping testcase:
885e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * strace got SIGINT while tracee is sleeping.
886e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * We sent PTRACE_INTERRUPT.
887e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * We see syscall exit, not PTRACE_INTERRUPT stop.
888e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * We won't get PTRACE_INTERRUPT stop
889e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * if we would CONT now. Need to DETACH.
890e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 */
89169e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko			if (sig == syscall_trap_sig)
89269e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko				sig = 0;
893e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/* else: not sure in which case we can be here.
894e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * Signal stop? Inject it while detaching.
895e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 */
896e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			ptrace_restart(PTRACE_DETACH, tcp, sig);
897e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			break;
898e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		}
899e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* Note: this check has to be after use_seize check */
900e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* (else, in use_seize case SIGSTOP will be mistreated) */
901e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (sig == SIGSTOP) {
902e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/* Detach, suppressing SIGSTOP */
903e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			ptrace_restart(PTRACE_DETACH, tcp, 0);
904e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			break;
905e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		}
906e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (sig == syscall_trap_sig)
907e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			sig = 0;
908e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		/* Can't detach just yet, may need to wait for SIGSTOP */
909e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		error = ptrace_restart(PTRACE_CONT, tcp, sig);
910e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko		if (error < 0) {
911e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			/* Should not happen.
912e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * Note: ptrace_restart returns 0 on ESRCH, so it's not it.
913e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 * ptrace_restart already emitted error message.
914e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			 */
915e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko			break;
91610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin		}
91710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin	}
9187dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko
919e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko drop:
920800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	if (!qflag && (tcp->flags & TCB_ATTACHED))
921800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko		fprintf(stderr, "Process %u detached\n", tcp->pid);
92210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
923800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko	droptcb(tcp);
92410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin}
92510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin
926558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkostatic void
927558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkoprocess_opt_p_list(char *opt)
928e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko{
929e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko	while (*opt) {
930e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		/*
931e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		 * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`".
932e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		 * pidof uses space as delim, pgrep uses newline. :(
933e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		 */
934e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		int pid;
935e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		char *delim = opt + strcspn(opt, ", \n\t");
936e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		char c = *delim;
937e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko
938e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		*delim = '\0';
939ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin		pid = string_to_uint(opt);
940e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		if (pid <= 0) {
941ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			error_msg_and_die("Invalid process id: '%s'", opt);
942e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		}
943e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		if (pid == strace_tracer_pid) {
944ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			error_msg_and_die("I'm sorry, I can't let you do that, Dave.");
945e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		}
946e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		*delim = c;
9473db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		alloctcb(pid);
948e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		if (c == '\0')
949e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko			break;
950e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko		opt = delim + 1;
951e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko	}
952e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko}
953e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko
95402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void
95502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void)
95602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{
95702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	int tcbi;
95802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	struct tcb *tcp;
95902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
96002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	/*
96102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 * Block user interruptions as we would leave the traced
96202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 * process stopped (process state T) if we would terminate in
9632e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko	 * between PTRACE_ATTACH and wait4() on SIGSTOP.
964b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko	 * We rely on cleanup() from this point on.
96502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 */
96602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	if (interactive)
96702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		sigprocmask(SIG_BLOCK, &blocked_set, NULL);
96802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
969ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	if (daemonized_tracer) {
970ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		pid_t pid = fork();
971ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		if (pid < 0) {
972014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko			perror_msg_and_die("fork");
973ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		}
974ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		if (pid) { /* parent */
975ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			/*
97675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			 * Wait for grandchild to attach to straced process
97775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			 * (grandparent). Grandchild SIGKILLs us after it attached.
97875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			 * Grandparent's wait() is unblocked by our death,
979ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			 * it proceeds to exec the straced program.
980ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			 */
981ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			pause();
982ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			_exit(0); /* paranoia */
983ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		}
98475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		/* grandchild */
98575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		/* We will be the tracer process. Remember our new pid: */
98675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		strace_tracer_pid = getpid();
987ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	}
988ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko
98902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	for (tcbi = 0; tcbi < tcbtabsize; tcbi++) {
99002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		tcp = tcbtab[tcbi];
99144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko
992fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko		if (!tcp->pid)
99375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko			continue;
99475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko
995d116a7338645af45090aecc331701e999148d284Denys Vlasenko		/* Is this a process we should attach to, but not yet attached? */
99675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko		if (tcp->flags & TCB_ATTACHED)
99775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko			continue; /* no, we already attached it */
998d116a7338645af45090aecc331701e999148d284Denys Vlasenko
999ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		if (followfork && !daemonized_tracer) {
10007a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko			char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
100102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			DIR *dir;
100202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
100302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			sprintf(procdir, "/proc/%d/task", tcp->pid);
100402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			dir = opendir(procdir);
100502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			if (dir != NULL) {
100602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				unsigned int ntid = 0, nerr = 0;
1007c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin				struct_dirent *de;
1008381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko
1009c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin				while ((de = read_dir(dir)) != NULL) {
1010381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					struct tcb *cur_tcp;
1011381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					int tid;
1012381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko
10137a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko					if (de->d_fileno == 0)
101402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath						continue;
1015ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin					/* we trust /proc filesystem */
101602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					tid = atoi(de->d_name);
101702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					if (tid <= 0)
101802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath						continue;
101902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					++ntid;
102031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					if (ptrace_attach_or_seize(tid) < 0) {
102102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath						++nerr;
1022a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko						if (debug_flag)
1023f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko							fprintf(stderr, "attach to pid %d failed\n", tid);
1024381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko						continue;
1025f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko					}
1026a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko					if (debug_flag)
1027381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko						fprintf(stderr, "attach to pid %d succeeded\n", tid);
1028381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					cur_tcp = tcp;
1029381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					if (tid != tcp->pid)
1030381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko						cur_tcp = alloctcb(tid);
103131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
10323db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko					newoutf(cur_tcp);
103302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				}
103402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				closedir(dir);
1035381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko				if (interactive) {
1036381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					sigprocmask(SIG_SETMASK, &empty_set, NULL);
1037381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					if (interrupted)
1038381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko						goto ret;
1039381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko					sigprocmask(SIG_BLOCK, &blocked_set, NULL);
1040381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko				}
10417a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko				ntid -= nerr;
10427a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko				if (ntid == 0) {
1043905e8e0e2f0a1f51ab92424dcb005885ea8b2459Denys Vlasenko					perror_msg("attach: ptrace(PTRACE_ATTACH, ...)");
104402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					droptcb(tcp);
104502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					continue;
104602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				}
104702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				if (!qflag) {
10487a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko					fprintf(stderr, ntid > 1
10493db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko? "Process %u attached with %u threads\n"
10503db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko: "Process %u attached\n",
105144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko						tcp->pid, ntid);
105202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				}
105375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko				if (!(tcp->flags & TCB_ATTACHED)) {
1054f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko					/* -p PID, we failed to attach to PID itself
1055f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko					 * but did attach to some of its sibling threads.
1056f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko					 * Drop PID's tcp.
1057f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko					 */
1058f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko					droptcb(tcp);
1059f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko				}
106002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				continue;
10617a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko			} /* if (opendir worked) */
10627a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko		} /* if (-f) */
106331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		if (ptrace_attach_or_seize(tcp->pid) < 0) {
1064905e8e0e2f0a1f51ab92424dcb005885ea8b2459Denys Vlasenko			perror_msg("attach: ptrace(PTRACE_ATTACH, ...)");
106502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			droptcb(tcp);
106602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			continue;
106702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		}
106875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko		tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
10693db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		newoutf(tcp);
1070a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko		if (debug_flag)
1071f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko			fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid);
1072ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko
1073ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		if (daemonized_tracer) {
1074ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			/*
1075ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			 * Make parent go away.
1076ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			 * Also makes grandparent's wait() unblock.
1077ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			 */
1078ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			kill(getppid(), SIGKILL);
1079ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		}
1080ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko
108102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		if (!qflag)
108202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			fprintf(stderr,
10839c3861d3177f3bfb12b24890fd118bcb77066abbDenys Vlasenko				"Process %u attached\n",
108402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				tcp->pid);
1085f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko	} /* for each tcbtab[] */
108602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
108744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret:
108802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	if (interactive)
108902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		sigprocmask(SIG_SETMASK, &empty_set, NULL);
109002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath}
109102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
1092f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko/* Stack-o-phobic exec helper, in the hope to work around
1093f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * NOMMU + "daemonized tracer" difficulty.
1094f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */
1095f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostruct exec_params {
1096f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	int fd_to_close;
1097f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	uid_t run_euid;
1098f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	gid_t run_egid;
1099f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	char **argv;
1100f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	char *pathname;
1101f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko};
1102f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostatic struct exec_params params_for_tracee;
1103f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostatic void __attribute__ ((noinline, noreturn))
1104f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkoexec_or_die(void)
1105f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko{
1106f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	struct exec_params *params = &params_for_tracee;
1107f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1108f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	if (params->fd_to_close >= 0)
1109f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		close(params->fd_to_close);
1110f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	if (!daemonized_tracer && !use_seize) {
1111f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) {
1112f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)");
1113f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		}
1114f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	}
1115f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1116f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	if (username != NULL) {
1117f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/*
1118f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * It is important to set groups before we
1119f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * lose privileges on setuid.
1120f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 */
1121f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (initgroups(username, run_gid) < 0) {
1122f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			perror_msg_and_die("initgroups");
1123f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		}
1124f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (setregid(run_gid, params->run_egid) < 0) {
1125f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			perror_msg_and_die("setregid");
1126f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		}
1127f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (setreuid(run_uid, params->run_euid) < 0) {
1128f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			perror_msg_and_die("setreuid");
1129f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		}
1130f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	}
1131f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	else if (geteuid() != 0)
1132f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (setreuid(run_uid, run_uid) < 0) {
1133f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			perror_msg_and_die("setreuid");
1134f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		}
1135f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1136f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	if (!daemonized_tracer) {
1137f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/*
1138f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * Induce a ptrace stop. Tracer (our parent)
1139f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * will resume us with PTRACE_SYSCALL and display
1140f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * the immediately following execve syscall.
1141f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * Can't do this on NOMMU systems, we are after
1142f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * vfork: parent is blocked, stopping would deadlock.
1143f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 */
1144f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		if (!NOMMU_SYSTEM)
1145f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko			kill(getpid(), SIGSTOP);
1146f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	} else {
1147f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		alarm(3);
1148f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/* we depend on SIGCHLD set to SIG_DFL by init code */
1149f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/* if it happens to be SIG_IGN'ed, wait won't block */
1150f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		wait(NULL);
1151f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		alarm(0);
1152f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	}
1153f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1154f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	execv(params->pathname, params->argv);
1155f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	perror_msg_and_die("exec");
1156f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko}
1157f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
115802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void
11591201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv)
116002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{
1161c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin	struct_stat statbuf;
116202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	const char *filename;
116302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	char pathname[MAXPATHLEN];
1164f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	int pid;
116502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	struct tcb *tcp;
116602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
116702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	filename = argv[0];
116802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	if (strchr(filename, '/')) {
116902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		if (strlen(filename) > sizeof pathname - 1) {
117002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			errno = ENAMETOOLONG;
1171cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko			perror_msg_and_die("exec");
117202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		}
117302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		strcpy(pathname, filename);
117402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	}
117502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC
117602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	/*
117702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 * Debuggers customarily check the current directory
117802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 * first regardless of the path but doing that gives
117902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 * security geeks a panic attack.
118002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	 */
1181c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin	else if (stat_file(filename, &statbuf) == 0)
118202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		strcpy(pathname, filename);
118302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */
118402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	else {
118530145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin		const char *path;
118602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		int m, n, len;
118702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
118802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		for (path = getenv("PATH"); path && *path; path += m) {
11894f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko			const char *colon = strchr(path, ':');
11904f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko			if (colon) {
11914f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko				n = colon - path;
119202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				m = n + 1;
119302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			}
119402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			else
119502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				m = n = strlen(path);
119602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			if (n == 0) {
119702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				if (!getcwd(pathname, MAXPATHLEN))
119802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath					continue;
119902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				len = strlen(pathname);
120002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			}
120102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			else if (n > sizeof pathname - 1)
120202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				continue;
120302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			else {
120402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				strncpy(pathname, path, n);
120502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				len = n;
120602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			}
120702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			if (len && pathname[len - 1] != '/')
120802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				pathname[len++] = '/';
120902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			strcpy(pathname + len, filename);
1210c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin			if (stat_file(pathname, &statbuf) == 0 &&
121102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			    /* Accept only regular files
121202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			       with some execute bits set.
121302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			       XXX not perfect, might still fail */
121402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			    S_ISREG(statbuf.st_mode) &&
121502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			    (statbuf.st_mode & 0111))
121602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				break;
121702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		}
121802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	}
1219c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin	if (stat_file(pathname, &statbuf) < 0) {
1220cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko		perror_msg_and_die("Can't stat '%s'", filename);
122102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	}
1222f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1223f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	params_for_tracee.fd_to_close = (shared_log != stderr) ? fileno(shared_log) : -1;
1224f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	params_for_tracee.run_euid = (statbuf.st_mode & S_ISUID) ? statbuf.st_uid : run_uid;
1225f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	params_for_tracee.run_egid = (statbuf.st_mode & S_ISGID) ? statbuf.st_gid : run_gid;
1226f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	params_for_tracee.argv = argv;
1227f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	/*
1228f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 * On NOMMU, can be safely freed only after execve in tracee.
1229f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 * It's hard to know when that happens, so we just leak it.
1230f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 */
123105f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko	params_for_tracee.pathname = NOMMU_SYSTEM ? strdup(pathname) : pathname;
1232f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko
1233882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#if defined HAVE_PRCTL && defined PR_SET_PTRACER && defined PR_SET_PTRACER_ANY
1234882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin	if (daemonized_tracer)
1235882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin		prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
1236882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#endif
1237882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin
1238e8681c926c02dad48aca66f3aba1e33122002c36Denys Vlasenko	pid = fork();
1239ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	if (pid < 0) {
1240cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko		perror_msg_and_die("fork");
1241ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	}
1242f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	if ((pid != 0 && daemonized_tracer)
1243f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 || (pid == 0 && !daemonized_tracer)
1244ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	) {
1245f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/* We are to become the tracee. Two cases:
1246f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * -D: we are parent
1247f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * not -D: we are child
1248f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 */
1249f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		exec_or_die();
125002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath	}
1251ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko
12522e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko	/* We are the tracer */
125375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
12542e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko	if (!daemonized_tracer) {
1255e8681c926c02dad48aca66f3aba1e33122002c36Denys Vlasenko		strace_child = pid;
125631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		if (!use_seize) {
125731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			/* child did PTRACE_TRACEME, nothing to do in parent */
125831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		} else {
12595c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko			if (!NOMMU_SYSTEM) {
126031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				/* Wait until child stopped itself */
126131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				int status;
126231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				while (waitpid(pid, &status, WSTOPPED) < 0) {
126331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					if (errno == EINTR)
126431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko						continue;
126531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					perror_msg_and_die("waitpid");
126631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				}
126731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
126875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko					kill_save_errno(pid, SIGKILL);
126931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					perror_msg_and_die("Unexpected wait status %x", status);
127031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				}
127131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			}
12725c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko			/* Else: NOMMU case, we have no way to sync.
127331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			 * Just attach to it as soon as possible.
127431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			 * This means that we may miss a few first syscalls...
127531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			 */
127631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
127731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			if (ptrace_attach_or_seize(pid)) {
127875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko				kill_save_errno(pid, SIGKILL);
127931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				perror_msg_and_die("Can't attach to %d", pid);
128031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			}
12815c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko			if (!NOMMU_SYSTEM)
128231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				kill(pid, SIGCONT);
128331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		}
12842e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko		tcp = alloctcb(pid);
12855c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko		if (!NOMMU_SYSTEM)
1286fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko			tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
1287f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		else
1288fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko			tcp->flags |= TCB_ATTACHED | TCB_STARTUP;
12893db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		newoutf(tcp);
12902e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko	}
12912e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko	else {
129205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		/* With -D, we are *child* here, IOW: different pid. Fetch it: */
12932e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko		strace_tracer_pid = getpid();
12942e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko		/* The tracee is our parent: */
12952e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko		pid = getppid();
1296f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko		alloctcb(pid);
1297f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko		/* attaching will be done later, by startup_attach */
12983db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		/* note: we don't do newoutf(tcp) here either! */
12995c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko
1300f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		/* NOMMU BUG! -D mode is active, we (child) return,
1301f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * and we will scribble over parent's stack!
1302f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * When parent later unpauses, it segfaults.
1303f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 *
1304f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * We work around it
1305f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * (1) by declaring exec_or_die() NORETURN,
1306f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * hopefully compiler will just jump to it
1307f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * instead of call (won't push anything to stack),
1308f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * (2) by trying very hard in exec_or_die()
1309f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * to not use any stack,
1310f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * (3) having a really big (MAXPATHLEN) stack object
1311f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * in this function, which creates a "buffer" between
1312f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * child's and parent's stack pointers.
1313f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * This may save us if (1) and (2) failed
1314f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * and compiler decided to use stack in exec_or_die() anyway
1315f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 * (happens on i386 because of stack parameter passing).
131605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		 *
131705f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		 * A cleaner solution is to use makecontext + setcontext
131805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		 * to create a genuine separate stack and execute on it.
1319f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko		 */
1320ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko	}
132102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath}
132202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
1323b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/*
1324b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options.
1325b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it,
1326b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel.
1327b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */
13288d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkostatic int
13293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void)
1330b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{
13312fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin	int pid, expected_grandchild = 0, found_grandchild = 0;
13322fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin	const unsigned int test_options = PTRACE_O_TRACECLONE |
13332fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin					  PTRACE_O_TRACEFORK |
13342fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin					  PTRACE_O_TRACEVFORK;
1335b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao
133605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko	/* Need fork for test. NOMMU has no forks */
133705f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko	if (NOMMU_SYSTEM)
133805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		goto worked; /* be bold, and pretend that test succeeded */
133905f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko
13405d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko	pid = fork();
13415d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko	if (pid < 0)
134204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		perror_msg_and_die("fork");
13435d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko	if (pid == 0) {
134404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		pid = getpid();
134531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
134604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
134704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					   __func__);
13484c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko		kill_save_errno(pid, SIGSTOP);
134904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (fork() < 0)
135004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("fork");
135104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		_exit(0);
1352b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao	}
1353b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin
1354b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin	while (1) {
1355b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin		int status, tracee_pid;
1356b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin
135704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		errno = 0;
1358b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin		tracee_pid = wait(&status);
135904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (tracee_pid <= 0) {
1360b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin			if (errno == EINTR)
1361b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin				continue;
13624c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko			if (errno == ECHILD)
1363b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao				break;
136404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			kill_save_errno(pid, SIGKILL);
136504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("%s: unexpected wait result %d",
136604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					   __func__, tracee_pid);
136704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		}
136804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (WIFEXITED(status)) {
136904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (WEXITSTATUS(status)) {
137004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				if (tracee_pid != pid)
137104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					kill_save_errno(pid, SIGKILL);
137204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				error_msg_and_die("%s: unexpected exit status %u",
137304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin						  __func__, WEXITSTATUS(status));
137404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			}
137504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			continue;
137604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		}
137704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (WIFSIGNALED(status)) {
137804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (tracee_pid != pid)
137904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				kill_save_errno(pid, SIGKILL);
138004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			error_msg_and_die("%s: unexpected signal %u",
138104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  __func__, WTERMSIG(status));
138204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		}
138304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (!WIFSTOPPED(status)) {
138404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (tracee_pid != pid)
138504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				kill_save_errno(tracee_pid, SIGKILL);
13864c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko			kill_save_errno(pid, SIGKILL);
138704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			error_msg_and_die("%s: unexpected wait status %x",
138804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  __func__, status);
1389b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin		}
1390b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin		if (tracee_pid != pid) {
13912fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin			found_grandchild = tracee_pid;
139204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) {
139304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				kill_save_errno(tracee_pid, SIGKILL);
139404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				kill_save_errno(pid, SIGKILL);
139504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				perror_msg_and_die("PTRACE_CONT doesn't work");
139604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			}
139704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			continue;
1398b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin		}
139904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		switch (WSTOPSIG(status)) {
140004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		case SIGSTOP:
140104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0
140204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			    && errno != EINVAL && errno != EIO)
140304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				perror_msg("PTRACE_SETOPTIONS");
140404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			break;
140504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		case SIGTRAP:
140604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (status >> 16 == PTRACE_EVENT_FORK) {
140704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				long msg = 0;
14082fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin
140904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				if (ptrace(PTRACE_GETEVENTMSG, pid,
141004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					   NULL, (long) &msg) == 0)
141104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					expected_grandchild = msg;
1412b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao			}
141304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			break;
141404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		}
141504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) {
141604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			kill_save_errno(pid, SIGKILL);
141704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("PTRACE_SYSCALL doesn't work");
1418b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao		}
1419b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao	}
142004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	if (expected_grandchild && expected_grandchild == found_grandchild) {
142105f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko worked:
1422f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko		ptrace_setoptions |= test_options;
1423a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko		if (debug_flag)
142404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			fprintf(stderr, "ptrace_setoptions = %#x\n",
142504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				ptrace_setoptions);
14268d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko		return 0;
142704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	}
142804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	error_msg("Test for PTRACE_O_TRACECLONE failed, "
142904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		  "giving up using this feature.");
14308d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	return 1;
1431b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao}
14323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
14333454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/*
14343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD.
14353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it,
14363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80).
14373454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko *
14383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs,
14393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86:
1440329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko
1441329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko# compile with: gcc -nostartfiles -nostdlib -o int3 int3.S
1442329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko_start:		.globl	_start
1443329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko		int3
1444329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko		movl	$42, %ebx
1445329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko		movl	$1, %eax
1446329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko		int	$0x80
14473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */
14488d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkostatic int
14493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void)
14503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{
145104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	const unsigned int test_options = PTRACE_O_TRACESYSGOOD |
145204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  PTRACE_O_TRACEEXEC;
14533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	int pid;
14543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	int it_worked = 0;
14553454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
145605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko	/* Need fork for test. NOMMU has no forks */
14575c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko	if (NOMMU_SYSTEM)
145805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko		goto worked; /* be bold, and pretend that test succeeded */
14597ff5ed932568a8049c3ca134da374f64c3e255ceMike Frysinger
14603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	pid = fork();
14613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	if (pid < 0)
146275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		perror_msg_and_die("fork");
14633454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
14643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	if (pid == 0) {
14653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		pid = getpid();
14663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0)
146775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			/* Note: exits with exitcode 1 */
146804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("%s: PTRACE_TRACEME doesn't work",
146904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					   __func__);
14703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		kill(pid, SIGSTOP);
14713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		_exit(0); /* parent should see entry into this syscall */
14723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	}
14733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
14743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	while (1) {
14753454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		int status, tracee_pid;
14763454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
14773454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		errno = 0;
14783454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		tracee_pid = wait(&status);
14793454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (tracee_pid <= 0) {
14803454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			if (errno == EINTR)
14813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko				continue;
148204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			kill_save_errno(pid, SIGKILL);
148304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			perror_msg_and_die("%s: unexpected wait result %d",
148404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					   __func__, tracee_pid);
148575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		}
148675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		if (WIFEXITED(status)) {
148775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			if (WEXITSTATUS(status) == 0)
148875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko				break;
148904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			error_msg_and_die("%s: unexpected exit status %u",
149004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  __func__, WEXITSTATUS(status));
149104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		}
149204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		if (WIFSIGNALED(status)) {
149304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			error_msg_and_die("%s: unexpected signal %u",
149404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  __func__, WTERMSIG(status));
14953454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		}
14963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (!WIFSTOPPED(status)) {
14973454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			kill(pid, SIGKILL);
149804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			error_msg_and_die("%s: unexpected wait status %x",
149904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin					  __func__, status);
15003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		}
15013454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (WSTOPSIG(status) == SIGSTOP) {
15023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			/*
15033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			 * We don't check "options aren't accepted" error.
15043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			 * If it happens, we'll never get (SIGTRAP | 0x80),
15053454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			 * and thus will decide to not use the option.
15063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			 * IOW: the outcome of the test will be correct.
15073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			 */
150804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0
150904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			    && errno != EINVAL && errno != EIO)
151004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin				perror_msg("PTRACE_SETOPTIONS");
15113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		}
15123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (WSTOPSIG(status) == (SIGTRAP | 0x80)) {
15133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			it_worked = 1;
15143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		}
15153454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) {
151604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin			kill_save_errno(pid, SIGKILL);
151775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko			perror_msg_and_die("PTRACE_SYSCALL doesn't work");
15183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko		}
15193454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	}
15203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
15213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	if (it_worked) {
152205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko worked:
152375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko		syscall_trap_sig = (SIGTRAP | 0x80);
1524f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko		ptrace_setoptions |= test_options;
1525a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko		if (debug_flag)
1526f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko			fprintf(stderr, "ptrace_setoptions = %#x\n",
1527f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko				ptrace_setoptions);
15288d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko		return 0;
15293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko	}
15303454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko
153104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	error_msg("Test for PTRACE_O_TRACESYSGOOD failed, "
153204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin		  "giving up using this feature.");
15338d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	return 1;
15343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko}
153531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
15365c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE
153731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic void
153831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotest_ptrace_seize(void)
153931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{
154031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	int pid;
154131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
154205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko	/* Need fork for test. NOMMU has no forks */
15435c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko	if (NOMMU_SYSTEM) {
15445c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko		post_attach_sigstop = 0; /* this sets use_seize to 1 */
15455c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko		return;
15465c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko	}
15475c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko
154831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	pid = fork();
154931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	if (pid < 0)
155031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		perror_msg_and_die("fork");
155131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
155231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	if (pid == 0) {
155331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		pause();
155431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		_exit(0);
155531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	}
155631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
155731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	/* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap.  After
155831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	 * attaching tracee continues to run unless a trap condition occurs.
155931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	 * PTRACE_SEIZE doesn't affect signal or group stop state.
156031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	 */
156126bc0606d96d05d30ba263939a0451889340a64cDenys Vlasenko	if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) {
156231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		post_attach_sigstop = 0; /* this sets use_seize to 1 */
1563a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko	} else if (debug_flag) {
156431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		fprintf(stderr, "PTRACE_SEIZE doesn't work\n");
156531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	}
156631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
156731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	kill(pid, SIGKILL);
156831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
156931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	while (1) {
157031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		int status, tracee_pid;
157131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
157231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		errno = 0;
157331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		tracee_pid = waitpid(pid, &status, 0);
157431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		if (tracee_pid <= 0) {
157531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			if (errno == EINTR)
157631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				continue;
157731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			perror_msg_and_die("%s: unexpected wait result %d",
157831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					 __func__, tracee_pid);
157931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		}
158031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		if (WIFSIGNALED(status)) {
158131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			return;
158231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		}
158331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		error_msg_and_die("%s: unexpected wait status %x",
158431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				__func__, status);
158531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	}
158631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko}
1587978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko#else /* !USE_SEIZE */
1588978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# define test_ptrace_seize() ((void)0)
1589978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko#endif
159031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
15916e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenkostatic unsigned
1592f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkoget_os_release(void)
1593f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko{
15946e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	unsigned rel;
15956e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	const char *p;
1596f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko	struct utsname u;
1597f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko	if (uname(&u) < 0)
1598f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		perror_msg_and_die("uname");
15996e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	/* u.release has this form: "3.2.9[-some-garbage]" */
16006e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	rel = 0;
16016e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	p = u.release;
16026e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	for (;;) {
16036e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		if (!(*p >= '0' && *p <= '9'))
16046e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko			error_msg_and_die("Bad OS release string: '%s'", u.release);
16056e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		/* Note: this open-codes KERNEL_VERSION(): */
16066e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		rel = (rel << 8) | atoi(p);
16076e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		if (rel >= KERNEL_VERSION(1,0,0))
16086e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko			break;
16096e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		while (*p >= '0' && *p <= '9')
16106e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko			p++;
16110dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin		if (*p != '.') {
16120dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin			if (rel >= KERNEL_VERSION(0,1,0)) {
16130dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin				/* "X.Y-something" means "X.Y.0" */
16140dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin				rel <<= 8;
16150dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin				break;
16160dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin			}
16176e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko			error_msg_and_die("Bad OS release string: '%s'", u.release);
16180dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin		}
16196e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		p++;
16206e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	}
16216e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	return rel;
1622f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko}
1623f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
1624ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko/*
1625ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Initialization part of main() was eating much stack (~0.5k),
1626ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * which was unused after init.
1627ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * We can reuse it if we move init code into a separate function.
1628ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko *
1629ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Don't want main() to inline us and defeat the reason
1630ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * we have a separate function.
1631ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko */
1632ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkostatic void __attribute__ ((noinline))
1633ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoinit(int argc, char *argv[])
163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct tcb *tcp;
1636ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin	int c, i;
163706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin	int optF = 0;
163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct sigaction sa;
163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
164008b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin	progname = argv[0] ? argv[0] : "strace";
164108b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin
1642a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	/* Make sure SIGCHLD has the default action so that waitpid
1643a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	   definitely works without losing track of children.  The user
1644a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	   should not have given us a bogus state to inherit, but he might
1645a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	   have.  Arguably we should detect SIG_IGN here and pass it on
1646a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	   to children, but probably noone really needs that.  */
1647a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko	signal(SIGCHLD, SIG_DFL);
1648a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko
164975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko	strace_tracer_pid = getpid();
165075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko
16516e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko	os_release = get_os_release();
1652f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
1653ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath	/* Allocate the initial tcbtab.  */
1654ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath	tcbtabsize = argc;	/* Surely enough for all -p args.  */
16554f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko	tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0]));
16561d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	if (!tcbtab)
16571d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		die_out_of_memory();
16584f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko	tcp = calloc(tcbtabsize, sizeof(*tcp));
16591d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko	if (!tcp)
16601d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		die_out_of_memory();
16614f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko	for (c = 0; c < tcbtabsize; c++)
16624f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko		tcbtab[c] = tcp++;
1663ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath
16646764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko	shared_log = stderr;
1665138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath	set_sortby(DEFAULT_SORTBY);
1666138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath	set_personality(DEFAULT_PERSONALITY);
166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	qualify("trace=all");
166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	qualify("abbrev=all");
166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	qualify("verbose=all");
167074ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko#if DEFAULT_QUAL_FLAGS != (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
167174ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko# error Bug in DEFAULT_QUAL_FLAGS
167274ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko#endif
167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	qualify("signal=all");
167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	while ((c = getopt(argc, argv,
1675e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills		"+b:cCdfFhiqrtTvVwxyz"
1676327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND
1677327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi		"k"
1678327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif
1679ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		"D"
1680b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		"a:e:o:O:p:s:S:u:E:P:I:")) != EOF) {
168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		switch (c) {
168261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko		case 'b':
168322efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko			if (strcmp(optarg, "execve") != 0)
168422efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko				error_msg_and_die("Syscall '%s' for -b isn't supported",
168522efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko					optarg);
168661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko			detach_on_execve = 1;
168761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko			break;
168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'c':
1689e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			if (cflag == CFLAG_BOTH) {
1690c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko				error_msg_and_die("-c and -C are mutually exclusive");
1691e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			}
1692e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			cflag = CFLAG_ONLY_STATS;
1693e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			break;
1694e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin		case 'C':
1695e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			if (cflag == CFLAG_ONLY_STATS) {
1696c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko				error_msg_and_die("-c and -C are mutually exclusive");
1697e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			}
1698e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			cflag = CFLAG_BOTH;
169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'd':
1701a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			debug_flag = 1;
170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
1703ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko		case 'D':
1704ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			daemonized_tracer = 1;
1705ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko			break;
170641c48227a86a176da333f713d5047240885f25ccRoland McGrath		case 'F':
170706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin			optF = 1;
170806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin			break;
170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'f':
171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			followfork++;
171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'h':
171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			usage(stdout, 0);
171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'i':
1716a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			iflag = 1;
171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'q':
171901997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange			qflag++;
172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'r':
1722a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			rflag = 1;
1723a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			/* fall through to tflag++ */
172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 't':
172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tflag++;
172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'T':
1728a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			Tflag = 1;
172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
1730e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills		case 'w':
1731e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills			count_wallclock = 1;
1732e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills			break;
173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'x':
173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			xflag++;
173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
17368a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards		case 'y':
17378a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards			show_fd_path = 1;
17388a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards			break;
173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'v':
174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			qualify("abbrev=none");
174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'V':
17439c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath			printf("%s -- version %s\n", PACKAGE_NAME, VERSION);
174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			exit(0);
174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
174617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig		case 'z':
174717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig			not_failing_only = 1;
174817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig			break;
174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'a':
1750ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			acolumn = string_to_uint(optarg);
1751102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko			if (acolumn < 0)
1752ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin				error_opt_arg(c, optarg);
175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'e':
175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			qualify(optarg);
175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'o':
175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			outfname = strdup(optarg);
175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'O':
1761ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			i = string_to_uint(optarg);
1762ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			if (i < 0)
1763ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin				error_opt_arg(c, optarg);
1764ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			set_overhead(i);
176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'p':
1767e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko			process_opt_p_list(optarg);
176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
17698a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards		case 'P':
17707239dbcf2dff792f408c60fe3e278f707fdf497bDenys Vlasenko			pathtrace_select(optarg);
17718a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards			break;
177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 's':
1773ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			i = string_to_uint(optarg);
1774ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			if (i < 0)
1775ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin				error_opt_arg(c, optarg);
1776ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			max_strlen = i;
177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'S':
177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			set_sortby(optarg);
178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		case 'u':
178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			username = strdup(optarg);
178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
1784327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND
1785327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi		case 'k':
1786327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi			stack_trace_enabled = true;
1787327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi			break;
1788327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif
1789de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath		case 'E':
17901d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko			if (putenv(optarg) < 0)
17911d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko				die_out_of_memory();
1792de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath			break;
1793b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		case 'I':
1794ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			opt_intr = string_to_uint(optarg);
1795ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin			if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS)
1796ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin				error_opt_arg(c, optarg);
1797b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			break;
179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		default:
179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			usage(stderr, 1);
180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			break;
180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1803837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko	argv += optind;
1804837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko	/* argc -= optind; - no need, argc is not used below */
180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1806102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko	acolumn_spaces = malloc(acolumn + 1);
1807102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko	if (!acolumn_spaces)
18081d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko		die_out_of_memory();
1809102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko	memset(acolumn_spaces, ' ', acolumn);
1810102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko	acolumn_spaces[acolumn] = '\0';
1811102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko
1812837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko	/* Must have PROG [ARGS], or -p PID. Not both. */
1813fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	if (!argv[0] == !nprocs)
1814ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath		usage(stderr, 1);
1815ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath
1816fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	if (nprocs != 0 && daemonized_tracer) {
1817c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko		error_msg_and_die("-D and -p are mutually exclusive");
1818d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao	}
1819d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao
182006350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin	if (!followfork)
182106350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin		followfork = optF;
182206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin
18233db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko	if (followfork >= 2 && cflag) {
1824c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko		error_msg_and_die("(-c or -C) and -ff are mutually exclusive");
1825cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath	}
1826cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath
1827e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills	if (count_wallclock && !cflag) {
1828e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills		error_msg_and_die("-w must be given with (-c or -C)");
1829e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills	}
1830e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills
18312727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin	if (cflag == CFLAG_ONLY_STATS) {
18322727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (iflag)
18332727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 'i');
18342727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#ifdef USE_LIBUNWIND
18352727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (stack_trace_enabled)
18362727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 'k');
18372727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#endif
18382727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (rflag)
18392727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 'r');
18402727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (tflag)
18412727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 't');
18422727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (Tflag)
18432727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 'T');
18442727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		if (show_fd_path)
18452727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin			error_msg("-%c has no effect with -c", 'y');
18462727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin	}
18472727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin
18482727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#ifdef USE_LIBUNWIND
18492727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin	if (stack_trace_enabled)
18502727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin		unwind_init();
18512727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#endif
18522727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin
185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* See if they want to run as another user. */
185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (username != NULL) {
185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		struct passwd *pent;
185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (getuid() != 0 || geteuid() != 0) {
1858cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko			error_msg_and_die("You must be root to use the -u option");
185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
18605d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko		pent = getpwnam(username);
18615d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko		if (pent == NULL) {
1862cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko			error_msg_and_die("Cannot find user '%s'", username);
186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		run_uid = pent->pw_uid;
186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		run_gid = pent->pw_gid;
186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	else {
186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		run_uid = getuid();
186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		run_gid = getgid();
187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
18728d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	/*
18738d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	 * On any reasonably recent Linux kernel (circa about 2.5.46)
18748d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	 * need_fork_exec_workarounds should stay 0 after these tests:
18758d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	 */
18768d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	/*need_fork_exec_workarounds = 0; - already is */
187704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin	if (followfork)
18788d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko		need_fork_exec_workarounds = test_ptrace_setoptions_followfork();
18798d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko	need_fork_exec_workarounds |= test_ptrace_setoptions_for_all();
188031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko	test_ptrace_seize();
18818044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin
188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	/* Check if they want to redirect the output. */
188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (outfname) {
188437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath		/* See if they want to pipe the output. */
188537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath		if (outfname[0] == '|' || outfname[0] == '!') {
188637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath			/*
188737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath			 * We can't do the <outfname>.PID funny business
188837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath			 * when using popen, so prohibit it.
188937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath			 */
18903db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko			if (followfork >= 2)
18917dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko				error_msg_and_die("Piping the output and -ff are mutually exclusive");
18926764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			shared_log = strace_popen(outfname + 1);
189354b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman		}
18943db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		else if (followfork < 2)
18956764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			shared_log = strace_fopen(outfname);
1896328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko	} else {
1897328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko		/* -ff without -o FILE is the same as single -f */
18983db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko		if (followfork >= 2)
1899328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko			followfork = 1;
190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1902cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko	if (!outfname || outfname[0] == '|' || outfname[0] == '!') {
1903a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko		char *buf = malloc(BUFSIZ);
1904a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko		if (!buf)
1905a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko			die_out_of_memory();
19066764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		setvbuf(shared_log, buf, _IOLBF, BUFSIZ);
1907cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko	}
1908837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko	if (outfname && argv[0]) {
1909b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		if (!opt_intr)
1910b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			opt_intr = INTR_NEVER;
191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		qflag = 1;
1912369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath	}
1913b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	if (!opt_intr)
1914b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		opt_intr = INTR_WHILE_WAIT;
1915b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko
1916b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	/* argv[0]	-pPID	-oFILE	Default interactive setting
1917b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	 * yes		0	0	INTR_WHILE_WAIT
1918b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	 * no		1	0	INTR_WHILE_WAIT
1919b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	 * yes		0	1	INTR_NEVER
1920b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	 * no		1	1	INTR_WHILE_WAIT
192154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath	 */
192254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath
19235c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko	sigemptyset(&empty_set);
19245c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko	sigemptyset(&blocked_set);
19255c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko
1926f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	/* startup_child() must be called before the signal handlers get
1927f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 * installed below as they are inherited into the spawned process.
1928f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 * Also we do not need to be protected by them as during interruption
1929f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 * in the startup_child() mode we kill the spawned process anyway.
1930f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko	 */
193161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko	if (argv[0]) {
19321d2435b20bc81fb52c3edb19a3b6247ce2d43ca6Dmitry V. Levin		if (!NOMMU_SYSTEM || daemonized_tracer)
19331d2435b20bc81fb52c3edb19a3b6247ce2d43ca6Dmitry V. Levin			hide_log_until_execve = 1;
19342a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko		skip_one_b_execve = 1;
1935837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko		startup_child(argv);
193661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko	}
193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sa.sa_handler = SIG_IGN;
193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sigemptyset(&sa.sa_mask);
194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	sa.sa_flags = 0;
1941b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */
1942b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */
1943b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko	if (opt_intr != INTR_ANYWHERE) {
1944b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		if (opt_intr == INTR_BLOCK_TSTP_TOO)
1945b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */
1946b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		/*
1947b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		 * In interactive mode (if no -o OUTFILE, or -p PID is used),
1948b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		 * fatal signals are blocked while syscall stop is processed,
1949b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		 * and acted on in between, when waiting for new syscall stops.
1950b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		 * In non-interactive mode, signals are ignored.
1951b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		 */
1952b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		if (opt_intr == INTR_WHILE_WAIT) {
1953b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaddset(&blocked_set, SIGHUP);
1954b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaddset(&blocked_set, SIGINT);
1955b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaddset(&blocked_set, SIGQUIT);
1956b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaddset(&blocked_set, SIGPIPE);
1957b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sigaddset(&blocked_set, SIGTERM);
1958b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko			sa.sa_handler = interrupt;
1959b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		}
1960b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		/* SIG_IGN, or set handler for these */
1961b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		sigaction(SIGHUP, &sa, NULL);
1962b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		sigaction(SIGINT, &sa, NULL);
1963b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		sigaction(SIGQUIT, &sa, NULL);
1964b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		sigaction(SIGPIPE, &sa, NULL);
1965b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko		sigaction(SIGTERM, &sa, NULL);
196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
1967fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	if (nprocs != 0 || daemonized_tracer)
196802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		startup_attach();
196902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath
1970fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	/* Do we want pids printed in our -o OUTFILE?
1971fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	 * -ff: no (every pid has its own file); or
1972fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	 * -f: yes (there can be more pids in the future); or
1973fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	 * -p PID1,PID2: yes (there are already more than one pid)
1974fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	 */
1975fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko	print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1));
197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1978eebb04d4ae8bf4b08a041f5ea442ca24c90692c2Denys Vlasenkostatic struct tcb *
197954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid)
198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i;
198254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath
198354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath	if (pid <= 0)
198454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath		return NULL;
198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
1986ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath	for (i = 0; i < tcbtabsize; i++) {
198754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath		struct tcb *tcp = tcbtab[i];
1988fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko		if (tcp->pid == pid)
198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			return tcp;
199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
199154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath
199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	return NULL;
199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void
19961201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void)
199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	int i;
199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct tcb *tcp;
20003521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko	int fatal_sig;
20013521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko
20023521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko	/* 'interrupted' is a volatile object, fetch it only once */
20033521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko	fatal_sig = interrupted;
20043521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko	if (!fatal_sig)
20053521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko		fatal_sig = SIGTERM;
200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2007ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath	for (i = 0; i < tcbtabsize; i++) {
2008ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath		tcp = tcbtab[i];
2009fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko		if (!tcp->pid)
201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			continue;
2011a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko		if (debug_flag)
201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr,
201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				"cleanup: looking at pid %u\n", tcp->pid);
2014fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko		if (tcp->pid == strace_child) {
201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			kill(tcp->pid, SIGCONT);
2016a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko			kill(tcp->pid, fatal_sig);
201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
20187de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko		detach(tcp);
201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	}
202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	if (cflag)
20216764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		call_summary(shared_log);
202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void
20251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig)
202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
2027a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko	interrupted = sig;
202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2030d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenkostatic void
20311201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void)
203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{
203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman	struct rusage ru;
203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2035d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	/* Used to be "while (nprocs != 0)", but in this testcase:
2036d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 *  int main() { _exit(!!fork()); }
2037d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 * under strace -f, parent sometimes (rarely) manages
2038d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 * to exit before we see the first stop of the child,
2039d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 * and we are losing track of it:
2040d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 *  19923 clone(...) = 19924
2041d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 *  19923 exit_group(1)     = ?
2042d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 *  19923 +++ exited with 1 +++
2043d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 * Waiting for ECHILD works better.
20447c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko	 * (However, if -o|logger is in use, we can't do that.
20457c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko	 * Can work around that by double-forking the logger,
20467c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko	 * but that loses the ability to wait for its completion on exit.
20477c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko	 * Oh well...)
2048d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	 */
2049d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko	while (1) {
2050f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		int pid;
2051f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		int wait_errno;
2052f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		int status, sig;
205331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		int stopped;
2054f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		struct tcb *tcp;
2055f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		unsigned event;
2056f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
2057222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko		if (interrupted)
2058d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			return;
2059725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko
20607c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko		if (popen_pid != 0 && nprocs == 0)
20617c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko			return;
20627c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko
2063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (interactive)
2064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			sigprocmask(SIG_SETMASK, &empty_set, NULL);
2065725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko		pid = wait4(-1, &status, __WALL, (cflag ? &ru : NULL));
206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		wait_errno = errno;
2067eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath		if (interactive)
2068eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			sigprocmask(SIG_BLOCK, &blocked_set, NULL);
206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
207026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko		if (pid < 0) {
2071725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko			if (wait_errno == EINTR)
207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				continue;
2073d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko			if (nprocs == 0 && wait_errno == ECHILD)
2074d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko				return;
2075d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko			/* If nprocs > 0, ECHILD is not expected,
2076d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko			 * treat it as any other error here:
2077d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko			 */
2078725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko			errno = wait_errno;
2079d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			perror_msg_and_die("wait4(__WALL)");
208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
2081725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko
208210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin		if (pid == popen_pid) {
2083c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko			if (!WIFSTOPPED(status))
20847dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko				popen_pid = 0;
208510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin			continue;
208610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin		}
2087f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
2088f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		event = ((unsigned)status >> 16);
2089a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko		if (debug_flag) {
20901d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16];
20911b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko			char evbuf[sizeof(",EVENT_VFORK_DONE (%u)") + sizeof(int)*3 /*paranoia:*/ + 16];
20921d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			strcpy(buf, "???");
20931d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			if (WIFSIGNALED(status))
20941d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP
20951d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko				sprintf(buf, "WIFSIGNALED,%ssig=%s",
20961d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko						WCOREDUMP(status) ? "core," : "",
20971d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko						signame(WTERMSIG(status)));
20981d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else
20991d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko				sprintf(buf, "WIFSIGNALED,sig=%s",
21001d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko						signame(WTERMSIG(status)));
21011d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif
21021d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			if (WIFEXITED(status))
21031d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko				sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status));
21041d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			if (WIFSTOPPED(status))
21051d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko				sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status)));
21065bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED
2107c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko			/* Should never be seen */
21081d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko			if (WIFCONTINUED(status))
21091d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko				strcpy(buf, "WIFCONTINUED");
21105bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif
211167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko			evbuf[0] = '\0';
211267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko			if (event != 0) {
211367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko				static const char *const event_names[] = {
211467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_CLONE] = "CLONE",
211567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_FORK]  = "FORK",
211667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_VFORK] = "VFORK",
211767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE",
211867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_EXEC]  = "EXEC",
211967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					[PTRACE_EVENT_EXIT]  = "EXIT",
21204e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko					/* [PTRACE_EVENT_STOP (=128)] would make biggish array */
212167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko				};
21221b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko				const char *e = "??";
212367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko				if (event < ARRAY_SIZE(event_names))
212467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko					e = event_names[event];
21254e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko				else if (event == PTRACE_EVENT_STOP)
21264e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko					e = "STOP";
21271b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko				sprintf(evbuf, ",EVENT_%s (%u)", e, event);
212867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko			}
212938eab5d6ea5627233b781f1bc68c2b264e8ee774Denys Vlasenko			fprintf(stderr, " [wait(0x%06x) = %u] %s%s\n", status, pid, buf, evbuf);
21301d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko		}
213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2132f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		/* Look up 'pid' in our table. */
21335d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko		tcp = pid2tcb(pid);
2134f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
21358511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko		if (!tcp) {
2136c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko			if (!WIFSTOPPED(status)) {
2137c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				/* This can happen if we inherited
2138c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				 * an unknown child. Example:
2139c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				 * (sleep 1 & exec strace sleep 2)
2140c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				 */
2141c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				error_msg("Exit of unknown pid %u seen", pid);
2142c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				continue;
2143c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko			}
21448511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (followfork) {
2145c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				/* We assume it's a fork/vfork/clone child */
21468511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				tcp = alloctcb(pid);
21478511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop;
21488511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				newoutf(tcp);
21498511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				if (!qflag)
21508511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko					fprintf(stderr, "Process %d attached\n",
21518511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko						pid);
21528511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			} else {
21538511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				/* This can happen if a clone call used
2154c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				 * CLONE_PTRACE itself.
215571d3d29a9d51add731c07e328a7394db0b3dd212Denys Vlasenko				 */
2156c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				ptrace(PTRACE_CONT, pid, (char *) 0, 0);
2157c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko				error_msg("Stop of unknown pid %u seen, PTRACE_CONTed it", pid);
215871d3d29a9d51add731c07e328a7394db0b3dd212Denys Vlasenko				continue;
21598511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			}
21608511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko		}
21618511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko
2162ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko		clear_regs();
2163ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko		if (WIFSTOPPED(status))
2164ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko			get_regs(pid);
2165ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko
2166f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		/* Under Linux, execve changes pid to thread leader's pid,
2167f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * and we see this changed pid on EVENT_EXEC and later,
2168f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * execve sysexit. Leader "disappears" without exit
2169f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * notification. Let user know that, drop leader's tcb,
2170f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * and fix up pid in execve thread's tcb.
2171f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * Effectively, execve thread's tcb replaces leader's tcb.
2172f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 *
2173f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * BTW, leader is 'stuck undead' (doesn't report WIFEXITED
2174f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * on exit syscall) in multithreaded programs exactly
2175f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * in order to handle this case.
2176f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 *
2177f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0.
2178f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 * On 2.6 and earlier, it can return garbage.
2179f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		 */
21806e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko		if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) {
21816764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			FILE *fp;
21828511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			struct tcb *execve_thread;
2183f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko			long old_pid = 0;
21848511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko
21858511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0)
21868511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				goto dont_switch_tcbs;
21876162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko			/* Avoid truncation in pid2tcb() param passing */
21886162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko			if (old_pid > UINT_MAX)
21896162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko				goto dont_switch_tcbs;
21908511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (old_pid <= 0 || old_pid == pid)
21918511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				goto dont_switch_tcbs;
21928511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			execve_thread = pid2tcb(old_pid);
21938511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			/* It should be !NULL, but I feel paranoid */
21948511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (!execve_thread)
21958511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				goto dont_switch_tcbs;
21968511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko
21978511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (execve_thread->curcol != 0) {
21988511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				/*
21998511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				 * One case we are here is -ff:
22008511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				 * try "strace -oLOG -ff test/threaded_execve"
22018511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				 */
22028511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid);
22036764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko				/*execve_thread->curcol = 0; - no need, see code below */
22048511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			}
22058511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			/* Swap output FILEs (needed for -ff) */
22066764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			fp = execve_thread->outf;
22076764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			execve_thread->outf = tcp->outf;
22086764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			tcp->outf = fp;
22098511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			/* And their column positions */
22106764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			execve_thread->curcol = tcp->curcol;
22116764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko			tcp->curcol = 0;
22128511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			/* Drop leader, but close execve'd thread outfile (if -ff) */
22138511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			droptcb(tcp);
22148511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			/* Switch to the thread, reusing leader's outfile and pid */
22158511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			tcp = execve_thread;
22168511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			tcp->pid = pid;
22178511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko			if (cflag != CFLAG_ONLY_STATS) {
22188511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				printleader(tcp);
22198511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				tprintf("+++ superseded by execve in pid %lu +++\n", old_pid);
22208511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				line_ended();
22218511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko				tcp->flags |= TCB_REPRINT;
2222f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko			}
2223f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		}
22248511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko dont_switch_tcbs:
2225f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko
22262a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko		if (event == PTRACE_EVENT_EXEC) {
22272a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko			if (detach_on_execve && !skip_one_b_execve)
22282a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko				detach(tcp); /* do "-b execve" thingy */
22292a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko			skip_one_b_execve = 0;
223061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko		}
223161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko
22327de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko		/* Set current output file */
22336764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko		current_tcp = tcp;
22347de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko
223513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko		if (cflag) {
223676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime);
223776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tcp->stime = ru.ru_stime;
223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
2239eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath
224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (WIFSIGNALED(status)) {
2241a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin			if (pid == strace_child)
2242a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin				exit_code = 0x100 | WTERMSIG(status);
2243e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			if (cflag != CFLAG_ONLY_STATS
2244a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenko			 && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)
2245a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenko			) {
224676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				printleader(tcp);
224713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP
2248000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko				tprintf("+++ killed by %s %s+++\n",
22492efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath					signame(WTERMSIG(status)),
225013d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko					WCOREDUMP(status) ? "(core dumped) " : "");
225113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else
2252000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko				tprintf("+++ killed by %s +++\n",
225313d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko					signame(WTERMSIG(status)));
22542efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif
22557de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko				line_ended();
225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			droptcb(tcp);
225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			continue;
225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (WIFEXITED(status)) {
2261a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin			if (pid == strace_child)
2262a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin				exit_code = WEXITSTATUS(status);
226301997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange			if (cflag != CFLAG_ONLY_STATS &&
226401997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange			    qflag < 2) {
226519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko				printleader(tcp);
2266000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko				tprintf("+++ exited with %d +++\n", WEXITSTATUS(status));
22677de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko				line_ended();
226819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko			}
226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			droptcb(tcp);
227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			continue;
227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		if (!WIFSTOPPED(status)) {
227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			fprintf(stderr, "PANIC: pid %u not stopped\n", pid);
227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			droptcb(tcp);
227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			continue;
227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
2278f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		/* Is this the very first time we see this tracee stopped? */
2279f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		if (tcp->flags & TCB_STARTUP) {
2280a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			if (debug_flag)
2281f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko				fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid);
228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			tcp->flags &= ~TCB_STARTUP;
228302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath			if (tcp->flags & TCB_BPTSET) {
228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				/*
228502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath				 * One example is a breakpoint inherited from
22862ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko				 * parent through fork().
228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				 */
22886cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko				if (clearbpt(tcp) < 0) {
22896cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko					/* Pretty fatal */
229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman					droptcb(tcp);
2291d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko					exit_code = 1;
2292d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko					return;
229376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman				}
229476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
2295c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko			if (!use_seize && ptrace_setoptions) {
2296a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko				if (debug_flag)
2297c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko					fprintf(stderr, "setting opts 0x%x on pid %d\n", ptrace_setoptions, tcp->pid);
229844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko				if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) {
229944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko					if (errno != ESRCH) {
230044f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko						/* Should never happen, really */
230144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko						perror_msg_and_die("PTRACE_SETOPTIONS");
23023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko					}
23033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko				}
23043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko			}
2305f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		}
2306f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko
230731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko		sig = WSTOPSIG(status);
230831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
2309f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko		if (event != 0) {
231031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			/* Ptrace event */
23115c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE
231226bc0606d96d05d30ba263939a0451889340a64cDenys Vlasenko			if (event == PTRACE_EVENT_STOP) {
23136703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko				/*
23146703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko				 * PTRACE_INTERRUPT-stop or group-stop.
23156703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko				 * PTRACE_INTERRUPT-stop has sig == SIGTRAP here.
23166703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko				 */
231731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				if (sig == SIGSTOP
231831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 || sig == SIGTSTP
231931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 || sig == SIGTTIN
232031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 || sig == SIGTTOU
232131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				) {
232231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					stopped = 1;
232331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko					goto show_stopsig;
232431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				}
232531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			}
232631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif
2327f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko			goto restart_tracee_with_sig_0;
2328f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		}
2329f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko
2330f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		/* Is this post-attach SIGSTOP?
2331f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		 * Interestingly, the process may stop
2332f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		 * with STOPSIG equal to some other signal
2333f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		 * than SIGSTOP if we happend to attach
2334f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		 * just before the process takes a signal.
2335f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		 */
2336f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko		if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) {
2337a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko			if (debug_flag)
2338f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko				fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid);
2339f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko			tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP;
23406cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko			goto restart_tracee_with_sig_0;
234176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
234276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman
23436cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko		if (sig != syscall_trap_sig) {
234431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			siginfo_t si;
234531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
234631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			/* Nonzero (true) if tracee is stopped by signal
234731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			 * (as opposed to "tracee received signal").
2348a44f9696e45f5bb51c6ec37c0ef95dc2cdfd4c8aDenys Vlasenko			 * TODO: shouldn't we check for errno == EINVAL too?
2349a44f9696e45f5bb51c6ec37c0ef95dc2cdfd4c8aDenys Vlasenko			 * We can get ESRCH instead, you know...
235031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			 */
235131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0);
23525c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE
235331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko show_stopsig:
23546703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#endif
2355e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin			if (cflag != CFLAG_ONLY_STATS
2356e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin			    && !hide_log_until_execve
2357e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin			    && (qual_flags[sig] & QUAL_SIGNAL)
2358e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin			   ) {
2359e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin				printleader(tcp);
2360e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin				if (!stopped) {
2361e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin					tprintf("--- %s ", signame(sig));
2362e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin					printsiginfo(&si, verbose(tcp));
23635a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko					tprints(" ---\n");
2364e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin				} else
23655a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko					tprintf("--- stopped by %s ---\n",
23665a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko						signame(sig));
2367e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin				line_ended();
236876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			}
236931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
237031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			if (!stopped)
237131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				/* It's signal-delivery-stop. Inject the signal */
237231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				goto restart_tracee;
237331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko
237431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			/* It's group-stop */
237531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			if (use_seize) {
237631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				/*
237731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 * This ends ptrace-stop, but does *not* end group-stop.
237831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 * This makes stopping signals work properly on straced process
237931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 * (that is, process really stops. It used to continue to run).
238031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				 */
238131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) {
2382d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko					/* Note: ptrace_restart emitted error message */
2383d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko					exit_code = 1;
2384d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko					return;
238531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				}
238631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko				continue;
238731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			}
238831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko			/* We don't have PTRACE_LISTEN support... */
23896cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko			goto restart_tracee;
239076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
23912ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko
23922ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko		/* We handled quick cases, we are permitted to interrupt now. */
239302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath		if (interrupted)
2394d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			return;
23952ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko
23962ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko		/* This should be syscall entry or exit.
23972ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko		 * (Or it still can be that pesky post-execve SIGTRAP!)
23982ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko		 * Handle it.
23992ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko		 */
2400235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko		if (trace_syscall(tcp) < 0) {
2401235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko			/* ptrace() failed in trace_syscall().
2402eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath			 * Likely a result of process disappearing mid-flight.
2403235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko			 * Observed case: exit_group() or SIGKILL terminating
2404f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko			 * all processes in thread group.
24057de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko			 * We assume that ptrace error was caused by process death.
2406f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko			 * We used to detach(tcp) here, but since we no longer
2407f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko			 * implement "detach before death" policy/hack,
2408f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko			 * we can let this process to report its death to us
2409f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko			 * normally, via WIFEXITED or WIFSIGNALED wait status.
2410f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko			 */
241176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman			continue;
241276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
24136cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0:
24146cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko		sig = 0;
24156cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee:
24166cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko		if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) {
2417d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			/* Note: ptrace_restart emitted error message */
2418d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			exit_code = 1;
2419d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko			return;
242076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman		}
24217c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko	} /* while (1) */
242276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}
2423ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko
2424ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoint
2425ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkomain(int argc, char *argv[])
2426ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko{
2427ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	init(argc, argv);
2428ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko
2429ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	/* Run main tracing loop */
2430d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko	trace();
2431ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko
2432ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	cleanup();
2433ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	fflush(NULL);
2434cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin	if (shared_log != stderr)
2435cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin		fclose(shared_log);
2436cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin	if (popen_pid) {
2437cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin		while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR)
2438cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin			;
2439cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin	}
2440ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	if (exit_code > 0xff) {
2441ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		/* Avoid potential core file clobbering.  */
2442c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin		struct_rlimit rlim = {0, 0};
2443c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin		set_rlimit(RLIMIT_CORE, &rlim);
2444ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko
2445ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		/* Child was killed by a signal, mimic that.  */
2446ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		exit_code &= 0xff;
2447ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		signal(exit_code, SIG_DFL);
2448ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		raise(exit_code);
2449ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		/* Paranoia - what if this signal is not fatal?
2450ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		   Exit with 128 + signo then.  */
2451ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko		exit_code += 128;
2452ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	}
2453ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko
2454ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko	return exit_code;
2455ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko}
2456