strace.c revision 3521884c91d0bbd8e796d72619da40bdad95789c
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> 48f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#include <sys/utsname.h> 4976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 50134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef LINUX 51134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# include <asm/unistd.h> 5244f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# if defined __NR_tkill 5344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 54134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# else 55134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath /* kill() may choose arbitrarily the target task of the process group 56134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath while we later wait on a that specific TID. PID process waits become 57134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath TID task specific waits for a process under ptrace(2). */ 58134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 5944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# define my_tkill(tid, sig) kill((tid), (sig)) 60134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# endif 61134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 62134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath 637b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#if defined(IA64) && defined(LINUX) 647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 67bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 68bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#include <poll.h> 69bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 70bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 7176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stropts.h> 73ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 741d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#ifdef HAVE_SYS_UIO_H 759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <sys/uio.h> 769ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 781d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 7996d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkoextern char **environ; 80418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern int optind; 81418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern char *optarg; 8296d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8441c48227a86a176da333f713d5047240885f25ccRoland McGrathint debug = 0, followfork = 0; 85f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0; 863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */ 8775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP; 88e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levinint dtime = 0, xflag = 0, qflag = 0; 89e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levincflag_t cflag = CFLAG_NONE; 90aa6ec415c1a9b8a886bddf0db765b5de365a8360Denys Vlasenkostatic int iflag = 0, pflag_seen = 0, rflag = 0, tflag = 0; 91b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 92b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* -I n */ 93b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkoenum { 94b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NOT_SET = 0, 95b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 96b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 97b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 98b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 99b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko NUM_INTR_OPTS 100b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko}; 101b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkostatic int opt_intr; 102b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* We play with signal mask only if this mode is active: */ 103b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko#define interactive (opt_intr == INTR_WHILE_WAIT) 104b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 105ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/* 106ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option. 107ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice. 108ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's, 109ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process 110ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild 111ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID. 112ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases 113ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals, 114ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between, 115ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link. 116ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 117ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0; 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 12031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 12131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize (post_attach_sigstop == 0) 12231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 12331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 12431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize 0 12531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 12631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 12717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 12817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvigint not_failing_only = 0; 12917f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 1308a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */ 1318a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint show_fd_path = 0; 1328a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 1338a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* are we filtering traces based on paths? */ 1348a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwardsint tracing_paths = 0; 1358a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 136a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0; 137a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0; 13875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0; 139eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 140b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL; 141ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid; 142ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid; 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 145102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic int acolumn = DEFAULT_ACOLUMN; 146102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic char *acolumn_spaces; 147b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL; 148ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic FILE *outf; 149000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenkostruct tcb *printing_tcp = NULL; 150ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwabstatic int curcol; 151ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab; 1522b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize; 153ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname; 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkostatic char *os_release; /* from uname() */ 156f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1574c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkostatic int detach(struct tcb *tcp); 158e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic int trace(void); 159e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void); 160e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig); 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 165a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#else 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 167a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#endif 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic struct tcb *pfd2tcb(int pfd); 172e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void reaper(int sig); 173e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void rebuild_pollv(void); 174ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstatic struct pollfd *pollv; 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poll_open(void); 179e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void proc_poller(int pfd); 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int fd; 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int proc_poll_pipe[2] = { -1, -1 }; 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 192ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 1939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLWRNORM 1949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 1959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLPRI 1969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 197bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 200cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 203b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkousage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 204b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 205b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko [-P path] [PROG [ARGS]]]\n\ 206b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 207b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko [PROG [ARGS]]]\n\ 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 209b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab-C -- like -c but also print regular output while processes are running\n\ 210b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-F -- attempt to follow vforks, -h -- print help message\n\ 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 214b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-I interruptible\n\ 215b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1: no signals are blocked\n\ 216b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 2: fatal signals are blocked while decoding syscall (default)\n\ 217b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 218b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 219b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-T -- print time spent in each syscall, -V -- print version\n\ 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 2258a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 235de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 236de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2378a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 238de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath" /* this is broken, so don't document it 23917f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 240de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath */ 241de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 24575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 24675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 24775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 24875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 24975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 25075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 25175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 25275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 25375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2563454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 25782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko char *msg; 25882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 25944d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 26082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 26182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We want to print entire message with single fprintf to ensure 26282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * message integrity if stderr is shared with other programs. 26382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * Thus we use vasprintf + single fprintf. 26482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko */ 26582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko msg = NULL; 266cfad543087d98c5313fd7f006c0de69a1d87dc8eDenys Vlasenko if (vasprintf(&msg, fmt, p) >= 0) { 26782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 26882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 26982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 27082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s\n", progname, msg); 27182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko free(msg); 27282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } else { 27382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* malloc in vasprintf failed, try it without malloc */ 27482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: ", progname); 27582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vfprintf(stderr, fmt, p); 27682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 27782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, ": %s\n", strerror(err_no)); 27882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 27982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko putc('\n', stderr); 28082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } 28182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We don't switch stderr to buffered, thus fprintf(stderr) 28282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * always flushes its output and this is not necessary: */ 28382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* fflush(stderr); */ 28475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 28575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 28675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 28775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 28875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 28975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 29075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 2913454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 29275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 2933454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 29475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 29575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 29675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 29775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 29875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 29975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 30075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 30175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 30275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 30375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 30475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 30575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 30675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 30775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 30875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 30975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 31075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 31175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 31275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 31375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 31475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 31575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 3163454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 3173454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 3181d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void) 3191d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{ 3201d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko static bool recursed = 0; 3211d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (recursed) 3221d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko exit(1); 3231d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko recursed = 1; 3241d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko error_msg_and_die("Out of memory"); 3251d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko} 3261d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 336c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger/* Glue for systems without a MMU that cannot provide fork() */ 337c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#ifdef HAVE_FORK 338c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 0 339c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#else 340c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 1 341c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define fork() vfork() 342c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#endif 343c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger 34431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 34531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int 34631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkoptrace_attach_or_seize(int pid) 34731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 34831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int r; 34931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) 35031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return ptrace(PTRACE_ATTACH, pid, 0, 0); 35131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 35231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (r) 35331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 35431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 35531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 35631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 35731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 35831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 35931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 36031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 3611f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 36210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 36310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3641f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 3651f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 3661f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 3671f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 3681f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 3691f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 3701f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 3711f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 3721f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 3731f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 37410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 37510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 37610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 37710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 3781f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 37910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3801f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 38110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 38210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 38310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 38410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * When strace is setuid executable, we have to swap uids 38510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * before and after filesystem and process management operations. 38610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 38710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 38810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinswap_uid(void) 38910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 39010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef SVR4 39110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin int euid = geteuid(), uid = getuid(); 39210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3937b609d5ba0852e6c56ba311350ebd4412361777bDenys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 394cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 39510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 39610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 39710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 39810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3994bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#if _LFS64_LARGEFILE 4004bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen64 4014bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#else 4024bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen 4034bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#endif 4044bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 40510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 4063d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostrace_fopen(const char *path) 40710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 40810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin FILE *fp; 40910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 41010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 4113d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko fp = fopen_for_output(path, "w"); 4123d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko if (!fp) 4133d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 41410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 4153d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko set_cloexec_flag(fileno(fp)); 41610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin return fp; 41710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 41810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4197dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenkostatic int popen_pid = 0; 42010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 42110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef _PATH_BSHELL 42210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin# define _PATH_BSHELL "/bin/sh" 42310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 42410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 42510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 42610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * We cannot use standard popen(3) here because we have to distinguish 42710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * popen child process from other processes we trace, and standard popen(3) 42810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * does not export its child's pid. 42910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 43010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 43110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstrace_popen(const char *command) 43210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 4337dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko FILE *fp; 4347dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko int fds[2]; 43510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 43610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 43710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pipe(fds) < 0) 4387dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("pipe"); 43910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4407dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 44110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4427dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = vfork(); 4437dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == -1) 4447dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("vfork"); 44510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4467dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == 0) { 44710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* child */ 44810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin close(fds[1]); 4497dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (fds[0] != 0) { 4507dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (dup2(fds[0], 0)) 4517dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("dup2"); 4527dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 45310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 45410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin execl(_PATH_BSHELL, "sh", "-c", command, NULL); 4557dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 45610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 4577dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 4587dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko /* parent */ 4597dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 4607dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko swap_uid(); 4617dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko fp = fdopen(fds[1], "w"); 4627dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (!fp) 4631d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 4647dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko return fp; 46510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 46610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4673d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostatic void 46810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinnewoutf(struct tcb *tcp) 46910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 47010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (outfname && followfork > 1) { 4717a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char name[520 + sizeof(int) * 3]; 4727a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 4733d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko tcp->outf = strace_fopen(name); 47410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 47510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 47610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 47702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 47802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 47902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 48002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 48102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 48202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 48302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 48402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 48502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 4862e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * between PTRACE_ATTACH and wait4() on SIGSTOP. 487b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 48802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 48902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 49002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 49102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 492ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 493ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 494ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 495014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko perror_msg_and_die("fork"); 496ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 497ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 498ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 49975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 50075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 50175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 502ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 503ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 504ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 505ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 506ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 50775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 50875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 50975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 510ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 511ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 51202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 51302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 51444f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko 515d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Is this a process we should attach to, but not yet attached? */ 516d116a7338645af45090aecc331701e999148d284Denys Vlasenko if ((tcp->flags & (TCB_ATTACHED | TCB_STARTUP)) != TCB_ATTACHED) 517d116a7338645af45090aecc331701e999148d284Denys Vlasenko continue; /* no */ 518d116a7338645af45090aecc331701e999148d284Denys Vlasenko 519d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Reinitialize the output since it may have changed */ 52002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 5213d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko newoutf(tcp); 52202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 52302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 52402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (proc_open(tcp, 1) < 0) { 52502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "trouble opening proc file\n"); 52602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 52702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 52802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 52902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 53002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath# ifdef LINUX 531ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 5327a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 53302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 53402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 53502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 53602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 53702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 53802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 53902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct dirent *de; 540381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 54102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath while ((de = readdir(dir)) != NULL) { 542381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko struct tcb *cur_tcp; 543381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko int tid; 544381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 5457a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 54602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 54702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 54802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 54902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 55002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 55131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tid) < 0) { 55202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 553f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 554f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 555381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko continue; 556f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 557381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (debug) 558381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 559381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = tcp; 560381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (tid != tcp->pid) 561381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = alloctcb(tid); 56231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 56302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 56402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 565381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interactive) { 566381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 567381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interrupted) 568381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko goto ret; 569381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 570381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko } 5717a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 5727a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 57302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 57402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 57502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 57602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 57702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 5787a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 5797a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko? "Process %u attached with %u threads - interrupt to quit\n" 5807a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko: "Process %u attached - interrupt to quit\n", 58144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko tcp->pid, ntid); 58202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 583f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!(tcp->flags & TCB_STARTUP)) { 584f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* -p PID, we failed to attach to PID itself 585f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * but did attach to some of its sibling threads. 586f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Drop PID's tcp. 587f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 588f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko droptcb(tcp); 589f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 59002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 5917a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 5927a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 59344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko# endif /* LINUX */ 59431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tcp->pid) < 0) { 59502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 59602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 59702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 59802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 59931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tcp->flags |= TCB_STARTUP | post_attach_sigstop; 600f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko if (debug) 601f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 602ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 603ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 604ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 605ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It is our grandparent we trace, not a -p PID. 606ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Don't want to just detach on exit, so... 607ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 608ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags &= ~TCB_ATTACHED; 609ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 610ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 611ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 612ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 613ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 614ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 615ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 61602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 61702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 61802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 61902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath "Process %u attached - interrupt to quit\n", 62002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 621f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 62202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 62344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret: 62402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 62502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 62602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 62702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 62802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 6291201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 63002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 63102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct stat statbuf; 63202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 63302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 63402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int pid = 0; 63502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 63602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 63702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 63802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 63902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 64002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 641cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 64202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 64302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 64402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 64502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 64602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 64702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 64802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 64902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 65002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 65102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 65202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 65302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 65402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 65530145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 65602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 65702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 65802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 65902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(path, ':')) { 66002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath n = strchr(path, ':') - path; 66102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 66202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 66402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 66502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 66602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 66702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 66802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 66902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 67002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 67102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 67202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 67302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 67402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 67502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 67602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 67702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 67802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 67902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0 && 68002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 68102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 68202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 68302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 68402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 68502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 68602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 68702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 68802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 689cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 69002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 691a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin strace_child = pid = fork(); 692ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 693cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 694ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 69575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 69675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 697ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 698ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid = getpid(); 6992e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (outf != stderr) 7002e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko close(fileno(outf)); 70102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 7022e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# ifdef MIPS 70302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Kludge for SGI, see proc_open for details. */ 70402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = foobar; 70502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = 0; 70602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&sa.sa_mask); 70702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGINT, &sa, NULL); 7082e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# endif 7092e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# ifndef FREEBSD 71002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pause(); 7112e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# else 712014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko kill(pid, SIGSTOP); 7132e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko# endif 71402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 71531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!daemonized_tracer && !use_seize) { 71631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 717cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 718ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 71902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 72002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 721ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (username != NULL) { 72202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 72302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 72402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 72502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 72602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 72702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 72802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 72902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 73002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * It is important to set groups before we 73102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * lose privileges on setuid. 73202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 733ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (initgroups(username, run_gid) < 0) { 734ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("initgroups"); 735ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 736ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setregid(run_gid, run_egid) < 0) { 737ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setregid"); 738ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 739ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setreuid(run_uid, run_euid) < 0) { 740ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setreuid"); 74102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 74202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 743ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko else if (geteuid() != 0) 74402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 74502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 746ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 747ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 7482e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Induce a ptrace stop. Tracer (our parent) 749ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will resume us with PTRACE_SYSCALL and display 7502e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * the immediately following execve syscall. 7512e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Can't do this on NOMMU systems, we are after 7522e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * vfork: parent is blocked, stopping would deadlock. 753ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 754c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if (!strace_vforked) 7552e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko kill(pid, SIGSTOP); 756ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } else { 757ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct sigaction sv_sigchld; 758ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, NULL, &sv_sigchld); 759ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 760ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make sure it is not SIG_IGN, otherwise wait 761ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will not block. 762ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 763ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko signal(SIGCHLD, SIG_DFL); 764ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 765ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Wait for grandchild to attach to us. 766ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It kills child after that, and wait() unblocks. 767ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 768ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(3); 769ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko wait(NULL); 770ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(0); 771ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, &sv_sigchld, NULL); 772ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 77302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 77402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 77502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, argv); 776cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 77702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 778ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 7792e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We are the tracer */ 78075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 7812e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (!daemonized_tracer) { 78231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) { 78331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* child did PTRACE_TRACEME, nothing to do in parent */ 78431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } else { 78531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) { 78631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Wait until child stopped itself */ 78731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status; 78831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (waitpid(pid, &status, WSTOPPED) < 0) { 78931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 79031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 79131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("waitpid"); 79231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 79331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 79431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 79531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Unexpected wait status %x", status); 79631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 79731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 79831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Else: vforked case, we have no way to sync. 79931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * Just attach to it as soon as possible. 80031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This means that we may miss a few first syscalls... 80131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 80231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 80331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(pid)) { 80431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 80531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Can't attach to %d", pid); 80631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 80731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) 80831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGCONT); 80931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 8102e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 811f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!strace_vforked) 81231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tcp->flags |= TCB_STARTUP | post_attach_sigstop; 813f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko else 814f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags |= TCB_STARTUP; 8152e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko } 8162e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko else { 8172e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 8182e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko strace_tracer_pid = getpid(); 8192e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* The tracee is our parent: */ 8202e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko pid = getppid(); 8212e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 8222e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We want subsequent startup_attach() to attach to it: */ 823ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->flags |= TCB_ATTACHED; 824ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 82502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 826ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (proc_open(tcp, 0) < 0) { 827cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("trouble opening proc file"); 82802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 8292e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko#endif 83002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 83102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 832b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#ifdef LINUX 83304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void kill_save_errno(pid_t pid, int sig) 83404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin{ 83504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin int saved_errno = errno; 83604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin 83704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin (void) kill(pid, sig); 83804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = saved_errno; 83904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin} 84004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin 841b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 842b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 843b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 844b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 845b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 84604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void 8473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 848b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 8492fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 8502fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 8512fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 8522fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 853b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 8545d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = fork(); 8555d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid < 0) 85604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 8575d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid == 0) { 85804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin pid = getpid(); 85931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 86004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 86104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 86204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill(pid, SIGSTOP); 86304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (fork() < 0) 86404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 86504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin _exit(0); 866b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 867b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 868b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 869b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 870b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 87104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = 0; 872b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 87304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid <= 0) { 874b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 875b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 876b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin else if (errno == ECHILD) 877b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 87804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 87904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 88004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 88104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 88204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFEXITED(status)) { 88304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WEXITSTATUS(status)) { 88404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 88504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 88604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 88704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 88804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 88904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 89004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 89104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 89204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 89304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 89404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 89504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 89604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 89704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (!WIFSTOPPED(status)) { 89804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 89904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 90004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill(pid, SIGKILL); 90104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 90204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 903b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 904b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 9052fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 90604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 90704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 90804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 90904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_CONT doesn't work"); 91004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 91104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 912b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 91304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin switch (WSTOPSIG(status)) { 91404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGSTOP: 91504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 91604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 91704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 91804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 91904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGTRAP: 92004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 92104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin long msg = 0; 9222fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 92304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 92404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin NULL, (long) &msg) == 0) 92504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin expected_grandchild = msg; 926b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 92704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 92804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 92904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 93004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 93104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 932b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 933b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 93404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) { 935f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 93604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (debug) 93704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin fprintf(stderr, "ptrace_setoptions = %#x\n", 93804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin ptrace_setoptions); 93904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin return; 94004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 94104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACECLONE failed, " 94204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 943b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 9443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9453454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 9463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 9473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 9483454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 9493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 9503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 9513454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 9523454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * _start: .globl _start 9533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int3 9543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $42, %ebx 9553454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $1, %eax 9563454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int $0x80 9573454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 9583454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 9593454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkostatic void 9603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 9613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 96204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 96304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin PTRACE_O_TRACEEXEC; 9643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 9653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 9663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9673454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 9683454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 96975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 9703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 9723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 9733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 97475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 97504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 97604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 9773454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 9783454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 9793454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 9803454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 9823454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 9833454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 9843454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 9853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 9863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 9873454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 9883454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 98904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 99004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 99104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 99275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 99375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 99475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 99575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 99604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 99704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 99804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 99904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 100004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 100104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 10023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 10043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 100504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 100604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 10073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10083454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 10093454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 10103454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 10113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 10123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 10133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 10143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 101504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 101604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 101704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 10183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10193454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 10203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 10213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10223454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 102304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 102475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 10253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10273454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10283454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 102975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 1030f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 10313454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (debug) 1032f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 1033f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 10343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko return; 10353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 103704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 103804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 10393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 104031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 104131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# ifdef USE_SEIZE 104231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic void 104331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotest_ptrace_seize(void) 104431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 104531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int pid; 104631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 104731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pid = fork(); 104831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid < 0) 104931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("fork"); 105031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 105131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid == 0) { 105231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pause(); 105331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko _exit(0); 105431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 105531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 105631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 105731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * attaching tracee continues to run unless a trap condition occurs. 105831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * PTRACE_SEIZE doesn't affect signal or group stop state. 105931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 106031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 106131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko post_attach_sigstop = 0; /* this sets use_seize to 1 */ 106231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } else if (debug) { 106331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 106431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 106531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 106631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 106731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 106831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (1) { 106931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status, tracee_pid; 107031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 107131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko errno = 0; 107231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tracee_pid = waitpid(pid, &status, 0); 107331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (tracee_pid <= 0) { 107431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 107531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 107631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("%s: unexpected wait result %d", 107731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, tracee_pid); 107831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 107931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (WIFSIGNALED(status)) { 108031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return; 108131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 108231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko error_msg_and_die("%s: unexpected wait status %x", 108331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, status); 108431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 108531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 108631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# else /* !USE_SEIZE */ 108731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define test_ptrace_seize() ((void)0) 108831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# endif 108931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 1090b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao#endif 1091b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 1092f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko/* Noinline: don't want main to have struct utsname permanently on stack */ 1093f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkostatic void __attribute__ ((noinline)) 1094f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkoget_os_release(void) 1095f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko{ 1096f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct utsname u; 1097f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (uname(&u) < 0) 1098f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko perror_msg_and_die("uname"); 1099f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko os_release = strdup(u.release); 1100f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (!os_release) 1101f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko die_out_of_memory(); 1102f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko} 1103f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 110508b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levinmain(int argc, char *argv[]) 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 110906350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 111208b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 111308b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 111475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 111575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 1116f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko get_os_release(); 1117f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1118ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 1119ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 11204f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 11211d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcbtab) 11221d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 11234f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 11241d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcp) 11251d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 11264f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 11274f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 1128ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 1130138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 1131138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 113376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 113476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 11378a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards "+cCdfFhiqrtTvVxyz" 1138ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 1139ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 1140ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 1141b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 1144e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 1145cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1146e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1147e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 1148e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 1149e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 1150e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 1151cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1152e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1153e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 115476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 115576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 115676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 115776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1158ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef USE_PROCFS 1159ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 1160ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 1161ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 1162ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 116341c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 116406350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 116506350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 116676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 116776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 117376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iflag++; 117476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 117576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 117676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag++; 117776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rflag++; 118076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 118376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 118776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 118876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 11918a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 11928a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 11938a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 119576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 119676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 11989c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 119976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 120117f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 120217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 120317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 120476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 120576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 1206102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (acolumn < 0) 1207102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko error_msg_and_die("Bad column width '%s'", optarg); 120876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 121276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 121376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 121476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 121576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 121776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 121876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 12195d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = atoi(optarg); 12205d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid <= 0) { 1221cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("Invalid process id: '%s'", optarg); 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (pid == strace_tracer_pid) { 1225cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg("I'm sorry, I can't let you do that, Dave."); 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1228418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloc_tcb(pid, 0); 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_ATTACHED; 123076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pflag_seen++; 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 12328a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 12338a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tracing_paths = 1; 12348a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (pathtrace_select(optarg)) { 1235cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Failed to select path '%s'", optarg); 12368a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards } 12378a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 123876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 123976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 1240dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (max_strlen < 0) { 1241b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1242dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 124676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 124776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 124876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 124976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1250de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 12511d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (putenv(optarg) < 0) 12521d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1253de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 1254b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko case 'I': 1255b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = atoi(optarg); 1256b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1257b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1258b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1259b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko break; 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1265837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko argv += optind; 1266837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* argc -= optind; - no need, argc is not used below */ 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1268102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces = malloc(acolumn + 1); 1269102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (!acolumn_spaces) 12701d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1271102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko memset(acolumn_spaces, ' ', acolumn); 1272102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces[acolumn] = '\0'; 1273102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko 1274837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* Must have PROG [ARGS], or -p PID. Not both. */ 1275837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (!argv[0] == !pflag_seen) 1276ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1277ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1278d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao if (pflag_seen && daemonized_tracer) { 1279cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-D and -p are mutually exclusive options"); 1280d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1281d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 128206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 128306350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 128406350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 1285cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (followfork > 1 && cflag) { 1286cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1287cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1288cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1294cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 12965d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pent = getpwnam(username); 12975d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pent == NULL) { 1298cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13088044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#ifdef LINUX 130904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (followfork) 131004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin test_ptrace_setoptions_followfork(); 13113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko test_ptrace_setoptions_for_all(); 131231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko test_ptrace_seize(); 13138044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin#endif 13148044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 131737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 131837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 131937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 132037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 132137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 132237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 13237dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (followfork > 1) 13247dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 13257dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko outf = strace_popen(outfname + 1); 132654b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 13273d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko else if (followfork <= 1) 13283d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko outf = strace_fopen(outfname); 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1331cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1332a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko char *buf = malloc(BUFSIZ); 1333a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko if (!buf) 1334a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko die_out_of_memory(); 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 1336cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 1337837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (outfname && argv[0]) { 1338b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1339b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_NEVER; 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1341369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1342b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1343b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_WHILE_WAIT; 1344b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1345b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* argv[0] -pPID -oFILE Default interactive setting 1346b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 0 INTR_WHILE_WAIT 1347b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 0 INTR_WHILE_WAIT 1348b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 1 INTR_NEVER 1349b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 1 INTR_WHILE_WAIT 135054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 135154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 135254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* STARTUP_CHILD must be called before the signal handlers get 135354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath installed below as they are inherited into the spawned process. 135454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Also we do not need to be protected by them as during interruption 135554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath in the STARTUP_CHILD mode we kill the spawned process anyway. */ 1356837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (argv[0]) 1357837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko startup_child(argv); 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 136076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 1364b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1365b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1366b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr != INTR_ANYWHERE) { 1367b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_BLOCK_TSTP_TOO) 1368b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1369b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* 1370b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In interactive mode (if no -o OUTFILE, or -p PID is used), 1371b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * fatal signals are blocked while syscall stop is processed, 1372b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * and acted on in between, when waiting for new syscall stops. 1373b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In non-interactive mode, signals are ignored. 1374b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko */ 1375b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_WHILE_WAIT) { 1376b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGHUP); 1377b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGINT); 1378b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGQUIT); 1379b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGPIPE); 1380b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGTERM); 1381b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sa.sa_handler = interrupt; 138276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 1383b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* POSIX signals on sunos4.1 are a little broken. */ 1384b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sa.sa_flags = SA_INTERRUPT; 1385b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko#endif 1386b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1387b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* SIG_IGN, or set handler for these */ 1388b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGHUP, &sa, NULL); 1389b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGINT, &sa, NULL); 1390b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGQUIT, &sa, NULL); 1391b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGPIPE, &sa, NULL); 1392b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTERM, &sa, NULL); 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1394bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = reaper; 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGCHLD, &sa, NULL); 1397553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 1398553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 1399553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 1400553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 1401553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 1402553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 1403553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 1404553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 1405bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1407ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pflag_seen || daemonized_tracer) 140802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 140902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace() < 0) 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 1412b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 1414a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin fflush(NULL); 1415a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (exit_code > 0xff) { 1416a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Child was killed by a signal, mimic that. */ 1417a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code &= 0xff; 1418a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin signal(exit_code, SIG_DFL); 1419a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin raise(exit_code); 1420a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin /* Paranoia - what if this signal is not fatal? 1421a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin Exit with 128 + signo then. */ 1422a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code += 128; 1423a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin } 1424a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit(exit_code); 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14272b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic void 1428418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoexpand_tcbtab(void) 14297b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 14307b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath /* Allocate some more TCBs and expand the table. 14317b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath We don't want to relocate the TCBs because our 14327b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath callers have pointers and it would be a pain. 14337b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath So tcbtab is a table of pointers. Since we never 14347b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath free the TCBs, we allocate a single chunk of many. */ 143518da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko int i = tcbtabsize; 143618da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 143718da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 14381d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!newtab || !newtcbs) 14391d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 14407b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtabsize *= 2; 14417b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtab = newtab; 144218da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko while (i < tcbtabsize) 144318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko tcbtab[i++] = newtcbs++; 14447b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath} 14457b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 144710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinalloc_tcb(int pid, int command_options_parsed) 144876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 145176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1452418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (nprocs == tcbtabsize) 1453418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko expand_tcbtab(); 1454418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1455ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1456ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 145776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 145818da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 1460381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko tcp->flags = TCB_INUSE; 146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 1462a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#if SUPPORTED_PERSONALITIES > 1 1463a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin tcp->currpers = current_personality; 1464a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#endif 14658dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#ifdef USE_PROCFS 146676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 14678dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#endif 146876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 14691d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 14701d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 147110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (command_options_parsed) 147210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newoutf(tcp); 147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 147618da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("bug in alloc_tcb"); 147776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 147876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1479bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 148076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 1481418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoproc_open(struct tcb *tcp, int attaching) 148276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 148376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char proc[32]; 148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long arg; 1485bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef SVR4 148619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 148719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes sysset_t syscalls; 148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t signals; 148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fltset_t faults; 1490bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 149276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last_pfd; 149376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 149476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1495ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 14969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Open the process pseudo-files in /proc. */ 14979ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/ctl", tcp->pid); 14985d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd = open(proc, O_WRONLY|O_EXCL); 14995d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd < 0) { 15009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 15019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 15029ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 15031f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 15049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 15055d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL); 15065d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_stat < 0) { 15079ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 15089ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 15099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 15101f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_stat); 15119ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/as", tcp->pid); 15125d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_as = open(proc, O_RDONLY|O_EXCL); 15135d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_as < 0) { 15149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 15159ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 15169ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 15171f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd_as); 15189ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Open the process pseudo-file in /proc. */ 15200890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# ifndef FREEBSD 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 1522372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR|O_EXCL); 15230890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# else 1524bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 1525372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab tcp->pfd = open(proc, O_RDWR); 15260890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko# endif 1527372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab if (tcp->pfd < 0) { 152876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15311f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(tcp->pfd); 15329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1533bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1534bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/regs", tcp->pid); 15355d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_reg = open(proc, O_RDONLY); 15365d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_reg < 0) { 1537bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../regs\", ...)"); 1538bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1539bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1540bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (cflag) { 1541bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 15425d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp->pfd_status = open(proc, O_RDONLY); 15435d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp->pfd_status < 0) { 1544bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../status\", ...)"); 1545bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1546bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1547bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 1548bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1549bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Wait for the child to pause. Because of a race 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * condition we have to poll for the event. 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1557b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_STATUS(tcp) < 0) { 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 1562cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko break; 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1565bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Stop the process so that we own the stop. */ 156716a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 156876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTOP"); 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1571553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PIOCSET 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 15759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 158076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 15819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 1586553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1595bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1596bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 1597bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 1598bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCGFL"); 15995ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1600bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1601bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg &= ~PF_LINGER; 1602bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 16035ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko perror("PIOCSFL"); 16045ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko return -1; 1605bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1606bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !PIOCSET */ 1608bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 160919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable all syscall entries we care about. */ 161019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&syscalls); 161119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 161219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof syscalls) * CHAR_BIT) break; 1613b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_TRACE) praddset(&syscalls, i); 161419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 1615b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_execve); 161619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (followfork) { 1617b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork); 161819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_forkall 1619b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_forkall); 162019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 1621553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef SYS_fork1 1622b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_fork1); 162319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 162419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rfork1 1625b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rfork1); 162619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 162719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rforkall 1628b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko praddset(&syscalls, SYS_rforkall); 162919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 163019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 163119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 163276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable the syscall exits. */ 163619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOSEXIT"); 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable signals we care about. */ 164119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&signals); 164219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 164319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof signals) * CHAR_BIT) break; 1644b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_SIGNAL) praddset(&signals, i); 164519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 16469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 165019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable faults we care about */ 165119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&faults); 165219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 165319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof faults) * CHAR_BIT) break; 1654b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (qual_flags[i] & QUAL_FAULT) praddset(&faults, i); 165519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 16569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 165876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 165976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1660bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1661bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* set events flags. */ 1662b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko arg = S_SIG | S_SCE | S_SCX; 1663b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 1664bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCBIS"); 1665bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 1666bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1667bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The SGI PRSABORT doesn't work for pause() so 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * we send it a caught signal to wake it up. 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGINT); 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 1676553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef PRSABORT 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 16789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = PRSABORT; 1679b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1683553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 1684bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !MIPS*/ 1685bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1686bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 1687bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1688553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 1691b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL_WSTOP(tcp) < 0) { 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 1696bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 169706602d99b72564e77600fc7c94e9ce8b78ec7085Denys Vlasenko get_scno(tcp); 169876989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath if (known_scno(tcp) == SYS_execve) 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set it running: maybe execve will be next. */ 1702bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 17039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 17040890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 17050890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#else 17060890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 17070890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#endif 17080890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko { 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1712bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1713bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* handle the case where we "opened" the child before 1714bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman it did the kill -STOP */ 1715bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->status.PR_WHY == PR_SIGNALLED && 1716bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 1717bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 1718553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17210890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko#ifdef FREEBSD 17220890c8a403f60c2f66f17bf5d6bb16039b47c913Denys Vlasenko else { 1723553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (attaching < 2) { 17242e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* We are attaching to an already running process. 17252e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * Try to figure out the state of the process in syscalls, 17262e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * to handle the first event well. 17272e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * This is done by having a look at the "wchan" property of the 17282e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * process, which tells where it is stopped (if it is). */ 17292e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman FILE * status; 17302e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman char wchan[20]; /* should be enough */ 1731553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 17322e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 17332e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman status = fopen(proc, "r"); 17342e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status && 17352e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 17362e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman "%*d,%*d %*d,%*d %19s", wchan) == 1) && 17372e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 17382e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "stopevent")) { 17392e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* The process is asleep in the middle of a syscall. 17402e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman Fake the syscall entry event */ 17412e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 17422e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 17432e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman trace_syscall(tcp); 17442e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 17452e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status) 17462e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fclose(status); 17472e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } /* otherwise it's a fork being followed */ 1748bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1749bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1763bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1765eebb04d4ae8bf4b08a041f5ea442ca24c90692c2Denys Vlasenkostatic struct tcb * 176654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 176954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 177054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 177154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1773ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 177454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 177554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 177676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 177854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1782bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 178554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathfirst_used_tcb(void) 178654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath{ 178754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath int i; 178854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp; 178954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath for (i = 0; i < tcbtabsize; i++) { 179054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = tcbtab[i]; 179154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->flags & TCB_INUSE) 179254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return tcp; 179354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath } 179454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 179554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath} 179654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 179754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathstatic struct tcb * 17981201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkopfd2tcb(int pfd) 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1802ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = 0; i < tcbtabsize; i++) { 1803ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != pfd) 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 181176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1812bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 18151201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodroptcb(struct tcb *tcp) 181676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 181919cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko 182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 18211d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) 18221d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1823eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 18248dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#ifdef USE_PROCFS 182576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != -1) { 182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(tcp->pfd); 182776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 18288dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko# ifdef FREEBSD 1829bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_reg != -1) { 1830bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_reg); 1831bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_reg = -1; 1832bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1833bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_status != -1) { 1834bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_status); 1835bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1836bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 18378dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko# endif 183819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko tcp->flags = 0; /* rebuild_pollv needs it */ 183919cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko rebuild_pollv(); 184076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 18418dc0c8c5ef66c2b2eb76484b83c750c0712891f9Denys Vlasenko#endif 1842eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1843822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 184476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 1845eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 184619cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko memset(tcp, 0, sizeof(*tcp)); 184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18490a463880341945df08b6dc79134dc78cc38dc283Roland McGrath/* detach traced process; continue with sig 18500a463880341945df08b6dc79134dc78cc38dc283Roland McGrath Never call DETACH twice on the same process as both unattached and 18510a463880341945df08b6dc79134dc78cc38dc283Roland McGrath attached-unstopped processes give the same ESRCH. For unattached process we 18520a463880341945df08b6dc79134dc78cc38dc283Roland McGrath would SIGSTOP it and wait for its SIGSTOP notification forever. */ 185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 18554c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkodetach(struct tcb *tcp) 185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1858ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#ifdef LINUX 18591bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int status, catch_sigstop; 1860ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 1863840d85b3e50cea9f28aedd23af94742c2a60265aAndreas Schwab clearbpt(tcp); 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 18687bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 18697bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 18717bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 18727bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 18737bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 18747bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 187502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 187631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * We attached but possibly didn't see the expected SIGSTOP. 1877f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * We must catch exactly one as otherwise the detached process 1878f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * would be left stopped (process state T). 187902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 1880f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko catch_sigstop = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 18814c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 18825d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (error == 0) { 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* On a clear day, you can see forever. */ 18847bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 18857bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (errno != ESRCH) { 18867bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath /* Shouldn't happen. */ 18877bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: ptrace(PTRACE_DETACH, ...)"); 18887bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 188944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko else if (my_tkill(tcp->pid, 0) < 0) { 18907bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 18917bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: checking sanity"); 18927bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 189344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko else if (!catch_sigstop && my_tkill(tcp->pid, SIGSTOP) < 0) { 18947bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 18957bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: stopping child"); 18967bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 189702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 189802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath catch_sigstop = 1; 1899ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (catch_sigstop) { 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 19017508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 19027508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 19037508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 19047508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 19057508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 19077508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 19087508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 19097508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 19107508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 19117508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 19127508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 19137508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 19147508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 19157508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 19167508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 19177508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 19187508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WCLONE, 19197508cb4678141d146d819120f6b5b428c103882eRoland McGrath NULL) < 0) { 19207508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 19217508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 19227508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 19237508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 19247508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 19257508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 19267508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19287508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 19344c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, 0); 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1937732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, 193875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko WSTOPSIG(status) == syscall_trap_sig ? 0 1939732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko : WSTOPSIG(status)); 1940732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (error < 0) 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1943ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } 19447bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* LINUX */ 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 19484c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko error = ptrace_restart(PTRACE_DETACH, tcp, 0); 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 195376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 195476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 1955a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1959bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1961e5e60858063f214fcd7860f50f8bcb46f951f9abDmitry V. Levinstatic void reaper(int sig) 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 196776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1970bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 19731201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 19773521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko int fatal_sig; 19783521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko 19793521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko /* 'interrupted' is a volatile object, fetch it only once */ 19803521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = interrupted; 19813521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko if (!fatal_sig) 19823521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = SIGTERM; 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1984ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1985ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 1991000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp && 1992000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko (!outfname || followfork < 2 || printing_tcp == tcp)) { 1993000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprints(" <unfinished ...>\n"); 1994000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 19974c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko detach(tcp); 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 2000a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko kill(tcp->pid, fatal_sig); 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 20081201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2010a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko interrupted = sig; 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20156d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 20186d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 20211201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrerror(int err_no) 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202535aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 202635aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko sprintf(buf, "Unknown error %d", err_no); 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202935aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko return sys_errlist[err_no]; 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20368f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 20376d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 20398f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 20408f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 20418f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 20441201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrsignal(int sig) 204576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 204676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 204776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 205076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 205176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 205476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2061bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 20641201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkorebuild_pollv(void) 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2068cfd364b011e170377ae002551c4391c01f51acbfDenys Vlasenko free(pollv); 2069cfd364b011e170377ae002551c4391c01f51acbfDenys Vlasenko pollv = malloc(nprocs * sizeof(pollv[0])); 20701d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!pollv) 20711d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 2072ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 2073ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = j = 0; i < tcbtabsize; i++) { 2074ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[j].fd = tcp->pfd; 20789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollv[j].events = POLLWANT; 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j++; 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j != nprocs) { 2082cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("proc miscount"); 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 20891201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll_open(void) 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 2094cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("pipe"); 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 20971f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko set_cloexec_flag(proc_poll_pipe[i]); 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 21021201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poll(struct pollfd *pollv, int nfds, int timeout) 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21085d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo)); 21095d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (n < 0) 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 2112cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("panic: short read: %d", n); 211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 211576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 211676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 211776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 211876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = 0; 211976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 212076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 212176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 212276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 212376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 21251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkowakeup_handler(int sig) 212676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 212776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 212876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 212976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 21301201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoproc_poller(int pfd) 213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 213276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 213376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 213476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t blocked_set, empty_set; 213576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 213676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 213776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 2138bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2139bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct procfs_status pfs; 2140bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (fork()) { 214376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 2144cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 214776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 215676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 215776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 215876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 215976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = wakeup_handler; 216076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGUSR1, &sa, NULL); 216176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 216276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGUSR1); 216376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 216476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 216576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 216676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 2167cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("getrlimit(RLIMIT_NOFILE, ...)"); 216876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 216976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = rl.rlim_cur; 217076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 217176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i != pfd && i != proc_poll_pipe[1]) 217276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(i); 217376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 217476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 217576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.fd = pfd; 217676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.pid = getpid(); 217776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 2178bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 21795ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 21805ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#else 21815ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 21825ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko#endif 21839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman { 218476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (errno) { 218576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 218676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 218776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLERR; 218976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 219076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLHUP; 219276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 219376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 219476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollinfo.revents = POLLWANT; 220076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 220176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 220276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 220576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 220776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 220976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 221076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 221176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 221276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 221376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 22169ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 221776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The previous process is ready to run again. We'll 221976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * let it do so if it is currently in a syscall. This 222076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * heuristic improves the readability of the trace. 222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 222276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[last].fd); 2223b88f96129f8ebc064d490c8c161bcbc925d938c8Denys Vlasenko if (tcp && exiting(tcp)) 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 222576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 222676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 222776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 222876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 222976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 223076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[j].revents & (POLLHUP | POLLERR)) { 223176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[j].fd); 223276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) { 2233cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("lost proc"); 223476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 223576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 223676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 223776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 22389ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pollv[j].revents & POLLWANT) { 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last = j; 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[j].fd; 224176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 224276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2243cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("nothing ready"); 224476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 224576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 224676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 22471201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 22499dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 2250d870b3c31a0139b335a66a829169bacc74624c44John Hughes struct tcb *in_syscall = NULL; 22519dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 225276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pfd; 225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int what; 225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int ioctl_result = 0, ioctl_errno = 0; 22569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman long arg; 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 226376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (nprocs) { 226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 1: 226776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] == -1) { 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 227054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath tcp = first_used_tcb(); 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = tcp->pfd; 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 227876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 227976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* fall through ... */ 228076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_POLLABLE_PROCFS 22839dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 22849dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman /* On some systems (e.g. UnixWare) we get too much ugly 22859dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman "unfinished..." stuff when multiple proceses are in 22869dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman syscalls. Here's a nasty hack */ 2287553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 22889dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (in_syscall) { 22899dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman struct pollfd pv; 22909dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp = in_syscall; 22919dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = NULL; 22929dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.fd = tcp->pfd; 22939dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.events = POLLWANT; 22945d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko what = poll(&pv, 1, 1); 22955d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (what < 0) { 22969dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (interrupted) 22979dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman return 0; 22989dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman continue; 22999dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 23009dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 23019dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman goto FOUND; 23029dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 23039dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 23049dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 23059dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 230676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 230776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 230876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 230976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 231076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 231176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_POLLABLE_PROCFS */ 231276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll(pollv, nprocs, INFTIM) < 0) { 231376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 231476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 231576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 231676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 231776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 231876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 231976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 232076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 232176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 232276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 232376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 232476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 23255d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pfd2tcb(pfd); 23265d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 2327cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("unknown pfd: %u", pfd); 232876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2329b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#ifdef POLL_HACK 23309dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman FOUND: 2331b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#endif 233276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Get the status of the process. */ 233376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!interrupted) { 2334bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 2335b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2336bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 2337bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* Thanks to some scheduling mystery, the first poller 2338bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sometimes waits for the already processed end of fork 2339bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 2340bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (proc_poll_pipe[0] != -1) 2341b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_STATUS(tcp); 2342bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else 2343b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko ioctl_result = IOCTL_WSTOP(tcp); 2344553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 234576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ioctl_errno = errno; 234676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 234776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) { 234876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) 234976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGKILL); 235076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 235176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGUSR1); 235276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 235376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 235476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 235576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 235676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 235776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 235876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 235976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 236076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 236176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) { 236276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Find out what happened if it failed. */ 236376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (ioctl_errno) { 236476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 236576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 236676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2367bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2368bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOTTY: 2369553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 237076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 237176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 237276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 237376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2374cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCWSTOP"); 237576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 237676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 237776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23782e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifdef FREEBSD 23792e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 23802e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* discard first event for a syscall we never entered */ 2381b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko IOCTL(tcp->pfd, PIOCRUN, 0); 23822e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 23832e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 2384553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2385553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 238676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 238776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 238876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 238976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 239076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 2391ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 239276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 239376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 239476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval stime; 2395bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2396bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman char buf[1024]; 2397bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int len; 2398bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 23995d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0); 24005d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (len > 0) { 2401bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman buf[len] = '\0'; 2402bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sscanf(buf, 2403bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 2404bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman &stime.tv_sec, &stime.tv_usec); 2405bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 2406bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 2407553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else /* !FREEBSD */ 240876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 240976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 2410bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 241176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 241276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = stime; 241376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman what = tcp->status.PR_WHAT; 24159ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman switch (tcp->status.PR_WHY) { 2416bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 241776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_REQUESTED: 24189ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) { 24199ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 242076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2421cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 242276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 242376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 242476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2425bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 242676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSENTRY: 24279dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 24289dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = tcp; 24299dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 243076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 243176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 2432cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("syscall trouble"); 243376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 243476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 243576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 2436e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 2437e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_SIGNAL)) { 243876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 2439000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("--- %s (%s) ---\n", 2440ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(what), strsignal(what)); 2441000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 24425826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#ifdef PR_INFO 24435826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes if (tcp->status.PR_INFO.si_signo == what) { 24445826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printleader(tcp); 244560fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" siginfo="); 24465826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printsiginfo(&tcp->status.PR_INFO, 1); 2447000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprints("\n"); 2448000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 24495826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes } 24505826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#endif 245176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 245276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 245376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 2454e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAGS_ONLY_STATS 2455e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin && (qual_flags[what] & QUAL_FAULT)) { 245676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 2457000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("=== FAULT %d ===\n", what); 2458000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 245976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 246076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 2461bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 2462bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case 0: /* handle case we polled for nothing */ 24635ae2b7c601dadf79a4345e1ee21053947b9e4addDenys Vlasenko continue; 2464553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 246576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 2466cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("odd stop %d", tcp->status.PR_WHY); 246776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 246876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2469ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2470ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 24719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 2472553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 2473b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) 2474553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 2475b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) 2476553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 2477372cc84c972f8e88cc148f343b02f4b5beb83dc7Andreas Schwab { 2478cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("PIOCRUN"); 247976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 248076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 248176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 248276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 248376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2484bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 248576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2486eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrathstatic int 248731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotrace(void) 248876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 248976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 249076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 249126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko struct rusage *rup = cflag ? &ru : NULL; 249226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 2493eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath static int wait4_options = __WALL; 249426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif 249576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 249676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2497eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath while (nprocs != 0) { 2498f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int pid; 2499f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int wait_errno; 2500f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int status, sig; 250131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int stopped; 2502f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *tcp; 2503f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko unsigned event; 2504f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 2505222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 2506eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2507eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2508eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 250976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 251026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 251126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 25125bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 25132f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 25142f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 251526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 25162f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 25175bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 25182f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 251926d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, __WCLONE, rup); 252026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2521cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg("wait4(__WCLONE) failed"); 25222f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 25232f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 252426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# else 252526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, 0, rup); 252626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif /* __WALL */ 252776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 252876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 252976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 253026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko#endif 253176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 2532eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2533eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 253476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 253526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2536eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath switch (wait_errno) { 2537eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case EINTR: 253876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2539eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case ECHILD: 254076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 254176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 254276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 254376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 254476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 254576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 2546eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 2547eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath default: 2548eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = wait_errno; 2549eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath perror("strace: wait"); 2550eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 255176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 255276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 255310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 255410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (WIFEXITED(status) || WIFSIGNALED(status)) 25557dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 255610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 255710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 2558f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 2559f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko event = ((unsigned)status >> 16); 25601d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (debug) { 25611d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 25621d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef LINUX 2563f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event != 0) { 25641d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko static const char *const event_names[] = { 25651d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 25661d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 25671d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 25681d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 25691d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 25701d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 25711d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko }; 25721d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko const char *e; 2573f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event < ARRAY_SIZE(event_names)) 2574f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko e = event_names[event]; 25751d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko else { 2576f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko sprintf(buf, "?? (%u)", event); 25771d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko e = buf; 25781d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 25791d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " PTRACE_EVENT_%s", e); 25801d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 25811d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 25821d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 25831d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 25841d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 25851d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 25861d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 25871d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 25881d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 25891d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 25901d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 25911d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 25921d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 25931d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 25941d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 25951d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 25965bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 25971d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 25981d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 25995bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 26001d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, " [wait(0x%04x) = %u] %s\n", status, pid, buf); 26011d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 260276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2603f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Look up 'pid' in our table. */ 26045d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pid2tcb(pid); 2605f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 2606f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#ifdef LINUX 2607f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Under Linux, execve changes pid to thread leader's pid, 2608f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and we see this changed pid on EVENT_EXEC and later, 2609f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * execve sysexit. Leader "disappears" without exit 2610f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * notification. Let user know that, drop leader's tcb, 2611f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and fix up pid in execve thread's tcb. 2612f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * Effectively, execve thread's tcb replaces leader's tcb. 2613f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 2614f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 2615f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * on exit syscall) in multithreaded programs exactly 2616f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * in order to handle this case. 2617f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 2618f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 2619f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * On 2.6 and earlier, it can return garbage. 2620f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko */ 2621f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') { 2622f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko long old_pid = 0; 2623f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 2624f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid > 0 2625f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid != pid 2626f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko ) { 2627f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *execve_thread = pid2tcb(old_pid); 2628f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 2629f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko outf = tcp->outf; 2630f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko curcol = tcp->curcol; 2631f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (!cflag) { 2632000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp) 2633f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tprints(" <unfinished ...>\n"); 2634f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko printleader(tcp); 2635000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 2636000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 2637f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko fflush(outf); 2638f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2639f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (execve_thread) { 2640f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* swap output FILEs (needed for -ff) */ 2641f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->outf = execve_thread->outf; 2642f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko execve_thread->outf = outf; 2643f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2644f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko droptcb(tcp); 2645f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2646f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp = execve_thread; 2647f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 2648f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->pid = pid; 2649f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->flags |= TCB_REPRINT; 2650f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2651f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2652f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2653f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#endif 2654f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 26555d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 2656e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef LINUX 265741c48227a86a176da333f713d5047240885f25ccRoland McGrath if (followfork) { 2658e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 2659e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 2660e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 2661e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 2662e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 2663e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 2664e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 2665e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 2666e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 2667418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloctcb(pid); 266831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 2669e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 2670833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko fprintf(stderr, "Process %d attached\n", 2671e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 26728b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 2673e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 2674e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 2675e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 2676eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#endif 2677e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 2678e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 2679e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_CONT, pid, (char *) 1, 0); 2680cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Unknown pid: %u", pid); 2681e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 268276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2683eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* set current output file */ 2684eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath outf = tcp->outf; 2685ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 2686eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath#ifdef LINUX 268713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 268876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 268976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 269076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 269113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#endif 2692eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 269376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 2694a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2695a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 2696e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 269776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 269876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 269913d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 2700000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s %s+++\n", 27012efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 270213d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 270313d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 2704000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s +++\n", 270513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 27062efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 2707000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 270876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27095e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 271076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 271176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 271276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 271376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 2714a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2715a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 2716000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (tcp == printing_tcp) { 2717000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprints(" <unfinished ...>\n"); 2718000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 27190a396906981a03f93c07cb912585d0679dd50899Roland McGrath } 272019cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 272119cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 2722000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 2723000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 272419cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 27255e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 272676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 272776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 272876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 272976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 273076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 273176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 273276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 273376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 273476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2735f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this the very first time we see this tracee stopped? */ 2736f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (tcp->flags & TCB_STARTUP) { 2737f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (debug) 2738f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 273976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 274002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 274176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 274202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 27432ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * parent through fork(). 274476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 27456cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (clearbpt(tcp) < 0) { 27466cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko /* Pretty fatal */ 274776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 274876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 274976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 275076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 275176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2752ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#ifdef LINUX 275344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace_setoptions) { 275444f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (debug) 275544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 275644f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 275744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (errno != ESRCH) { 275844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko /* Should never happen, really */ 275944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 27603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 27613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 27623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2763ca8ab8d2958f86297a6574a73cc1b9759d59c9b1Wang Chao#endif 2764f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2765f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 276631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko sig = WSTOPSIG(status); 276731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 2768f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event != 0) { 276931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Ptrace event */ 277031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 277131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 27726703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko /* 27736703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop or group-stop. 27746703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 27756703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko */ 277631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (sig == SIGSTOP 277731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTSTP 277831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTIN 277931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTOU 278031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko ) { 278131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = 1; 278231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto show_stopsig; 278331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 278431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 278531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 2786f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko goto restart_tracee_with_sig_0; 2787f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2788f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2789f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this post-attach SIGSTOP? 2790f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Interestingly, the process may stop 2791f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * with STOPSIG equal to some other signal 2792f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * than SIGSTOP if we happend to attach 2793f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * just before the process takes a signal. 2794f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 2795f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2796f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (debug) 2797f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2798f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 27996cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee_with_sig_0; 280076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 280176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 28026cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (sig != syscall_trap_sig) { 280331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko siginfo_t si; 280431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 280531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Nonzero (true) if tracee is stopped by signal 280631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (as opposed to "tracee received signal"). 280731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 280831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 28096703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#ifdef USE_SEIZE 281031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko show_stopsig: 28116703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#endif 2812e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 28136cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko && (qual_flags[sig] & QUAL_SIGNAL)) { 2814c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 28156b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long pc = 0; 28166b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long psr = 0; 28177b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2818932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IPSR, &psr); 2819932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IIP, &pc); 28207b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 28216b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PSR_RI 41 28227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 28236b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR " @ %lx" 28242ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG , pc 28256b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin#else 28262ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_STR "" 28272ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG /* nothing */ 28287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 282976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 283031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) { 283160fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("--- "); 28326b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin printsiginfo(&si, verbose(tcp)); 2833000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf(" (%s)" PC_FORMAT_STR " ---\n", 28346cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig) 28356b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 28366b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin } else 2837000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("--- %s by %s" PC_FORMAT_STR " ---\n", 28386cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig), 28396cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko signame(sig) 28406b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 2841000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 28425e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 284376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 284431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 284531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) 284631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's signal-delivery-stop. Inject the signal */ 284731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto restart_tracee; 284831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 284931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's group-stop */ 285031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 285131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (use_seize) { 285231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* 285331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This ends ptrace-stop, but does *not* end group-stop. 285431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This makes stopping signals work properly on straced process 285531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (that is, process really stops. It used to continue to run). 285631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 285731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 285831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cleanup(); 285931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return -1; 286031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 286131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 286231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 286331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* We don't have PTRACE_LISTEN support... */ 286431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 28656cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee; 286676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28672ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 28682ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* We handled quick cases, we are permitted to interrupt now. */ 286902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 287002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return 0; 28712ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 28722ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* This should be syscall entry or exit. 28732ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * (Or it still can be that pesky post-execve SIGTRAP!) 28742ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * Handle it. 28752ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko */ 2876eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2877eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* ptrace() failed in trace_syscall() with ESRCH. 2878eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2879eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Observed case: exit_group() terminating 2880f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * all processes in thread group. 2881ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko */ 2882ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (tcp->flags & TCB_ATTACHED) { 2883000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp) { 2884eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* Do we have dangling line "syscall(param, param"? 2885178de007d14f3ae890117b540def9cf14bcb61feDenys Vlasenko * Finish the line then. 2886eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath */ 2887000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp->flags |= TCB_REPRINT; 2888000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprints(" <unfinished ...>\n"); 2889000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = NULL; 28905e09d77500a656da343580a16e6d005eb1c560b1Denys Vlasenko fflush(tcp->outf); 2891eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath } 2892f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* We assume that ptrace error was caused by process death. 2893f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * We used to detach(tcp) here, but since we no longer 2894f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * implement "detach before death" policy/hack, 2895f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * we can let this process to report its death to us 2896f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * normally, via WIFEXITED or WIFSIGNALED wait status. 2897f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko */ 2898ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } else { 2899f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* It's our real child (and we also trace it) */ 2900f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* my_tkill(pid, SIGKILL); - why? */ 2901f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko /* droptcb(tcp); - why? */ 290276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 290376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 290476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 29056cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0: 29066cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko sig = 0; 29076cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee: 2908ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2909ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 29106cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 291176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 291276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 291376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 291476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 291576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 291676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 291776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2918bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 291976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 292076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 292176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 292276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 292376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 292476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2925e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwab va_start(args, fmt); 2926b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (outf) { 2927b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath int n = vfprintf(outf, fmt, args); 2928ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (n < 0) { 2929ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab if (outf != stderr) 2930ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab perror(outfname == NULL 2931ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab ? "<writing to pipe>" : outfname); 2932ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab } else 2933b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath curcol += n; 2934b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath } 293576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_end(args); 29365940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko} 29375940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko 29385940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenkovoid 29395940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenkotprints(const char *str) 29405940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko{ 29415940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (outf) { 29425940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko int n = fputs(str, outf); 29435940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (n >= 0) { 29445940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko curcol += strlen(str); 29455940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko return; 29465940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko } 29475940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko if (outf != stderr) 29485940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko perror(outfname == NULL 29495940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko ? "<writing to pipe>" : outfname); 29505940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko } 295176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 295276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 295376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 29541201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkoprintleader(struct tcb *tcp) 295576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2956000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp) { 2957000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp->ptrace_errno) { 2958000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko if (printing_tcp->flags & TCB_INSYSCALL) { 295960fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unavailable>) "); 2960102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko tabto(); 2961732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 296260fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("= ? <unavailable>\n"); 2963000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp->ptrace_errno = 0; 2964000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko } else if (!outfname || followfork < 2 || printing_tcp == tcp) { 2965000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp->flags |= TCB_REPRINT; 296660fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints(" <unfinished ...>\n"); 2967732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko } 296876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2969000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko 2970000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko printing_tcp = tcp; 297176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman curcol = 0; 297276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 297376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%-5d ", tcp->pid); 297476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1 && !outfname) 297576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 297676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag) { 297776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char str[sizeof("HH:MM:SS")]; 297876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 297976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 298076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 298176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 298276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 298376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 298476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 298576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 298676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 298776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 298876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 298976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 299076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 299176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 299276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 299376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 299476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 299576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 299676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 299776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 299876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 299976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 300076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 300176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 300276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 300376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iflag) 300476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 300576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 300676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 300776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 3008102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkotabto(void) 300976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 3010102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (curcol < acolumn) 30115940e6593911dcace424c668a1c0934c71fccb9eDenys Vlasenko tprints(acolumn_spaces + curcol); 301276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 301376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3014ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 30159ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 3016ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkoint 3017ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenkomp_ioctl(int fd, int cmd, void *arg, int size) 3018ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko{ 30199ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct iovec iov[2]; 30209ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int n = 1; 3021553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 30229ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_base = &cmd; 30239ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_len = sizeof cmd; 30249ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (arg) { 30259ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ++n; 30269ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_base = arg; 30279ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_len = size; 30289ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 3029553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 3030ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko return writev(fd, iov, n); 30319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 30329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 30339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 3034