strace.c revision 833fb13cef3f1f05b71361b5002aa3c2faad9615
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 * $Id$ 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 35795edb11488dd47c4598e2228e3b5431de7ed46dRoland McGrath#include <sys/types.h> 363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko#include <stdarg.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <signal.h> 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <errno.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h> 4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h> 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h> 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h> 4676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <string.h> 4719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#include <limits.h> 4870b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath#include <dirent.h> 4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 50134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef LINUX 51134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# include <asm/unistd.h> 52134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# if defined __NR_tgkill 53b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko# define my_tgkill(pid, tid, sig) syscall(__NR_tgkill, (pid), (tid), (sig)) 54134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# elif defined __NR_tkill 55b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko# define my_tgkill(pid, tid, sig) syscall(__NR_tkill, (tid), (sig)) 56134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# else 57134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath /* kill() may choose arbitrarily the target task of the process group 58134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath while we later wait on a that specific TID. PID process waits become 59134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath TID task specific waits for a process under ptrace(2). */ 60134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 61b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko# define my_tgkill(pid, tid, sig) kill((tid), (sig)) 62134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# endif 63134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 64134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath 657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#if defined(IA64) && defined(LINUX) 667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 687b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 69bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 70bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#include <poll.h> 71bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 72bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stropts.h> 75ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 761d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#ifdef HAVE_SYS_UIO_H 779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <sys/uio.h> 789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 801d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 8196d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkoextern char **environ; 82418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern int optind; 83418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern char *optarg; 8496d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8641c48227a86a176da333f713d5047240885f25ccRoland McGrathint debug = 0, followfork = 0; 87f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0; 883454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */ 8975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP; 90e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levinint dtime = 0, xflag = 0, qflag = 0; 91e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levincflag_t cflag = CFLAG_NONE; 92b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0; 93ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/* 94ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option. 95ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice. 96ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's, 97ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process 98ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild 99ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID. 100ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases 101ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals, 102ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between, 103ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link. 104ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 105ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0; 10676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 10817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvigint not_failing_only = 0; 10917f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 1108a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */ 1118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint show_fd_path = 0; 1128a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 1138a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* are we filtering traces based on paths? */ 1148a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint tracing_paths = 0; 1158a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 116a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0; 117a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0; 11875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0; 119eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 120b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL; 121ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid; 122ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid; 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint acolumn = DEFAULT_ACOLUMN; 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 126b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL; 127ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic FILE *outf; 128ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwabstatic int curcol; 129ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab; 1302b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize; 131ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname; 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 133e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic int detach(struct tcb *tcp, int sig); 134e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic int trace(void); 135e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void); 136e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig); 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_SIG_ATOMIC_T */ 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_SIG_ATOMIC_T */ 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 145bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 147e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic struct tcb *pfd2tcb(int pfd); 148e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void reaper(int sig); 149e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void rebuild_pollv(void); 150ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstatic struct pollfd *pollv; 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poll_open(void); 155e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poller(int pfd); 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int fd; 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int proc_poll_pipe[2] = { -1, -1 }; 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 1699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLWRNORM 1709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 1719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLPRI 1729ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 173bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 176cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 1798a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsusage: strace [-CdDffhiqrtttTvVxxy] [-a column] [-e expr] ... [-o file]\n\ 180de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ 1818a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards [-P path] [command [arg ...]]\n\ 182b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab or: strace -c [-D] [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ 183de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 185b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab-C -- like -c but also print regular output while processes are running\n\ 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-F -- attempt to follow vforks, -h -- print help message\n\ 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-T -- print time spent in each syscall, -V -- print version\n\ 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 1948a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 201ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 205de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 206de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2078a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 208de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath" /* this is broken, so don't document it 20917f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 210de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath */ 211de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 21675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 21775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 21875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 21975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 22075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 22175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 22275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 22375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 22475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 22575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 22744d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 22844d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fprintf(stderr, "%s: ", progname); 22944d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin vfprintf(stderr, fmt, p); 23044d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin if (err_no) 23144d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fprintf(stderr, ": %s\n", strerror(err_no)); 23244d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin else 23344d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin putc('\n', stderr); 23444d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(stderr); 23575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 23675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 23775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 23875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 23975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 24075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 24175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 2423454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 24375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 2443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 24575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 24675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 24775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 24875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 24975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 25075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 25175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 25275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 25375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 25675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 25775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 25875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 25975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 26075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 26175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 26275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 26375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 26475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 26575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 26675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 2673454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 2683454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 27476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 278c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger/* Glue for systems without a MMU that cannot provide fork() */ 279c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#ifdef HAVE_FORK 280c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 0 281c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#else 282c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 1 283c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define fork() vfork() 284c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#endif 285c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger 2861f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 28710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 28810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 2891f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 2901f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 2911f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 2921f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 2931f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 2941f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 2951f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 2961f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 2971f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 2981f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 29910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 30010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 30110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 30210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 3031f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 30410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3051f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 30610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 30710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 30810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 30910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * When strace is setuid executable, we have to swap uids 31010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * before and after filesystem and process management operations. 31110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 31210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 31310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinswap_uid(void) 31410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 31510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef SVR4 31610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin int euid = geteuid(), uid = getuid(); 31710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3187b609d5ba0852e6c56ba311350ebd4412361777bDenys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 319cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 32010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 32110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 32210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 32310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3244bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#if _LFS64_LARGEFILE 3254bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen64 3264bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#else 3274bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen 3284bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#endif 3294bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 33010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 3313d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostrace_fopen(const char *path) 33210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 33310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin FILE *fp; 33410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 33510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 3363d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko fp = fopen_for_output(path, "w"); 3373d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko if (!fp) 3383d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 33910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 3403d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko set_cloexec_flag(fileno(fp)); 34110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin return fp; 34210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 34310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3447dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenkostatic int popen_pid = 0; 34510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 34610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef _PATH_BSHELL 34710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin# define _PATH_BSHELL "/bin/sh" 34810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 34910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 35010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 35110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * We cannot use standard popen(3) here because we have to distinguish 35210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * popen child process from other processes we trace, and standard popen(3) 35310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * does not export its child's pid. 35410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 35510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 35610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstrace_popen(const char *command) 35710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3587dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko FILE *fp; 3597dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko int fds[2]; 36010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 36110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 36210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pipe(fds) < 0) 3637dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("pipe"); 36410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3657dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 36610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3677dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = vfork(); 3687dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == -1) 3697dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("vfork"); 37010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3717dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == 0) { 37210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* child */ 37310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin close(fds[1]); 3747dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (fds[0] != 0) { 3757dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (dup2(fds[0], 0)) 3767dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("dup2"); 3777dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 37810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 37910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin execl(_PATH_BSHELL, "sh", "-c", command, NULL); 3807dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 38110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 3827dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 3837dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko /* parent */ 3847dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 3857dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko swap_uid(); 3867dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko fp = fdopen(fds[1], "w"); 3877dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (!fp) 3887dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Out of memory"); 3897dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko return fp; 39010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 39110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3923d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostatic void 39310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinnewoutf(struct tcb *tcp) 39410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 39510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (outfname && followfork > 1) { 3967a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char name[520 + sizeof(int) * 3]; 3977a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 3983d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko tcp->outf = strace_fopen(name); 39910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 40010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 40110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 40202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 40302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 40402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 40502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 40602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 40702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 40802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 40902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 41002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 41102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * between PTRACE_ATTACH and wait4 () on SIGSTOP. 412b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 41302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 41402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 41502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 41602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 417ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 418ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 419ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 420ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(1); 421ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 422ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 423ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 42475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 42575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 42675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 427ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 428ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 429ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 430ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 431ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 43275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 43375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 43475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 435ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 436ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 43702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 43802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 43902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 44002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 44102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef LINUX 44202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_CLONE_THREAD) 44302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 44402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif 44502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Reinitialize the output since it may have changed. */ 44602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 4473d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko newoutf(tcp); 44802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 44902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 45002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (proc_open(tcp, 1) < 0) { 45102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "trouble opening proc file\n"); 45202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 45302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 45402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 45502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 45602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath# ifdef LINUX 457ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 4587a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 45902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 46002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 46102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 46202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 46302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 46402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 46502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct dirent *de; 46602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tid; 46702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath while ((de = readdir(dir)) != NULL) { 4687a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 46902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 47002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 47102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 47202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 47302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 474f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (ptrace(PTRACE_ATTACH, tid, (char *) 1, 0) < 0) { 47502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 476f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 477f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 478f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 479f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko else { 480f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 481f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 482f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (tid != tcbtab[tcbi]->pid) { 483f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko tcp = alloctcb(tid); 484f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD; 485f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko tcp->parent = tcbtab[tcbi]; 486f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 48702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 488aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko if (interactive) { 489aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 490aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko if (interrupted) 491aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko return; 492aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 493aab52cae4cf597a556911fec3ef4cb5803a95b12Denys Vlasenko } 49402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 49502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 4967a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 4977a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 49802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 49902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 50002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 50102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 50202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 5037a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 5047a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko? "Process %u attached with %u threads - interrupt to quit\n" 5057a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko: "Process %u attached - interrupt to quit\n", 5067a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko tcbtab[tcbi]->pid, ntid); 50702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 50802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 5097a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 5107a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 51102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath# endif 51202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 51302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 51402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 51502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 51602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 517f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 518f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 519ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 520ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 521ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 522ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It is our grandparent we trace, not a -p PID. 523ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Don't want to just detach on exit, so... 524ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 525ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags &= ~TCB_ATTACHED; 526ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 527ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 528ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 529ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 530ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 531ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 532ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 53302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 53402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 53502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 53602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath "Process %u attached - interrupt to quit\n", 53702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 538f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 53902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 54002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 54102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 54202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 54302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 54402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 5451201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 54602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 54702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct stat statbuf; 54802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 54902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 55002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int pid = 0; 55102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 55202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 55302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 55402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 55502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 55602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 557cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 55802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 55902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 56002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 56102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 56202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 56302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 56402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 56502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 56602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 56702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 56802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 56902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 57002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 57130145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 57202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 57302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 57402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 57502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(path, ':')) { 57602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath n = strchr(path, ':') - path; 57702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 57802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 57902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 58002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 58102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 58202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 58302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 58402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 58502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 58602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 58702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 58802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 58902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 59002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 59102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 59202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 59302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 59402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 59502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0 && 59602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 59702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 59802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 59902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 60002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 60102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 60202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 60302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 60402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 605cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 60602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 607a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin strace_child = pid = fork(); 608ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 609cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 610ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 61175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 61275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 613ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 614ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid = getpid(); 61502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 616b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (outf != stderr) close(fileno(outf)); 61702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef MIPS 61802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Kludge for SGI, see proc_open for details. */ 61902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = foobar; 62002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = 0; 62102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&sa.sa_mask); 62202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGINT, &sa, NULL); 62302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* MIPS */ 62402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef FREEBSD 62502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pause(); 62602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* FREEBSD */ 627ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(pid, SIGSTOP); /* stop HERE */ 62802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* FREEBSD */ 62902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 630b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (outf != stderr) 631b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko close(fileno(outf)); 63202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 633ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 634ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 635cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 636ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 637ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (debug) 638ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(pid, SIGSTOP); 63902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 64002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 64102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (username != NULL || geteuid() == 0) { 64202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 64302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 64402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 64502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 64602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 64702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 64802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 64902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 65002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 65102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * It is important to set groups before we 65202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * lose privileges on setuid. 65302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 65402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (username != NULL) { 65502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (initgroups(username, run_gid) < 0) { 656cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("initgroups"); 65702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 65802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (setregid(run_gid, run_egid) < 0) { 659cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setregid"); 66002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (setreuid(run_uid, run_euid) < 0) { 662cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 66302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 66702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 66802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 669ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 670ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 671ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Induce an immediate stop so that the parent 672ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will resume us with PTRACE_SYSCALL and display 673ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * this execve call normally. 674c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger * Unless of course we're on a no-MMU system where 675c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger * we vfork()-ed, so we cannot stop the child. 676ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 677c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if (!strace_vforked) 678c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger kill(getpid(), SIGSTOP); 679ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } else { 680ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct sigaction sv_sigchld; 681ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, NULL, &sv_sigchld); 682ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 683ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make sure it is not SIG_IGN, otherwise wait 684ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will not block. 685ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 686ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko signal(SIGCHLD, SIG_DFL); 687ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 688ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Wait for grandchild to attach to us. 689ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It kills child after that, and wait() unblocks. 690ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 691ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(3); 692ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko wait(NULL); 693ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(0); 694ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, &sv_sigchld, NULL); 695ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 69602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 69702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 69802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, argv); 699cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 70002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 701ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 702ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* We are the tracer. */ 70375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* With -D, we are *child* here, IOW: different pid. Fetch it. */ 70475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 70575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 706ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp = alloctcb(daemonized_tracer ? getppid() : pid); 707ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 708ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* We want subsequent startup_attach() to attach to it. */ 709ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags |= TCB_ATTACHED; 710ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 71102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 712ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (proc_open(tcp, 0) < 0) { 713cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("trouble opening proc file"); 71402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 715ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif /* USE_PROCFS */ 71602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 71702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 718b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#ifdef LINUX 719b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 720b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 721b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 722b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 723b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 724b13c0de058585de7d47778a8923426b89bfffbb5Wang Chaostatic int 7253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 726b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 7272fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 7282fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 7292fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 7302fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 731b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 732b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao if ((pid = fork()) < 0) 733b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao return -1; 734b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao else if (pid == 0) { 735b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0) 736b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao _exit(1); 737b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao kill(getpid(), SIGSTOP); 738b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin _exit(fork() < 0); 739b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 740b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 741b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 742b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 743b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 744b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 745b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid == -1) { 746b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 747b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 748b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin else if (errno == ECHILD) 749b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 7503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko perror("test_ptrace_setoptions_followfork"); 751b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin return -1; 752b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 753b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 7542fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 755b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 && 756b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin errno != ESRCH) 757b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin kill(tracee_pid, SIGKILL); 758b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 759b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin else if (WIFSTOPPED(status)) { 7602fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin switch (WSTOPSIG(status)) { 7612fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin case SIGSTOP: 7622fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 7632fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin NULL, test_options) < 0) { 764b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao kill(pid, SIGKILL); 765b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin return -1; 766b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 7672fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin break; 7682fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin case SIGTRAP: 7692fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 7702fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin long msg = 0; 7712fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 7722fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 7732fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin NULL, (long) &msg) == 0) 7742fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin expected_grandchild = msg; 7752fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin } 7762fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin break; 777b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 778b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 && 779b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin errno != ESRCH) 780b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin kill(pid, SIGKILL); 781b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 782b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 7832fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) 784f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 785b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao return 0; 786b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 7873454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 7883454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 7893454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 7903454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 7913454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 7923454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 7933454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 7943454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 7953454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * _start: .globl _start 7963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int3 7973454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $42, %ebx 7983454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $1, %eax 7993454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int $0x80 8003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 8013454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 8023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkostatic void 8033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 8043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 8053454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko const unsigned int test_options = PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC; 8063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 8073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 8083454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8093454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 8103454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 81175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 8123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 8143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 8153454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 81675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 81775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", __func__); 8183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 8193454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 8203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8223454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 8233454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 8243454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 8263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 8273454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 8283454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 8293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 8303454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 83175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("%s: unexpected wait result %d", __func__, tracee_pid); 83275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 83375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 83475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 83575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 83675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* PTRACE_TRACEME failed in child. This is fatal. */ 83775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 8383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 8403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 8413454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko error_msg_and_die("%s: unexpected wait status %x", __func__, status); 8423454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8433454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 8443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 8453454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 8463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 8473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 8483454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 8493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 85075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0) 85175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (errno != EINVAL) 85275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg("PTRACE_SETOPTIONS"); 8533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 8553454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 8563454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8573454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 8583454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 85975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 8603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8633454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 86475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 865f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 8663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (debug) 867f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 868f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 8693454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko return; 8703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 8713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko fprintf(stderr, 8733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko "Test for PTRACE_O_TRACESYSGOOD failed, giving up using this feature.\n"); 8743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 875b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#endif 876b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 87776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 87808b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levinmain(int argc, char *argv[]) 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 88206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 88376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 88476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 88508b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 88608b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 88775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 88875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 889ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 890ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 8914f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 892cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (tcbtab == NULL) 893cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Out of memory"); 8944f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 8954f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko if (tcp == NULL) 896cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Out of memory"); 8974f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 8984f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 899ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 90176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 1; 902138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 903138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 90476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 90576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 90676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 9098a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards "+cCdfFhiqrtTvVxyz" 910ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 911ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 912ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 9138a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards "a:e:o:O:p:s:S:u:E:P:")) != EOF) { 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 916e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 917cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 918e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 919e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 920e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 921e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 922e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 923cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 924e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 925e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 930ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 931ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 932ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 933ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 934ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 93541c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 93606350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 93706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 93976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 94076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 94176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 94276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 94376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 94476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 94576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iflag++; 94676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 94776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag++; 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rflag++; 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 96276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 9638a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 9648a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 9658a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 9709c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 97317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 97417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 97517f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 98176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 989de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if ((pid = atoi(optarg)) <= 0) { 990cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("Invalid process id: '%s'", optarg); 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (pid == strace_tracer_pid) { 994cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("I'm sorry, I can't let you do that, Dave."); 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 997418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloc_tcb(pid, 0); 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_ATTACHED; 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pflag_seen++; 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 10018a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 10028a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tracing_paths = 1; 10038a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (pathtrace_select(optarg)) { 1004cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Failed to select path '%s'", optarg); 10058a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards } 10068a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 100876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 1009dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (max_strlen < 0) { 1010cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Invalid -s argument: '%s'", optarg); 1011dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 101276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1019de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 1020de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if (putenv(optarg) < 0) { 1021cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Out of memory"); 1022de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath } 1023de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 102476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 102576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 102676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1030d0c4c0cb881facd0ccf16b0c266875a8bf3e56aaRoland McGrath if ((optind == argc) == !pflag_seen) 1031ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1032ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1033d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao if (pflag_seen && daemonized_tracer) { 1034cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-D and -p are mutually exclusive options"); 1035d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1036d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 103706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 103806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 103906350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 1040cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (followfork > 1 && cflag) { 1041cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1042cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1043cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1049cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((pent = getpwnam(username)) == NULL) { 1052cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 105376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 105476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 105676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10628044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#ifdef LINUX 10638044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin if (followfork) { 10643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (test_ptrace_setoptions_followfork() < 0) { 10658044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin fprintf(stderr, 10668044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin "Test for options supported by PTRACE_SETOPTIONS " 10678044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin "failed, giving up using this feature.\n"); 1068f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions = 0; 10698044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin } 10708044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin if (debug) 1071f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 1072f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 10738044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin } 10743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko test_ptrace_setoptions_for_all(); 10758044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#endif 10768044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 107937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 108037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 108137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 108237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 108337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 108437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 10857dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (followfork > 1) 10867dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 10877dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko outf = strace_popen(outfname + 1); 108854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 10893d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko else if (followfork <= 1) 10903d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko outf = strace_fopen(outfname); 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1093cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1094cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko static char buf[BUFSIZ]; 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 1096cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 109737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname && optind < argc) { 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 0; 109976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1100369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1101b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 110254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* Valid states here: 110354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath optind < argc pflag_seen outfname interactive 110454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 1 0 0 1 110554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 0 1 0 1 110654cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 1 0 1 0 110754cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 0 1 1 1 110854cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 110954cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 111054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* STARTUP_CHILD must be called before the signal handlers get 111154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath installed below as they are inherited into the spawned process. 111254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Also we do not need to be protected by them as during interruption 111354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath in the STARTUP_CHILD mode we kill the spawned process anyway. */ 111454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath if (!pflag_seen) 111554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath startup_child(&argv[optind]); 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTOU, &sa, NULL); 112376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTIN, &sa, NULL); 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) { 112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGHUP); 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGINT); 112776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGQUIT); 112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGPIPE); 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGTERM); 113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interrupt; 113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* POSIX signals on sunos4.1 are a little broken. */ 113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = SA_INTERRUPT; 113476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 1141bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = reaper; 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGCHLD, &sa, NULL); 1144553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 1145553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 1146553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 1147553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 1148553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 1149553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 1150553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 1151553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 1152bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1154ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pflag_seen || daemonized_tracer) 115502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 115602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace() < 0) 115876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 1160a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin fflush(NULL); 1161a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (exit_code > 0xff) { 1162a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Child was killed by a signal, mimic that. */ 1163a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code &= 0xff; 1164a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin signal(exit_code, SIG_DFL); 1165a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin raise(exit_code); 1166a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Paranoia - what if this signal is not fatal? 1167a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin Exit with 128 + signo then. */ 1168a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code += 128; 1169a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin } 1170a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit(exit_code); 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11732b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic void 1174418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoexpand_tcbtab(void) 11757b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 11767b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath /* Allocate some more TCBs and expand the table. 11777b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath We don't want to relocate the TCBs because our 11787b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath callers have pointers and it would be a pain. 11797b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath So tcbtab is a table of pointers. Since we never 11807b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath free the TCBs, we allocate a single chunk of many. */ 118118da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko int i = tcbtabsize; 118218da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 118318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 118418da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko if (newtab == NULL || newtcbs == NULL) 118518da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("expand_tcbtab: out of memory"); 11867b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtabsize *= 2; 11877b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtab = newtab; 118818da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko while (i < tcbtabsize) 118918da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko tcbtab[i++] = newtcbs++; 11907b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath} 11917b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 119276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 119310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinalloc_tcb(int pid, int command_options_parsed) 119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 119576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 119676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1198418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (nprocs == tcbtabsize) 1199418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko expand_tcbtab(); 1200418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1201ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1202ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 120376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 120418da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 120676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags = TCB_INUSE | TCB_STARTUP; 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 12101d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 12111d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 121210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (command_options_parsed) 121310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newoutf(tcp); 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 121718da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("bug in alloc_tcb"); 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1220bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1222418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoproc_open(struct tcb *tcp, int attaching) 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char proc[32]; 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long arg; 1226bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef SVR4 122719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 122819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes sysset_t syscalls; 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t signals; 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fltset_t faults; 1231bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last_pfd; 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 123576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1236ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 12379ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Open the process pseudo-files in /proc. */ 12389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/ctl", tcp->pid); 12399ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 12409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 12419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 12429ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 12431f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 12449ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 12459ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 12469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 12479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 12489ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 12491f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_stat); 12509ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/as", tcp->pid); 12519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 12529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 12539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 12549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 12551f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_as); 12569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Open the process pseudo-file in /proc. */ 1258bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 1260372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR|O_EXCL); 1261bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1262bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 1263372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR); 1264bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 1265372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab if (tcp->pfd < 0) { 126676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 12691f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 12709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1271bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1272bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/regs", tcp->pid); 1273bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 1274bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../regs\", ...)"); 1275bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1276bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1277bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (cflag) { 1278bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 1279bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 1280bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../status\", ...)"); 1281bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1282bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1283bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 1284bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1285bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Wait for the child to pause. Because of a race 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * condition we have to poll for the event. 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1293b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_STATUS(tcp) < 0) { 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 12979ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 1298cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko break; 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1301bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Stop the process so that we own the stop. */ 130316a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTOP"); 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1307553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PIOCSET 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 13119ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 13179ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 1322553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1331bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1332bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 1333bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 1334bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCGFL"); 13355ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1336bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1337bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg &= ~PF_LINGER; 1338bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 13395ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko perror("PIOCSFL"); 13405ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1341bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1342bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !PIOCSET */ 1344bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 134519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable all syscall entries we care about. */ 134619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&syscalls); 134719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 134819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof syscalls) * CHAR_BIT) break; 1349b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_TRACE) praddset(&syscalls, i); 135019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 1351b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_execve); 135219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (followfork) { 1353b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork); 135419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_forkall 1355b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_forkall); 135619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 1357553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef SYS_fork1 1358b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork1); 135919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 136019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rfork1 1361b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rfork1); 136219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 136319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rforkall 1364b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rforkall); 136519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 136619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 136719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable the syscall exits. */ 137219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOSEXIT"); 137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable signals we care about. */ 137719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&signals); 137819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 137919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof signals) * CHAR_BIT) break; 1380b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_SIGNAL) praddset(&signals, i); 138119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 13829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 138376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 138476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 138576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable faults we care about */ 138719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&faults); 138819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 138919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof faults) * CHAR_BIT) break; 1390b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_FAULT) praddset(&faults, i); 139119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 13929ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 139476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1396bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1397bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* set events flags. */ 1398b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko arg = S_SIG | S_SCE | S_SCX; 1399b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 1400bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCBIS"); 1401bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1402bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1403bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 140476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The SGI PRSABORT doesn't work for pause() so 140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * we send it a caught signal to wake it up. 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGINT); 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 1412553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef PRSABORT 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 14149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = PRSABORT; 1415b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 141676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 141776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 141876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1419553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 1420bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !MIPS*/ 1421bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1422bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 1423bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1424553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 1427b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_WSTOP(tcp) < 0) { 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 14319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 1432bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 1433bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman get_scno(tcp); 143476989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath if (known_scno(tcp) == SYS_execve) 143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set it running: maybe execve will be next. */ 1438bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 14399ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 14409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 1441bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1442bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 1443553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1447bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1448bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* handle the case where we "opened" the child before 1449bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman it did the kill -STOP */ 1450bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->status.PR_WHY == PR_SIGNALLED && 1451bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 1452bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1453553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 145476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1455bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1457bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1458bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else { 1459553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (attaching < 2) { 14602e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* We are attaching to an already running process. 14612e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * Try to figure out the state of the process in syscalls, 14622e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * to handle the first event well. 14632e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * This is done by having a look at the "wchan" property of the 14642e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * process, which tells where it is stopped (if it is). */ 14652e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman FILE * status; 14662e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman char wchan[20]; /* should be enough */ 1467553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 14682e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 14692e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman status = fopen(proc, "r"); 14702e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status && 14712e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 14722e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman "%*d,%*d %*d,%*d %19s", wchan) == 1) && 14732e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 14742e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "stopevent")) { 14752e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* The process is asleep in the middle of a syscall. 14762e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman Fake the syscall entry event */ 14772e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 14782e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 14792e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman trace_syscall(tcp); 14802e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 14812e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status) 14822e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fclose(status); 14832e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } /* otherwise it's a fork being followed */ 1484bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1485bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 148776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 149076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 149276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 149376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 149476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 149776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1499bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1501e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstruct tcb * 150254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 150554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 150654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 150754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1509ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 151054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 151154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 151454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1518bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 152154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathfirst_used_tcb(void) 152254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath{ 152354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath int i; 152454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp; 152554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath for (i = 0; i < tcbtabsize; i++) { 152654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = tcbtab[i]; 152754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->flags & TCB_INUSE) 152854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return tcp; 152954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath } 153054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 153154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath} 153254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 153354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathstatic struct tcb * 15341201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkopfd2tcb(int pfd) 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1538ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = 0; i < tcbtabsize; i++) { 1539ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != pfd) 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1548bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15511201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodroptcb(struct tcb *tcp) 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 155519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 15571d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 15581d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1559eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != -1) { 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(tcp->pfd); 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 1563bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1564bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_reg != -1) { 1565bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_reg); 1566bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_reg = -1; 1567bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1568bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_status != -1) { 1569bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_status); 1570bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1571bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1572553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* !FREEBSD */ 1573bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 157419cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko tcp->flags = 0; /* rebuild_pollv needs it */ 157519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko rebuild_pollv(); 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1578eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1579822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 1581eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 158219cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko memset(tcp, 0, sizeof(*tcp)); 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15850a463880341945df08b6dc79134dc78cc38dc283Roland McGrath/* detach traced process; continue with sig 15860a463880341945df08b6dc79134dc78cc38dc283Roland McGrath Never call DETACH twice on the same process as both unattached and 15870a463880341945df08b6dc79134dc78cc38dc283Roland McGrath attached-unstopped processes give the same ESRCH. For unattached process we 15880a463880341945df08b6dc79134dc78cc38dc283Roland McGrath would SIGSTOP it and wait for its SIGSTOP notification forever. */ 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 15911201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodetach(struct tcb *tcp, int sig) 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1594ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#ifdef LINUX 15951bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int status, catch_sigstop; 1596ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 1599840d85b3e50cea9f28aedd23af94742c2a60265aAndreas Schwab clearbpt(tcp); 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 16047bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 16057bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 16077bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 16087bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 16097bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 16107bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 161102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 161202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * On TCB_STARTUP we did PTRACE_ATTACH but still did not get the 161302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * expected SIGSTOP. We must catch exactly one as otherwise the 161402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * detached process would be left stopped (process state T). 161502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 161602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath catch_sigstop = (tcp->flags & TCB_STARTUP); 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* On a clear day, you can see forever. */ 16197bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 16207bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (errno != ESRCH) { 16217bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath /* Shouldn't happen. */ 16227bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: ptrace(PTRACE_DETACH, ...)"); 16237bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 1624134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath else if (my_tgkill((tcp->flags & TCB_CLONE_THREAD ? tcp->parent->pid 1625134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath : tcp->pid), 1626134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath tcp->pid, 0) < 0) { 16277bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 16287bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: checking sanity"); 16297bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 163002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (!catch_sigstop && my_tgkill((tcp->flags & TCB_CLONE_THREAD 163102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ? tcp->parent->pid : tcp->pid), 163202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid, SIGSTOP) < 0) { 16337bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 16347bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: stopping child"); 16357bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 163602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 163702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath catch_sigstop = 1; 1638ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (catch_sigstop) { 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 16407508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 16417508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 16427508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 16437508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16447508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 16467508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16477508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16487508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 16497508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 16507508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 16517508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 16527508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16537508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16547508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16557508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 16567508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 16577508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WCLONE, 16587508cb4678141d146d819120f6b5b428c103882eRoland McGrath NULL) < 0) { 16597508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 16607508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16617508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16627508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16637508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 16647508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16657508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16677508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 1673732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, sig); 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1676732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, 167775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko WSTOPSIG(status) == syscall_trap_sig ? 0 1678732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko : WSTOPSIG(status)); 1679732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (error < 0) 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1682ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } 16837bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* LINUX */ 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig && kill(tcp->pid, sig) < 0) 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: kill"); 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = 0; 1690732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_DETACH, tcp, sig); 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 1697a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1701bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1703e5e60858063f214fcd7860f50f8bcb46f951f9abDmitry V. Levinstatic void reaper(int sig) 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1712bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 17151201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1720ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1721ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (!outfname || followfork < 2 || tcp_last == tcp)) { 1729ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko tprintf(" <unfinished ...>"); 1730ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 173676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGTERM); 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 17441201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interrupted = 1; 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17516d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 17546d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 17571201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrerror(int err_no) 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176135aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 176235aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko sprintf(buf, "Unknown error %d", err_no); 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 176535aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko return sys_errlist[err_no]; 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17728f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 17736d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 177476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 17758f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 17768f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 17778f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 17801201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrsignal(int sig) 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 179076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 179276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 179476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1797bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18001201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkorebuild_pollv(void) 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1804ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv != NULL) 1805b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko free(pollv); 1806c012d223a6b915f06ef32b8aaa52b984015d192eRoland McGrath pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]); 1807ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv == NULL) { 1808cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Out of memory"); 1809ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 1810ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 1811ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = j = 0; i < tcbtabsize; i++) { 1812ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 181576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[j].fd = tcp->pfd; 18169ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollv[j].events = POLLWANT; 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j++; 181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j != nprocs) { 1820cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("proc miscount"); 182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 182476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 182576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18271201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll_open(void) 182876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 182976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 1832cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("pipe"); 183376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 18351f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(proc_poll_pipe[i]); 183676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 183876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 183976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 18401201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll(struct pollfd *pollv, int nfds, int timeout) 184176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 184276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 184376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 184476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 184576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 184676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 1849cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("panic: short read: %d", n); 185076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 185176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 185276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = 0; 185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18621201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkowakeup_handler(int sig) 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18671201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poller(int pfd) 186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t blocked_set, empty_set; 187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 1875bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1876bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct procfs_status pfs; 1877bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (fork()) { 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 1881cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = wakeup_handler; 189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGUSR1, &sa, NULL); 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGUSR1); 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 1904cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("getrlimit(RLIMIT_NOFILE, ...)"); 190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = rl.rlim_cur; 190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i != pfd && i != proc_poll_pipe[1]) 190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(i); 191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.fd = pfd; 191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.pid = getpid(); 191476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1915bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 19165ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 19175ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#else 19185ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 19195ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#endif 19209ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman { 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (errno) { 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLERR; 192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLHUP; 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19369ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollinfo.revents = POLLWANT; 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 194376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 19539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 195476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The previous process is ready to run again. We'll 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * let it do so if it is currently in a syscall. This 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * heuristic improves the readability of the trace. 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[last].fd); 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp && (tcp->flags & TCB_INSYSCALL)) 196176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[j].revents & (POLLHUP | POLLERR)) { 196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[j].fd); 196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) { 1970cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("lost proc"); 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pollv[j].revents & POLLWANT) { 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last = j; 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[j].fd; 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1980cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("nothing ready"); 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 19841201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 19869dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 1987d870b3c31a0139b335a66a829169bacc74624c44John Hughes struct tcb *in_syscall = NULL; 19889dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pfd; 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int what; 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int ioctl_result = 0, ioctl_errno = 0; 19939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman long arg; 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (nprocs) { 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 1: 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] == -1) { 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 200754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = first_used_tcb(); 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = tcp->pfd; 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* fall through ... */ 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_POLLABLE_PROCFS 20209dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 20219dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman /* On some systems (e.g. UnixWare) we get too much ugly 20229dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman "unfinished..." stuff when multiple proceses are in 20239dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman syscalls. Here's a nasty hack */ 2024553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 20259dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (in_syscall) { 20269dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman struct pollfd pv; 20279dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp = in_syscall; 20289dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = NULL; 20299dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.fd = tcp->pfd; 20309dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.events = POLLWANT; 2031b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if ((what = poll(&pv, 1, 1)) < 0) { 20329dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (interrupted) 20339dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman return 0; 20349dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman continue; 20359dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 20369dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 20379dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman goto FOUND; 20389dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 20399dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 20409dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 20419dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_POLLABLE_PROCFS */ 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll(pollv, nprocs, INFTIM) < 0) { 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pfd2tcb(pfd)) == NULL) { 2062cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("unknown pfd: %u", pfd); 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2064b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#ifdef POLL_HACK 20659dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman FOUND: 2066b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#endif 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Get the status of the process. */ 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!interrupted) { 2069bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 2070b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2071bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 2072bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* Thanks to some scheduling mystery, the first poller 2073bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sometimes waits for the already processed end of fork 2074bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 2075bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (proc_poll_pipe[0] != -1) 2076b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_STATUS(tcp); 2077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else 2078b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2079553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ioctl_errno = errno; 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) { 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGKILL); 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGUSR1); 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) { 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Find out what happened if it failed. */ 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (ioctl_errno) { 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2102bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2103bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOTTY: 2104553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2109cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCWSTOP"); 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21132e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifdef FREEBSD 21142e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 21152e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* discard first event for a syscall we never entered */ 2116b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko IOCTL(tcp->pfd, PIOCRUN, 0); 21172e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 21182e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 2119553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2120553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 212176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 212276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 212376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 212576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 2126ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 212776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 212976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval stime; 2130bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2131bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman char buf[1024]; 2132bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int len; 2133bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 2134bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 2135bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman buf[len] = '\0'; 2136bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sscanf(buf, 2137bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 2138bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman &stime.tv_sec, &stime.tv_usec); 2139bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 2140bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 2141553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else /* !FREEBSD */ 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 2144bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = stime; 214776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21489ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman what = tcp->status.PR_WHAT; 21499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman switch (tcp->status.PR_WHY) { 2150bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_REQUESTED: 21529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) { 21539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2155cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 215676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2159bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 216076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSENTRY: 21619dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 21629dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = tcp; 21639dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 216476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 216576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2166cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 216776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 216876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 216976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 2170e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 2171e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_SIGNAL)) { 217276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 217376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) ---", 2174ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(what), strsignal(what)); 2175ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 21765826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#ifdef PR_INFO 21775826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes if (tcp->status.PR_INFO.si_signo == what) { 21785826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printleader(tcp); 21795826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes tprintf(" siginfo="); 21805826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printsiginfo(&tcp->status.PR_INFO, 1); 2181ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 21825826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes } 21835826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#endif 218476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 218676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 2187e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAGS_ONLY_STATS 2188e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_FAULT)) { 218976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 219076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("=== FAULT %d ===", what); 2191ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 219276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 219376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2194bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2195bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case 0: /* handle case we polled for nothing */ 21965ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko continue; 2197553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2199cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("odd stop %d", tcp->status.PR_WHY); 220076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2202ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2203ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 22049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 2205553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 2206b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 2207553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 2208b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 2209553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2210372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab { 2211cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCRUN"); 221276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 221376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 221676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2217bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2219eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstatic int 2220eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathtrace() 222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 222276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 222376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int wait_errno; 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 222676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 222776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 222826d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko struct rusage *rup = cflag ? &ru : NULL; 222926d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 2230eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath static int wait4_options = __WALL; 223126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif 223276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 223376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2234eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath while (nprocs != 0) { 2235222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 2236eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2237eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2238eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 224026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 224126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 22425bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 22432f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 22442f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 224526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 22462f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 22475bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 22482f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 224926d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, __WCLONE, rup); 225026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2251cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg("wait4(__WCLONE) failed"); 22522f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 22532f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 225426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# else 225526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, 0, rup); 225626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif /* __WALL */ 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 226026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko#endif 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 2262eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2263eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 226526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2266eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath switch (wait_errno) { 2267eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case EINTR: 226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2269eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case ECHILD: 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2276eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2277eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath default: 2278eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = wait_errno; 2279eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("strace: wait"); 2280eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 228310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 228410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (WIFEXITED(status) || WIFSIGNALED(status)) 22857dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 228610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 228710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 22881d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) { 22891d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 22901d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef LINUX 22911d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko unsigned ev = (unsigned)status >> 16; 22921d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (ev) { 22931d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko static const char *const event_names[] = { 22941d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 22951d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 22961d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 22971d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 22981d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 22991d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 23001d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko }; 23011d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko const char *e; 23021d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (ev < ARRAY_SIZE(event_names)) 23031d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko e = event_names[ev]; 23041d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko else { 23051d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "?? (%u)", ev); 23061d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko e = buf; 23071d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 23081d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " PTRACE_EVENT_%s", e); 23091d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 23101d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 23111d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 23121d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 23131d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 23141d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 23151d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 23161d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 23171d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 23181d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 23191d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 23201d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 23211d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 23221d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 23231d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 23241d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 23255bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 23261d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 23271d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 23285bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 23291d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf); 23301d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 233176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 233276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pid' in our table. */ 233376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pid2tcb(pid)) == NULL) { 2334e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef LINUX 233541c48227a86a176da333f713d5047240885f25ccRoland McGrath if (followfork) { 2336e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 2337e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 2338e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 2339e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 2340e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 2341e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 2342e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 2343e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 2344e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 2345418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloctcb(pid); 2346833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko tcp->flags |= TCB_ATTACHED; 2347e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 2348833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko fprintf(stderr, "Process %d attached\n", 2349e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 23508b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 2351e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 2352e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 2353e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 2354eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#endif 2355e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 2356e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 2357e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_CONT, pid, (char *) 1, 0); 2358cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Unknown pid: %u", pid); 2359e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 236076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2361eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* set current output file */ 2362eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath outf = tcp->outf; 2363ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 2364eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#ifdef LINUX 236513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 236676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 236776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 236876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 236913d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#endif 2370eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 237176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 2372a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2373a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 2374e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 237576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 237676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 237713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 23782efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath tprintf("+++ killed by %s %s+++", 23792efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 238013d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 238113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 238213d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko tprintf("+++ killed by %s +++", 238313d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 23842efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 2385ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 238676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 238776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 238876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 238976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 239076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 2391a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2392a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 23930a396906981a03f93c07cb912585d0679dd50899Roland McGrath if (tcp == tcp_last) { 23947a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL) 23950a396906981a03f93c07cb912585d0679dd50899Roland McGrath tprintf(" <unfinished ... exit status %d>\n", 23960a396906981a03f93c07cb912585d0679dd50899Roland McGrath WEXITSTATUS(status)); 23970a396906981a03f93c07cb912585d0679dd50899Roland McGrath tcp_last = NULL; 23980a396906981a03f93c07cb912585d0679dd50899Roland McGrath } 239919cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 240019cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 240119cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko tprintf("+++ exited with %d +++", WEXITSTATUS(status)); 240219cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printtrailer(); 240319cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 240476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 240576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 240676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 240776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 240876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 240976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 241076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 241176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 241276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (status >> 16) { 2414833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko /* Ptrace event (we ignore all of them for now) */ 2415833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko goto tracing; 2416ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao } 2417ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao 241802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 241902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Interestingly, the process may stop 242002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * with STOPSIG equal to some other signal 2421eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * than SIGSTOP if we happend to attach 242202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * just before the process takes a signal. 2423c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger * A no-MMU vforked child won't send up a signal, 2424c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger * so skip the first (lost) execve notification. 242502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 2426c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if ((tcp->flags & TCB_STARTUP) && 2427c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger (WSTOPSIG(status) == SIGSTOP || strace_vforked)) { 242876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 242976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * This flag is there to keep us in sync. 243076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Next time this process stops it should 243176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * really be entering a system call. 243276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 243376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 243402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 243576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 243602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 243702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * parent through fork (). 243876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 243976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (clearbpt(tcp) < 0) /* Pretty fatal */ { 244076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 244176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 244276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 244376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 244476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2445ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#ifdef LINUX 2446f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko /* If options were not set for this tracee yet */ 2447f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko if (tcp->parent == NULL) { 2448f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko if (ptrace_setoptions) { 2449f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko if (debug) 2450f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 2451f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 2452f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko if (errno != ESRCH) { 2453f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko /* Should never happen, really */ 2454f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 2455f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko } 24563454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 24573454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 24583454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2459ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#endif 246076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto tracing; 246176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 246276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 246375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WSTOPSIG(status) != syscall_trap_sig) { 246476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP && 246576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (tcp->flags & TCB_SIGTRAPPED)) { 246676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 246776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Trapped attempt to block SIGTRAP 246876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Hope we are back in control now. 246976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 247076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 2471732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) { 247276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 247376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 247476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 247576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 247676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2477e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 247876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 2479c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin siginfo_t si; 2480c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 24816b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long pc = 0; 24826b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long psr = 0; 24837b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2484932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IPSR, &psr); 2485932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IIP, &pc); 24867b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 24876b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PSR_RI 41 24887b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 24896b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR " @ %lx" 24906b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_ARG pc 24916b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin#else 24926b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR "%s" 24936b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_ARG "" 24947b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 249576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 24966b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin if (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) == 0) { 24976b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin tprintf("--- "); 24986b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin printsiginfo(&si, verbose(tcp)); 24996b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin tprintf(" (%s)" PC_FORMAT_STR " ---", 25006b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin strsignal(WSTOPSIG(status)), 25016b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 25026b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin } else 25036b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin tprintf("--- %s by %s" PC_FORMAT_STR " ---", 25046b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin strsignal(WSTOPSIG(status)), 25056b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin signame(WSTOPSIG(status)), 25066b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 2507ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 250876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2509732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, WSTOPSIG(status)) < 0) { 251076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 251176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 251276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 251376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 251476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 251502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* we handled the STATUS, we are permitted to interrupt now. */ 251602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 251702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return 0; 2518eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2519eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* ptrace() failed in trace_syscall() with ESRCH. 2520eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2521eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Observed case: exit_group() terminating 2522eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * all processes in thread group. In this case, threads 2523eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * "disappear" in an unpredictable moment without any 2524eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * notification to strace via wait(). 2525ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko */ 2526ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (tcp->flags & TCB_ATTACHED) { 2527eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tcp_last) { 2528eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Do we have dangling line "syscall(param, param"? 2529178de007d14f3ae890117b540def9cf14bcb61feDenys Vlasenko * Finish the line then. 2530eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath */ 2531eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp_last->flags |= TCB_REPRINT; 2532eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tprintf(" <unfinished ...>"); 2533eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath printtrailer(); 2534eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 253576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 2536ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } else { 2537eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath ptrace(PTRACE_KILL, 2538eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp->pid, (char *) 1, SIGTERM); 253976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 254076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 254176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 254276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 254376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tracing: 2544ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2545ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 2546732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) { 254776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 254876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 254976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 255076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 255176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 255276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 255376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2554bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 255576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 255676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 255776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 255876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 255976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 256076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2561e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwab va_start(args, fmt); 2562b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (outf) { 2563b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath int n = vfprintf(outf, fmt, args); 2564ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (n < 0) { 2565ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (outf != stderr) 2566ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab perror(outfname == NULL 2567ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab ? "<writing to pipe>" : outfname); 2568ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab } else 2569b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath curcol += n; 2570b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath } 257176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_end(args); 257276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 257376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 257476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 257576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 25761201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintleader(struct tcb *tcp) 257776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2578732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (tcp_last) { 2579eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tcp_last->ptrace_errno) { 2580732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (tcp_last->flags & TCB_INSYSCALL) { 2581e62df004ce7a649c014fc0b5af058d56bc168920Denys Vlasenko tprintf(" <unavailable>) "); 2582eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tabto(acolumn); 2583732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 2584eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tprintf("= ? <unavailable>\n"); 2585eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp_last->ptrace_errno = 0; 2586732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } else if (!outfname || followfork < 2 || tcp_last == tcp) { 25877e0615f3aecc023e2756a83bdf113c5ceaac431dDenys Vlasenko tcp_last->flags |= TCB_REPRINT; 2588eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tprintf(" <unfinished ...>\n"); 2589732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 259076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 259176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman curcol = 0; 259276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 259376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%-5d ", tcp->pid); 259476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1 && !outfname) 259576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 259676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag) { 259776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char str[sizeof("HH:MM:SS")]; 259876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 259976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 260076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 260176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 260276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 260376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 260476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 260576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 260676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 260776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 260876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 260976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 261076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 261176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 261276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 261376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 261476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 261576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 261676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 261776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 261876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 261976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 262076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 262176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 262276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 262376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iflag) 262476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 262576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 262676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 262776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 26281201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotabto(int col) 262976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 263076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (curcol < col) 263176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%*s", col - curcol, ""); 263276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 263376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 263476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 2635ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoprinttrailer(void) 263676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 263776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\n"); 263876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 263976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 26409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2641ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 26429ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2643ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoint 2644ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkomp_ioctl(int fd, int cmd, void *arg, int size) 2645ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko{ 26469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct iovec iov[2]; 26479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int n = 1; 2648553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 26499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_base = &cmd; 26509ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_len = sizeof cmd; 26519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (arg) { 26529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ++n; 26539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_base = arg; 26549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_len = size; 26559ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 2656553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 2657ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko return writev(fd, iov, n); 26589ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 26599ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 26609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 2661