strace.c revision 82bb78c149a1b527f4ae7a764be29a9c85067b29
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> 4770b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath#include <dirent.h> 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef LINUX 50134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# include <asm/unistd.h> 5144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# if defined __NR_tkill 5244f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 53134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# else 54134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath /* kill() may choose arbitrarily the target task of the process group 55134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath while we later wait on a that specific TID. PID process waits become 56134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath TID task specific waits for a process under ptrace(2). */ 57134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 5844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# define my_tkill(tid, sig) kill((tid), (sig)) 59134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# endif 60134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 61134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath 627b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#if defined(IA64) && defined(LINUX) 637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 66bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 67bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#include <poll.h> 68bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 69bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 7076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stropts.h> 72ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 731d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#ifdef HAVE_SYS_UIO_H 749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <sys/uio.h> 759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 771d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 7896d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkoextern char **environ; 79418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern int optind; 80418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern char *optarg; 8196d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko 8276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8341c48227a86a176da333f713d5047240885f25ccRoland McGrathint debug = 0, followfork = 0; 84f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0; 853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */ 8675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP; 87e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levinint dtime = 0, xflag = 0, qflag = 0; 88e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levincflag_t cflag = CFLAG_NONE; 89b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0; 90ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/* 91ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option. 92ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice. 93ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's, 94ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process 95ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild 96ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID. 97ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases 98ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals, 99ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between, 100ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link. 101ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 102ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0; 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 10517f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvigint not_failing_only = 0; 10617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 1078a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */ 1088a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint show_fd_path = 0; 1098a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 1108a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* are we filtering traces based on paths? */ 1118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint tracing_paths = 0; 1128a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 113a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0; 114a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0; 11575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0; 116eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 117b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL; 118ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid; 119ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid; 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 122102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic int acolumn = DEFAULT_ACOLUMN; 123102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic char *acolumn_spaces; 124b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL; 125ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic FILE *outf; 126ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwabstatic int curcol; 127ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab; 1282b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize; 129ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname; 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1314c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkostatic int detach(struct tcb *tcp); 132e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic int trace(void); 133e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void); 134e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig); 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 13876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_SIG_ATOMIC_T */ 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_SIG_ATOMIC_T */ 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 145e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic struct tcb *pfd2tcb(int pfd); 146e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void reaper(int sig); 147e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void rebuild_pollv(void); 148ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstatic struct pollfd *pollv; 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poll_open(void); 153e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poller(int pfd); 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int fd; 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}; 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int proc_poll_pipe[2] = { -1, -1 }; 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 16576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 166ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 1679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLWRNORM 1689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 1699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLPRI 1709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 171bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 174cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 1778a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsusage: strace [-CdDffhiqrtttTvVxxy] [-a column] [-e expr] ... [-o file]\n\ 178de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ 1798a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards [-P path] [command [arg ...]]\n\ 180b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab or: strace -c [-D] [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ 181de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 183b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab-C -- like -c but also print regular output while processes are running\n\ 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-F -- attempt to follow vforks, -h -- print help message\n\ 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-T -- print time spent in each syscall, -V -- print version\n\ 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 1928a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 199ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 203de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 204de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2058a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 206de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath" /* this is broken, so don't document it 20717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 208de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath */ 209de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 21475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 21575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 21675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 21775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 21875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 21975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 22075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 22175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 22275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 22375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2243454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 22582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko char *msg; 22682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 22744d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 22882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 22982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We want to print entire message with single fprintf to ensure 23082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * message integrity if stderr is shared with other programs. 23182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * Thus we use vasprintf + single fprintf. 23282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko */ 23382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko msg = NULL; 23482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vasprintf(&msg, fmt, p); 23582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (msg) { 23682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 23782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 23882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 23982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s\n", progname, msg); 24082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko free(msg); 24182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } else { 24282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* malloc in vasprintf failed, try it without malloc */ 24382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: ", progname); 24482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vfprintf(stderr, fmt, p); 24582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 24682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, ": %s\n", strerror(err_no)); 24782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 24882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko putc('\n', stderr); 24982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } 25082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We don't switch stderr to buffered, thus fprintf(stderr) 25182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * always flushes its output and this is not necessary: */ 25282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* fflush(stderr); */ 25375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 25675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 25775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 25875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 25975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 2603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 26175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 2623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 26375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 26475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 26575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 26675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 26775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 26875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 26975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 27075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 27175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 27275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 27375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 27475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 27575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 27675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 27775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 27875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 27975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 28075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 28175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 28275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 28375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 28475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 2853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 2863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 2871d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void) 2881d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{ 2891d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko static bool recursed = 0; 2901d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (recursed) 2911d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko exit(1); 2921d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko recursed = 1; 2931d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko error_msg_and_die("Out of memory"); 2941d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko} 2951d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 29676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 29776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 29876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 29976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 30076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 305c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger/* Glue for systems without a MMU that cannot provide fork() */ 306c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#ifdef HAVE_FORK 307c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 0 308c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#else 309c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 1 310c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define fork() vfork() 311c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#endif 312c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger 3131f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 31410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 31510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3161f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 3171f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 3181f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 3191f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 3201f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 3211f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 3221f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 3231f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 3241f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 3251f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 32610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 32710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 32810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 32910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 3301f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 33110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3321f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 33310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 33410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 33510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 33610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * When strace is setuid executable, we have to swap uids 33710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * before and after filesystem and process management operations. 33810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 33910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 34010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinswap_uid(void) 34110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 34210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef SVR4 34310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin int euid = geteuid(), uid = getuid(); 34410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3457b609d5ba0852e6c56ba311350ebd4412361777bDenys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 346cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 34710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 34810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 34910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 35010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3514bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#if _LFS64_LARGEFILE 3524bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen64 3534bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#else 3544bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen 3554bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#endif 3564bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 35710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 3583d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostrace_fopen(const char *path) 35910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 36010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin FILE *fp; 36110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 36210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 3633d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko fp = fopen_for_output(path, "w"); 3643d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko if (!fp) 3653d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 36610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 3673d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko set_cloexec_flag(fileno(fp)); 36810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin return fp; 36910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 37010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3717dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenkostatic int popen_pid = 0; 37210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 37310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef _PATH_BSHELL 37410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin# define _PATH_BSHELL "/bin/sh" 37510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 37610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 37710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 37810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * We cannot use standard popen(3) here because we have to distinguish 37910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * popen child process from other processes we trace, and standard popen(3) 38010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * does not export its child's pid. 38110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 38210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 38310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstrace_popen(const char *command) 38410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3857dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko FILE *fp; 3867dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko int fds[2]; 38710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 38810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 38910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pipe(fds) < 0) 3907dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("pipe"); 39110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3927dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 39310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3947dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = vfork(); 3957dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == -1) 3967dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("vfork"); 39710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3987dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == 0) { 39910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* child */ 40010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin close(fds[1]); 4017dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (fds[0] != 0) { 4027dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (dup2(fds[0], 0)) 4037dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("dup2"); 4047dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 40510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 40610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin execl(_PATH_BSHELL, "sh", "-c", command, NULL); 4077dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 40810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 4097dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 4107dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko /* parent */ 4117dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 4127dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko swap_uid(); 4137dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko fp = fdopen(fds[1], "w"); 4147dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (!fp) 4151d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 4167dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko return fp; 41710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 41810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4193d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostatic void 42010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinnewoutf(struct tcb *tcp) 42110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 42210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (outfname && followfork > 1) { 4237a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char name[520 + sizeof(int) * 3]; 4247a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 4253d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko tcp->outf = strace_fopen(name); 42610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 42710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 42810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 42902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 43002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 43102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 43202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 43302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 43402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 43502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 43602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 43702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 4382e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * between PTRACE_ATTACH and wait4() on SIGSTOP. 439b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 44002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 44102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 44202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 44302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 444ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 445ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 446ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 447014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko perror_msg_and_die("fork"); 448ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 449ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 450ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 45175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 45275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 45375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 454ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 455ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 456ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 457ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 458ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 45975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 46075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 46175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 462ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 463ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 46402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 46502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 46644f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko 467d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Is this a process we should attach to, but not yet attached? */ 468d116a7338645af45090aecc331701e999148d284Denys Vlasenko if ((tcp->flags & (TCB_ATTACHED | TCB_STARTUP)) != TCB_ATTACHED) 469d116a7338645af45090aecc331701e999148d284Denys Vlasenko continue; /* no */ 470d116a7338645af45090aecc331701e999148d284Denys Vlasenko 471d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Reinitialize the output since it may have changed */ 47202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 4733d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko newoutf(tcp); 47402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 47502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 47602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (proc_open(tcp, 1) < 0) { 47702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "trouble opening proc file\n"); 47802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 47902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 48002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 48102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 48202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath# ifdef LINUX 483ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 4847a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 48502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 48602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 48702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 48802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 48902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 49002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 49102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct dirent *de; 492381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 49302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath while ((de = readdir(dir)) != NULL) { 494381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko struct tcb *cur_tcp; 495381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko int tid; 496381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 4977a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 49802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 49902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 50002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 50102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 50202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 503f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (ptrace(PTRACE_ATTACH, tid, (char *) 1, 0) < 0) { 50402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 505f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 506f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 507381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko continue; 508f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 509381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (debug) 510381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 511381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = tcp; 512381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (tid != tcp->pid) 513381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = alloctcb(tid); 514f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP; 51502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 51602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 517381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interactive) { 518381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 519381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interrupted) 520381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko goto ret; 521381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 522381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko } 5237a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 5247a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 52502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 52602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 52702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 52802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 52902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 5307a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 5317a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko? "Process %u attached with %u threads - interrupt to quit\n" 5327a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko: "Process %u attached - interrupt to quit\n", 53344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko tcp->pid, ntid); 53402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 535f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!(tcp->flags & TCB_STARTUP)) { 536f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* -p PID, we failed to attach to PID itself 537f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * but did attach to some of its sibling threads. 538f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Drop PID's tcp. 539f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 540f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko droptcb(tcp); 541f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 54202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 5437a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 5447a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 54544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# endif /* LINUX */ 54602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 54702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 54802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 54902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 55002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 551f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags |= TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP; 552f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 553f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 554ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 555ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 556ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 557ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It is our grandparent we trace, not a -p PID. 558ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Don't want to just detach on exit, so... 559ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 560ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags &= ~TCB_ATTACHED; 561ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 562ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 563ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 564ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 565ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 566ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 567ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 56802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 56902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 57002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 57102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath "Process %u attached - interrupt to quit\n", 57202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 573f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 57402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 57544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret: 57602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 57702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 57802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 57902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 58002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 5811201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 58202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 58302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct stat statbuf; 58402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 58502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 58602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int pid = 0; 58702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 58802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 58902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 59002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 59102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 59202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 593cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 59402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 59502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 59602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 59702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 59802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 59902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 60002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 60102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 60202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 60302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 60402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 60502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 60602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 60730145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 60802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 60902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 61002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 61102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(path, ':')) { 61202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath n = strchr(path, ':') - path; 61302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 61402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 61502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 61602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 61702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 61802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 61902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 62002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 62102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 62202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 62302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 62402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 62502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 62602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 62702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 62802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 62902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 63002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 63102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0 && 63202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 63302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 63402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 63502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 63602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 63702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 63802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 63902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 64002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 641cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 64202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 643a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin strace_child = pid = fork(); 644ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 645cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 646ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 64775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 64875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 649ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 650ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid = getpid(); 6512e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (outf != stderr) 6522e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko close(fileno(outf)); 65302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 6542e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# ifdef MIPS 65502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Kludge for SGI, see proc_open for details. */ 65602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = foobar; 65702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = 0; 65802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&sa.sa_mask); 65902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGINT, &sa, NULL); 6602e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# endif 6612e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# ifndef FREEBSD 66202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pause(); 6632e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# else 664014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko kill(pid, SIGSTOP); 6652e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# endif 66602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 667ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 668ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 669cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 670ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 671ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (debug) 672ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(pid, SIGSTOP); 67302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 67402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 675ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (username != NULL) { 67602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 67702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 67802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 67902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 68002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 68102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 68202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 68302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 68402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * It is important to set groups before we 68502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * lose privileges on setuid. 68602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 687ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (initgroups(username, run_gid) < 0) { 688ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("initgroups"); 689ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 690ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setregid(run_gid, run_egid) < 0) { 691ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setregid"); 692ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 693ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setreuid(run_uid, run_euid) < 0) { 694ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setreuid"); 69502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 69602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 697ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko else if (geteuid() != 0) 69802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 69902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 700ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 701ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 7022e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Induce a ptrace stop. Tracer (our parent) 703ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will resume us with PTRACE_SYSCALL and display 7042e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * the immediately following execve syscall. 7052e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Can't do this on NOMMU systems, we are after 7062e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * vfork: parent is blocked, stopping would deadlock. 707ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 708c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if (!strace_vforked) 7092e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko kill(pid, SIGSTOP); 710ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } else { 711ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct sigaction sv_sigchld; 712ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, NULL, &sv_sigchld); 713ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 714ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make sure it is not SIG_IGN, otherwise wait 715ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will not block. 716ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 717ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko signal(SIGCHLD, SIG_DFL); 718ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 719ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Wait for grandchild to attach to us. 720ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It kills child after that, and wait() unblocks. 721ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 722ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(3); 723ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko wait(NULL); 724ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(0); 725ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, &sv_sigchld, NULL); 726ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 72702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 72802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 72902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, argv); 730cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 73102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 732ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 7332e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We are the tracer */ 73475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 7352e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (!daemonized_tracer) { 7362e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 737f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!strace_vforked) 738f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags |= TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP; 739f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko else 740f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags |= TCB_STARTUP; 7412e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko } 7422e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko else { 7432e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 7442e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko strace_tracer_pid = getpid(); 7452e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* The tracee is our parent: */ 7462e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko pid = getppid(); 7472e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 7482e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We want subsequent startup_attach() to attach to it: */ 749ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags |= TCB_ATTACHED; 750ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 75102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 752ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (proc_open(tcp, 0) < 0) { 753cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("trouble opening proc file"); 75402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 7552e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko#endif 75602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 75702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 758b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#ifdef LINUX 75904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void kill_save_errno(pid_t pid, int sig) 76004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin{ 76104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin int saved_errno = errno; 76204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin 76304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin (void) kill(pid, sig); 76404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = saved_errno; 76504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin} 76604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin 767b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 768b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 769b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 770b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 771b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 77204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void 7733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 774b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 7752fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 7762fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 7772fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 7782fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 779b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 7805d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = fork(); 7815d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid < 0) 78204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 7835d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid == 0) { 78404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin pid = getpid(); 78504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) 78604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 78704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 78804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill(pid, SIGSTOP); 78904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (fork() < 0) 79004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 79104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin _exit(0); 792b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 793b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 794b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 795b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 796b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 79704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = 0; 798b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 79904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid <= 0) { 800b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 801b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 802b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin else if (errno == ECHILD) 803b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 80404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 80504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 80604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 80704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 80804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFEXITED(status)) { 80904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WEXITSTATUS(status)) { 81004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 81104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 81204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 81304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 81404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 81504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 81604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 81704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 81804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 81904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 82004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 82104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 82204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 82304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (!WIFSTOPPED(status)) { 82404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 82504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 82604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill(pid, SIGKILL); 82704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 82804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 829b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 830b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 8312fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 83204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 83304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 83404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 83504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_CONT doesn't work"); 83604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 83704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 838b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 83904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin switch (WSTOPSIG(status)) { 84004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGSTOP: 84104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 84204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 84304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 84404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 84504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGTRAP: 84604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 84704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin long msg = 0; 8482fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 84904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 85004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin NULL, (long) &msg) == 0) 85104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin expected_grandchild = msg; 852b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 85304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 85404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 85504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 85604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 85704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 858b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 859b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 86004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) { 861f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 86204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (debug) 86304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin fprintf(stderr, "ptrace_setoptions = %#x\n", 86404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin ptrace_setoptions); 86504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin return; 86604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 86704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACECLONE failed, " 86804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 869b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 8703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 8723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 8733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 8743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 8753454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 8763454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 8773454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 8783454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * _start: .globl _start 8793454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int3 8803454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $42, %ebx 8813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $1, %eax 8823454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int $0x80 8833454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 8843454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 8853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkostatic void 8863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 8873454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 88804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 88904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin PTRACE_O_TRACEEXEC; 8903454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 8913454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 8923454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8933454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 8943454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 89575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 8963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 8973454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 8983454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 8993454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 90075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 90104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 90204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 9033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 9043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 9053454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 9083454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 9093454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9103454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 9113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 9123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 9133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 9143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 91504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 91604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 91704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 91875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 91975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 92075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 92175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 92204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 92304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 92404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 92504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 92604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 92704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 9283454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 9303454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 93104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 93204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 9333454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 9353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 9363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 9373454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 9383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 9393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 9403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 94104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 94204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 94304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 9443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9453454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 9463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 9473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9483454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 94904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 95075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 9513454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9523454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 95575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 956f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 9573454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (debug) 958f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 959f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 9603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko return; 9613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 96304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 96404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 9653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 966b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#endif 967b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 96908b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levinmain(int argc, char *argv[]) 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 97176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 97276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 97306350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 97608b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 97708b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 97875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 97975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 980ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 981ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 9824f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 9831d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcbtab) 9841d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 9854f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 9861d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcp) 9871d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 9884f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 9894f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 990ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 1; 993138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 994138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 99976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 10008a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards "+cCdfFhiqrtTvVxyz" 1001ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 1002ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 1003ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 10048a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards "a:e:o:O:p:s:S:u:E:P:")) != EOF) { 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 1007e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 1008cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1009e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1010e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 1011e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 1012e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 1013e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 1014cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1015e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1016e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 101976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 102076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1021ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 1022ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 1023ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 1024ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 1025ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 102641c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 102706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 102806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 102976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 103176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 103576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iflag++; 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag++; 104076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rflag++; 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 104576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 104676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 104776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 104876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 104976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 105076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 105376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 10548a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 10558a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 10568a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 106076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 10619c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 106417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 106517f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 106617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 1069102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (acolumn < 0) 1070102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko error_msg_and_die("Bad column width '%s'", optarg); 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 107676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 107776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 108076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 10825d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = atoi(optarg); 10835d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid <= 0) { 1084cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("Invalid process id: '%s'", optarg); 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 108775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (pid == strace_tracer_pid) { 1088cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("I'm sorry, I can't let you do that, Dave."); 108976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1091418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloc_tcb(pid, 0); 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_ATTACHED; 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pflag_seen++; 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 10958a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 10968a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tracing_paths = 1; 10978a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (pathtrace_select(optarg)) { 1098cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Failed to select path '%s'", optarg); 10998a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards } 11008a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 110176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 1103dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (max_strlen < 0) { 1104cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Invalid -s argument: '%s'", optarg); 1105dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 110976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1113de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 11141d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (putenv(optarg) < 0) 11151d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1116de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 111976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1123102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces = malloc(acolumn + 1); 1124102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (!acolumn_spaces) 11251d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1126102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko memset(acolumn_spaces, ' ', acolumn); 1127102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces[acolumn] = '\0'; 1128102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko 1129d0c4c0cb881facd0ccf16b0c266875a8bf3e56aaRoland McGrath if ((optind == argc) == !pflag_seen) 1130ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1131ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1132d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao if (pflag_seen && daemonized_tracer) { 1133cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-D and -p are mutually exclusive options"); 1134d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1135d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 113606350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 113706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 113806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 1139cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (followfork > 1 && cflag) { 1140cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1141cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1142cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 114776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1148cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 114976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11505d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pent = getpwnam(username); 11515d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pent == NULL) { 1152cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 115376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 115876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 116076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11628044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#ifdef LINUX 116304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (followfork) 116404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin test_ptrace_setoptions_followfork(); 11653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko test_ptrace_setoptions_for_all(); 11668044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#endif 11678044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 117037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 117137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 117237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 117337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 117437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 117537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 11767dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (followfork > 1) 11777dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 11787dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko outf = strace_popen(outfname + 1); 117954b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 11803d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko else if (followfork <= 1) 11813d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko outf = strace_fopen(outfname); 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 118376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1184cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1185cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko static char buf[BUFSIZ]; 118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 1187cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 118837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname && optind < argc) { 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 0; 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1191369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1192b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 119354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* Valid states here: 119454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath optind < argc pflag_seen outfname interactive 119554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 1 0 0 1 119654cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 0 1 0 1 119754cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 1 0 1 0 119854cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 0 1 1 1 119954cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 120054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 120154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* STARTUP_CHILD must be called before the signal handlers get 120254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath installed below as they are inherited into the spawned process. 120354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Also we do not need to be protected by them as during interruption 120454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath in the STARTUP_CHILD mode we kill the spawned process anyway. */ 120554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath if (!pflag_seen) 120654cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath startup_child(&argv[optind]); 120776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTOU, &sa, NULL); 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTIN, &sa, NULL); 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) { 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGHUP); 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGINT); 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGQUIT); 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGPIPE); 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGTERM); 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interrupt; 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* POSIX signals on sunos4.1 are a little broken. */ 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = SA_INTERRUPT; 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 122876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 1232bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = reaper; 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGCHLD, &sa, NULL); 1235553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 1236553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 1237553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 1238553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 1239553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 1240553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 1241553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 1242553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 1243bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1245ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pflag_seen || daemonized_tracer) 124602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 124702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace() < 0) 124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 1251a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin fflush(NULL); 1252a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (exit_code > 0xff) { 1253a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Child was killed by a signal, mimic that. */ 1254a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code &= 0xff; 1255a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin signal(exit_code, SIG_DFL); 1256a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin raise(exit_code); 1257a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Paranoia - what if this signal is not fatal? 1258a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin Exit with 128 + signo then. */ 1259a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code += 128; 1260a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin } 1261a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit(exit_code); 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12642b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic void 1265418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoexpand_tcbtab(void) 12667b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 12677b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath /* Allocate some more TCBs and expand the table. 12687b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath We don't want to relocate the TCBs because our 12697b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath callers have pointers and it would be a pain. 12707b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath So tcbtab is a table of pointers. Since we never 12717b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath free the TCBs, we allocate a single chunk of many. */ 127218da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko int i = tcbtabsize; 127318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 127418da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 12751d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!newtab || !newtcbs) 12761d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 12777b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtabsize *= 2; 12787b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtab = newtab; 127918da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko while (i < tcbtabsize) 128018da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko tcbtab[i++] = newtcbs++; 12817b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath} 12827b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 128410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinalloc_tcb(int pid, int command_options_parsed) 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1289418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (nprocs == tcbtabsize) 1290418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko expand_tcbtab(); 1291418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1292ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1293ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 129518da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 1297381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko tcp->flags = TCB_INUSE; 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 1299a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#if SUPPORTED_PERSONALITIES > 1 1300a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin tcp->currpers = current_personality; 1301a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#endif 13028dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#ifdef USE_PROCFS 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 13048dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#endif 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 13061d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 13071d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 130810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (command_options_parsed) 130910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newoutf(tcp); 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("bug in alloc_tcb"); 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1316bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1318418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoproc_open(struct tcb *tcp, int attaching) 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char proc[32]; 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long arg; 1322bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef SVR4 132319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 132419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes sysset_t syscalls; 132576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t signals; 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fltset_t faults; 1327bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last_pfd; 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1332ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 13339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Open the process pseudo-files in /proc. */ 13349ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/ctl", tcp->pid); 13355d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd = open(proc, O_WRONLY|O_EXCL); 13365d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd < 0) { 13379ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 13389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 13399ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 13401f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 13419ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 13425d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL); 13435d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_stat < 0) { 13449ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 13459ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 13469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 13471f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_stat); 13489ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/as", tcp->pid); 13495d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_as = open(proc, O_RDONLY|O_EXCL); 13505d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_as < 0) { 13519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 13529ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 13539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 13541f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_as); 13559ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Open the process pseudo-file in /proc. */ 13570890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# ifndef FREEBSD 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 1359372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR|O_EXCL); 13600890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# else 1361bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 1362372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR); 13630890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# endif 1364372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab if (tcp->pfd < 0) { 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13681f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 13699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1370bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1371bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/regs", tcp->pid); 13725d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_reg = open(proc, O_RDONLY); 13735d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_reg < 0) { 1374bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../regs\", ...)"); 1375bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1376bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1377bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (cflag) { 1378bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 13795d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_status = open(proc, O_RDONLY); 13805d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_status < 0) { 1381bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../status\", ...)"); 1382bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1383bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1384bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 1385bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1386bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 139076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Wait for the child to pause. Because of a race 139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * condition we have to poll for the event. 139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1394b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_STATUS(tcp) < 0) { 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 1399cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko break; 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1402bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Stop the process so that we own the stop. */ 140416a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTOP"); 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1408553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PIOCSET 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 14129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 141476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 141576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 141776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 14189ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 141976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 142076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 142176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 1423553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1432bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1433bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 1434bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 1435bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCGFL"); 14365ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1437bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1438bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg &= ~PF_LINGER; 1439bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 14405ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko perror("PIOCSFL"); 14415ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1442bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1443bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !PIOCSET */ 1445bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 144619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable all syscall entries we care about. */ 144719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&syscalls); 144819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 144919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof syscalls) * CHAR_BIT) break; 1450b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_TRACE) praddset(&syscalls, i); 145119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 1452b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_execve); 145319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (followfork) { 1454b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork); 145519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_forkall 1456b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_forkall); 145719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 1458553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef SYS_fork1 1459b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork1); 146019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 146119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rfork1 1462b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rfork1); 146319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 146419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rforkall 1465b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rforkall); 146619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 146719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 146819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 146976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 147219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable the syscall exits. */ 147319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOSEXIT"); 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 147676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 147719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable signals we care about. */ 147819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&signals); 147919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 148019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof signals) * CHAR_BIT) break; 1481b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_SIGNAL) praddset(&signals, i); 148219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 14839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 148719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable faults we care about */ 148819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&faults); 148919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 149019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof faults) * CHAR_BIT) break; 1491b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_FAULT) praddset(&faults, i); 149219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 14939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 149476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1497bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1498bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* set events flags. */ 1499b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko arg = S_SIG | S_SCE | S_SCX; 1500b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 1501bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCBIS"); 1502bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1503bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1504bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 150776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The SGI PRSABORT doesn't work for pause() so 150976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * we send it a caught signal to wake it up. 151076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGINT); 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 1513553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef PRSABORT 151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 15159ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = PRSABORT; 1516b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1520553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 1521bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !MIPS*/ 1522bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1523bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 1524bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1525553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 1528b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_WSTOP(tcp) < 0) { 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 1533bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 153406602d99b72564e77600fc7c94e9ce8b78ec7085Denys Vlasenko get_scno(tcp); 153576989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath if (known_scno(tcp) == SYS_execve) 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set it running: maybe execve will be next. */ 1539bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 15409ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 15410890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 15420890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#else 15430890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 15440890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#endif 15450890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko { 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1549bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1550bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* handle the case where we "opened" the child before 1551bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman it did the kill -STOP */ 1552bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->status.PR_WHY == PR_SIGNALLED && 1553bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 1554bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1555553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15580890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#ifdef FREEBSD 15590890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko else { 1560553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (attaching < 2) { 15612e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* We are attaching to an already running process. 15622e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * Try to figure out the state of the process in syscalls, 15632e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * to handle the first event well. 15642e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * This is done by having a look at the "wchan" property of the 15652e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * process, which tells where it is stopped (if it is). */ 15662e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman FILE * status; 15672e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman char wchan[20]; /* should be enough */ 1568553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 15692e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 15702e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman status = fopen(proc, "r"); 15712e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status && 15722e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 15732e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman "%*d,%*d %*d,%*d %19s", wchan) == 1) && 15742e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 15752e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "stopevent")) { 15762e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* The process is asleep in the middle of a syscall. 15772e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman Fake the syscall entry event */ 15782e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 15792e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 15802e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman trace_syscall(tcp); 15812e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 15822e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status) 15832e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fclose(status); 15842e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } /* otherwise it's a fork being followed */ 1585bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1586bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1600bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1602e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstruct tcb * 160354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 160654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 160754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 160854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1610ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 161154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 161254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 161876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1619bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 162176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 162254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathfirst_used_tcb(void) 162354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath{ 162454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath int i; 162554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp; 162654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath for (i = 0; i < tcbtabsize; i++) { 162754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = tcbtab[i]; 162854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->flags & TCB_INUSE) 162954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return tcp; 163054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath } 163154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 163254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath} 163354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 163454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathstatic struct tcb * 16351201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkopfd2tcb(int pfd) 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1639ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = 0; i < tcbtabsize; i++) { 1640ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != pfd) 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1649bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 165076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 16521201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodroptcb(struct tcb *tcp) 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 165619cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 16581d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 16591d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1660eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 16618dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#ifdef USE_PROCFS 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != -1) { 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(tcp->pfd); 166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 16658dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko# ifdef FREEBSD 1666bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_reg != -1) { 1667bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_reg); 1668bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_reg = -1; 1669bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1670bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_status != -1) { 1671bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_status); 1672bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1673bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 16748dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko# endif 167519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko tcp->flags = 0; /* rebuild_pollv needs it */ 167619cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko rebuild_pollv(); 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16788dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#endif 1679eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1680822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 1682eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 168319cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko memset(tcp, 0, sizeof(*tcp)); 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16860a463880341945df08b6dc79134dc78cc38dc283Roland McGrath/* detach traced process; continue with sig 16870a463880341945df08b6dc79134dc78cc38dc283Roland McGrath Never call DETACH twice on the same process as both unattached and 16880a463880341945df08b6dc79134dc78cc38dc283Roland McGrath attached-unstopped processes give the same ESRCH. For unattached process we 16890a463880341945df08b6dc79134dc78cc38dc283Roland McGrath would SIGSTOP it and wait for its SIGSTOP notification forever. */ 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 16924c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkodetach(struct tcb *tcp) 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1695ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#ifdef LINUX 16961bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int status, catch_sigstop; 1697ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 1700840d85b3e50cea9f28aedd23af94742c2a60265aAndreas Schwab clearbpt(tcp); 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 17057bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 17067bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 17087bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 17097bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 17107bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 17117bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 171202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 1713f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * We did PTRACE_ATTACH but possibly didn't see the expected SIGSTOP. 1714f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * We must catch exactly one as otherwise the detached process 1715f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * would be left stopped (process state T). 171602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 1717f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 17184c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 17195d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (error == 0) { 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* On a clear day, you can see forever. */ 17217bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 17227bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (errno != ESRCH) { 17237bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath /* Shouldn't happen. */ 17247bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: ptrace(PTRACE_DETACH, ...)"); 17257bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 172644f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko else if (my_tkill(tcp->pid, 0) < 0) { 17277bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 17287bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: checking sanity"); 17297bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 173044f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) { 17317bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 17327bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: stopping child"); 17337bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 173402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 173502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath catch_sigstop = 1; 1736ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (catch_sigstop) { 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 17387508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 17397508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 17407508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 17417508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 17427508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 17447508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 17457508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 17467508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 17477508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 17487508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 17497508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 17507508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 17517508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 17527508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 17537508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 17547508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 17557508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WCLONE, 17567508cb4678141d146d819120f6b5b428c103882eRoland McGrath NULL) < 0) { 17577508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 17587508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 17597508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 17607508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 17617508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 17627508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 17637508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17657508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 17714c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, 0); 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 177376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1774732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, 177575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko WSTOPSIG(status) == syscall_trap_sig ? 0 1776732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko : WSTOPSIG(status)); 1777732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (error < 0) 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1780ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } 17817bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* LINUX */ 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 17854c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko error = ptrace_restart(PTRACE_DETACH, tcp, 0); 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 179076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 1792a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath 179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 179476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1796bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1798e5e60858063f214fcd7860f50f8bcb46f951f9abDmitry V. Levinstatic void reaper(int sig) 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 180376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1807bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18101201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 181176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 181276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1815ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1816ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && 182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (!outfname || followfork < 2 || tcp_last == tcp)) { 182460fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unfinished ...>"); 1825ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 182776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 18284c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko detach(tcp); 182976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGTERM); 183276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 183576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 183676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 183776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 183876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18391201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 184076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 184176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interrupted = 1; 184276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 184376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 184476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 184576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18466d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 18496d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 185076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 18521201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrerror(int err_no) 185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185635aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 185735aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko sprintf(buf, "Unknown error %d", err_no); 185876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186035aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko return sys_errlist[err_no]; 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18678f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 18686d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 18708f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 18718f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 18728f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 18751201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrsignal(int sig) 187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1892bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 18951201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkorebuild_pollv(void) 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 189776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 189876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1899cfd364b011e170377ae002551c4391c01f51acbfDenys Vlasenko free(pollv); 1900cfd364b011e170377ae002551c4391c01f51acbfDenys Vlasenko pollv = malloc(nprocs * sizeof(pollv[0])); 19011d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!pollv) 19021d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1903ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 1904ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = j = 0; i < tcbtabsize; i++) { 1905ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[j].fd = tcp->pfd; 19099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollv[j].events = POLLWANT; 191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j++; 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j != nprocs) { 1913cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("proc miscount"); 191476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 19201201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll_open(void) 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 1925cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("pipe"); 192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 19281f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(proc_poll_pipe[i]); 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 19331201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll(struct pollfd *pollv, int nfds, int timeout) 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19395d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo)); 19405d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (n < 0) 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 1943cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("panic: short read: %d", n); 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = 0; 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 195376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 195476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 19561201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkowakeup_handler(int sig) 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 19611201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poller(int pfd) 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t blocked_set, empty_set; 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 1969bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1970bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct procfs_status pfs; 1971bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (fork()) { 197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 1975cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = wakeup_handler; 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGUSR1, &sa, NULL); 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGUSR1); 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 1998cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("getrlimit(RLIMIT_NOFILE, ...)"); 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = rl.rlim_cur; 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i != pfd && i != proc_poll_pipe[1]) 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(i); 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.fd = pfd; 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.pid = getpid(); 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 2009bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 20105ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 20115ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#else 20125ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 20135ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#endif 20149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman { 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (errno) { 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLERR; 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 202176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLHUP; 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 20309ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollinfo.revents = POLLWANT; 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 20479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The previous process is ready to run again. We'll 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * let it do so if it is currently in a syscall. This 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * heuristic improves the readability of the trace. 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[last].fd); 2054b88f96129f8ebc064d490c8c161bcbc925d938c8Denys Vlasenko if (tcp && exiting(tcp)) 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[j].revents & (POLLHUP | POLLERR)) { 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[j].fd); 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) { 2064cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("lost proc"); 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 20699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pollv[j].revents & POLLWANT) { 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last = j; 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[j].fd; 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2074cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("nothing ready"); 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 20781201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20809dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 2081d870b3c31a0139b335a66a829169bacc74624c44John Hughes struct tcb *in_syscall = NULL; 20829dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pfd; 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int what; 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int ioctl_result = 0, ioctl_errno = 0; 20879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman long arg; 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (nprocs) { 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 1: 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] == -1) { 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 210154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = first_used_tcb(); 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = tcp->pfd; 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* fall through ... */ 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_POLLABLE_PROCFS 21149dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 21159dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman /* On some systems (e.g. UnixWare) we get too much ugly 21169dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman "unfinished..." stuff when multiple proceses are in 21179dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman syscalls. Here's a nasty hack */ 2118553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 21199dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (in_syscall) { 21209dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman struct pollfd pv; 21219dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp = in_syscall; 21229dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = NULL; 21239dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.fd = tcp->pfd; 21249dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.events = POLLWANT; 21255d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko what = poll(&pv, 1, 1); 21265d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (what < 0) { 21279dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (interrupted) 21289dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman return 0; 21299dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman continue; 21309dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 21319dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 21329dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman goto FOUND; 21339dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 21349dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 21359dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 21369dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 213776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 213876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 213976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 214076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_POLLABLE_PROCFS */ 214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll(pollv, nprocs, INFTIM) < 0) { 214476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 21565d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pfd2tcb(pfd); 21575d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 2158cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("unknown pfd: %u", pfd); 215976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2160b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#ifdef POLL_HACK 21619dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman FOUND: 2162b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#endif 216376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Get the status of the process. */ 216476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!interrupted) { 2165bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 2166b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2167bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 2168bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* Thanks to some scheduling mystery, the first poller 2169bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sometimes waits for the already processed end of fork 2170bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 2171bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (proc_poll_pipe[0] != -1) 2172b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_STATUS(tcp); 2173bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else 2174b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2175553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 217676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ioctl_errno = errno; 217776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 217876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) { 217976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) 218076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGKILL); 218176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 218276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGUSR1); 218376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 218576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 218776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 218976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 219076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 219276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) { 219376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Find out what happened if it failed. */ 219476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (ioctl_errno) { 219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2198bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2199bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOTTY: 2200553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 220276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2205cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCWSTOP"); 220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 220776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 22092e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifdef FREEBSD 22102e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 22112e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* discard first event for a syscall we never entered */ 2212b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko IOCTL(tcp->pfd, PIOCRUN, 0); 22132e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 22142e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 2215553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2216553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 221776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 221976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 222076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 2222ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 222376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval stime; 2226bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2227bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman char buf[1024]; 2228bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int len; 2229bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 22305d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0); 22315d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (len > 0) { 2232bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman buf[len] = '\0'; 2233bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sscanf(buf, 2234bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 2235bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman &stime.tv_sec, &stime.tv_usec); 2236bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 2237bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 2238553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else /* !FREEBSD */ 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 2241bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 224276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 224376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = stime; 224476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22459ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman what = tcp->status.PR_WHAT; 22469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman switch (tcp->status.PR_WHY) { 2247bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_REQUESTED: 22499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) { 22509ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 225176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2252cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2256bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSENTRY: 22589dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 22599dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = tcp; 22609dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2263cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 2267e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 2268e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_SIGNAL)) { 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) ---", 2271ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(what), strsignal(what)); 2272ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 22735826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#ifdef PR_INFO 22745826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes if (tcp->status.PR_INFO.si_signo == what) { 22755826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printleader(tcp); 227660fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" siginfo="); 22775826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printsiginfo(&tcp->status.PR_INFO, 1); 2278ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 22795826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes } 22805826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#endif 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 228376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 2284e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAGS_ONLY_STATS 2285e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_FAULT)) { 228676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("=== FAULT %d ===", what); 2288ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 228976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2291bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2292bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case 0: /* handle case we polled for nothing */ 22935ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko continue; 2294553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 229576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2296cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("odd stop %d", tcp->status.PR_WHY); 229776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 229876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2299ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2300ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 23019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 2302553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 2303b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 2304553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 2305b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 2306553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2307372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab { 2308cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCRUN"); 230976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 231076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 231176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 231276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 231376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2314bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 231576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2316eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstatic int 2317eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathtrace() 231876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 231976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 232076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int wait_errno; 23216cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko int status, sig; 232276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 232376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 232476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 232526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko struct rusage *rup = cflag ? &ru : NULL; 232626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 2327eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath static int wait4_options = __WALL; 232826d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif 232976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 233076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2331eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath while (nprocs != 0) { 2332222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 2333eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2334eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2335eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 233676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 233726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 233826d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 23395bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 23402f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 23412f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 234226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 23432f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 23445bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 23452f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 234626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, __WCLONE, rup); 234726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2348cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg("wait4(__WCLONE) failed"); 23492f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 23502f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 235126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# else 235226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, 0, rup); 235326d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif /* __WALL */ 235476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 235576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 235676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 235726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko#endif 235876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 2359eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2360eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 236176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 236226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2363eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath switch (wait_errno) { 2364eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case EINTR: 236576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2366eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case ECHILD: 236776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 236876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 236976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 237076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 237176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 237276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2373eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2374eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath default: 2375eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = wait_errno; 2376eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("strace: wait"); 2377eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 237876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 237976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 238010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 238110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (WIFEXITED(status) || WIFSIGNALED(status)) 23827dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 238310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 238410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 23851d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) { 23861d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 23871d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef LINUX 23881d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko unsigned ev = (unsigned)status >> 16; 23891d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (ev) { 23901d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko static const char *const event_names[] = { 23911d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 23921d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 23931d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 23941d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 23951d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 23961d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 23971d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko }; 23981d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko const char *e; 23991d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (ev < ARRAY_SIZE(event_names)) 24001d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko e = event_names[ev]; 24011d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko else { 24021d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "?? (%u)", ev); 24031d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko e = buf; 24041d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 24051d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " PTRACE_EVENT_%s", e); 24061d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 24071d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 24081d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 24091d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 24101d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 24111d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 24121d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 24131d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 24141d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 24151d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 24161d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 24171d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 24181d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 24191d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 24201d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 24211d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 24225bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 24231d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 24241d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 24255bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 24261d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf); 24271d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 242876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 242976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pid' in our table. */ 24305d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pid2tcb(pid); 24315d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 2432e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef LINUX 243341c48227a86a176da333f713d5047240885f25ccRoland McGrath if (followfork) { 2434e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 2435e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 2436e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 2437e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 2438e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 2439e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 2440e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 2441e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 2442e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 2443418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloctcb(pid); 2444f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | TCB_IGNORE_ONE_SIGSTOP; 2445e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 2446833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko fprintf(stderr, "Process %d attached\n", 2447e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 24488b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 2449e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 2450e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 2451e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 2452eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#endif 2453e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 2454e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 2455e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_CONT, pid, (char *) 1, 0); 2456cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Unknown pid: %u", pid); 2457e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 245876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2459eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* set current output file */ 2460eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath outf = tcp->outf; 2461ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 2462eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#ifdef LINUX 246313d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 246476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 246576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 246676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 246713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#endif 2468eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 246976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 2470a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2471a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 2472e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 247376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 247476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 247513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 24762efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath tprintf("+++ killed by %s %s+++", 24772efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 247813d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 247913d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 248013d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko tprintf("+++ killed by %s +++", 248113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 24822efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 2483ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 248476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24855e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 248676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 248776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 248876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 248976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 2490a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2491a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 24920a396906981a03f93c07cb912585d0679dd50899Roland McGrath if (tcp == tcp_last) { 24937a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL) 24940a396906981a03f93c07cb912585d0679dd50899Roland McGrath tprintf(" <unfinished ... exit status %d>\n", 24950a396906981a03f93c07cb912585d0679dd50899Roland McGrath WEXITSTATUS(status)); 24960a396906981a03f93c07cb912585d0679dd50899Roland McGrath tcp_last = NULL; 24970a396906981a03f93c07cb912585d0679dd50899Roland McGrath } 249819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 249919cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 250019cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko tprintf("+++ exited with %d +++", WEXITSTATUS(status)); 250119cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printtrailer(); 250219cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 25035e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 250476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 250576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 250676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 250776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 250876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 250976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 251076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 251176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 251276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2513f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this the very first time we see this tracee stopped? */ 2514f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (tcp->flags & TCB_STARTUP) { 2515f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (debug) 2516f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 251776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 251802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 251976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 252002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 25212ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * parent through fork(). 252276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 25236cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (clearbpt(tcp) < 0) { 25246cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko /* Pretty fatal */ 252576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 252676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 252776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 252876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 252976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2530ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#ifdef LINUX 253144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace_setoptions) { 253244f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (debug) 253344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 253444f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 253544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (errno != ESRCH) { 253644f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko /* Should never happen, really */ 253744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 25383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 25393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 25403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2541ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#endif 2542f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2543f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2544f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (((unsigned)status >> 16) != 0) { 2545f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Ptrace event (we ignore all of them for now) */ 2546f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko goto restart_tracee_with_sig_0; 2547f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2548f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2549f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko sig = WSTOPSIG(status); 2550f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2551f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this post-attach SIGSTOP? 2552f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Interestingly, the process may stop 2553f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * with STOPSIG equal to some other signal 2554f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * than SIGSTOP if we happend to attach 2555f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * just before the process takes a signal. 2556f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 2557f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2558f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (debug) 2559f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2560f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 25616cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee_with_sig_0; 256276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 256376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25646cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (sig != syscall_trap_sig) { 2565e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 25666cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko && (qual_flags[sig] & QUAL_SIGNAL)) { 2567c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin siginfo_t si; 2568c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 25696b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long pc = 0; 25706b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long psr = 0; 25717b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2572932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IPSR, &psr); 2573932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IIP, &pc); 25747b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 25756b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PSR_RI 41 25767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 25776b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR " @ %lx" 25782ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG , pc 25796b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin#else 25802ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_STR "" 25812ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG /* nothing */ 25827b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 258376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 2584436d892212dd56401bacf818a238333d30f85c6aDmitry V. Levin if (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) == 0) { 258560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("--- "); 25866b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin printsiginfo(&si, verbose(tcp)); 25876b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin tprintf(" (%s)" PC_FORMAT_STR " ---", 25886cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig) 25896b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 25906b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin } else 25916b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin tprintf("--- %s by %s" PC_FORMAT_STR " ---", 25926cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig), 25936cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko signame(sig) 25946b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 2595ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko printtrailer(); 25965e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 259776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 25986cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee; 259976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26002ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 26012ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* We handled quick cases, we are permitted to interrupt now. */ 260202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 260302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return 0; 26042ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 26052ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* This should be syscall entry or exit. 26062ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * (Or it still can be that pesky post-execve SIGTRAP!) 26072ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * Handle it. 26082ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko */ 2609eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2610eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* ptrace() failed in trace_syscall() with ESRCH. 2611eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2612eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Observed case: exit_group() terminating 2613f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * all processes in thread group. 2614ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko */ 2615ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (tcp->flags & TCB_ATTACHED) { 2616eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tcp_last) { 2617eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Do we have dangling line "syscall(param, param"? 2618178de007d14f3ae890117b540def9cf14bcb61feDenys Vlasenko * Finish the line then. 2619eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath */ 2620eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp_last->flags |= TCB_REPRINT; 262160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unfinished ...>"); 2622eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath printtrailer(); 26235e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 2624eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 2625f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* We assume that ptrace error was caused by process death. 2626f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * We used to detach(tcp) here, but since we no longer 2627f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * implement "detach before death" policy/hack, 2628f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * we can let this process to report its death to us 2629f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * normally, via WIFEXITED or WIFSIGNALED wait status. 2630f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko */ 2631ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } else { 2632f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* It's our real child (and we also trace it) */ 2633f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* my_tkill(pid, SIGKILL); - why? */ 2634f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* droptcb(tcp); - why? */ 263576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 263676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 263776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 26386cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0: 26396cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko sig = 0; 26406cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee: 2641ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2642ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 26436cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 264476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 264576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 264676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 264776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 264876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 264976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 265076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2651bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 265276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 265376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 265476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 265576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 265676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 265776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2658e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwab va_start(args, fmt); 2659b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (outf) { 2660b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath int n = vfprintf(outf, fmt, args); 2661ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (n < 0) { 2662ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (outf != stderr) 2663ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab perror(outfname == NULL 2664ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab ? "<writing to pipe>" : outfname); 2665ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab } else 2666b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath curcol += n; 2667b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath } 266876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_end(args); 26695940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko} 26705940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko 26715940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenkovoid 26725940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenkotprints(const char *str) 26735940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko{ 26745940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (outf) { 26755940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko int n = fputs(str, outf); 26765940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (n >= 0) { 26775940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko curcol += strlen(str); 26785940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko return; 26795940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko } 26805940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (outf != stderr) 26815940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko perror(outfname == NULL 26825940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko ? "<writing to pipe>" : outfname); 26835940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko } 268476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 268576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 268676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 26871201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintleader(struct tcb *tcp) 268876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2689732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (tcp_last) { 2690eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (tcp_last->ptrace_errno) { 2691732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (tcp_last->flags & TCB_INSYSCALL) { 269260fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unavailable>) "); 2693102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko tabto(); 2694732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 269560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("= ? <unavailable>\n"); 2696eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath tcp_last->ptrace_errno = 0; 2697732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } else if (!outfname || followfork < 2 || tcp_last == tcp) { 26987e0615f3aecc023e2756a83bdf113c5ceaac431dDenys Vlasenko tcp_last->flags |= TCB_REPRINT; 269960fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unfinished ...>\n"); 2700732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 270176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 270276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman curcol = 0; 270376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 270476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%-5d ", tcp->pid); 270576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1 && !outfname) 270676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 270776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag) { 270876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char str[sizeof("HH:MM:SS")]; 270976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 271076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 271176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 271276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 271376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 271476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 271576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 271676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 271776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 271876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 271976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 272076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 272176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 272276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 272376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 272476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 272576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 272676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 272776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 272876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 272976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 273076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 273176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 273276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 273376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 273476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iflag) 273576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 273676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 273776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 273876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 2739102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkotabto(void) 274076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2741102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (curcol < acolumn) 27425940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko tprints(acolumn_spaces + curcol); 274376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 274476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 274576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 2746ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoprinttrailer(void) 274776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 274860fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("\n"); 274976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 275076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 27519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2752ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 27539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2754ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoint 2755ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkomp_ioctl(int fd, int cmd, void *arg, int size) 2756ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko{ 27579ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct iovec iov[2]; 27589ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int n = 1; 2759553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 27609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_base = &cmd; 27619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_len = sizeof cmd; 27629ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (arg) { 27639ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ++n; 27649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_base = arg; 27659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_len = size; 27669ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 2767553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 2768ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko return writev(fd, iov, n); 27699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 27709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 27719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 2772