strace.c revision 6d2b34971b33d379c89c36c5ad1b0c6d5d12c453
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 <sys/types.h> 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 35795edb11488dd47c4598e2228e3b5431de7ed46dRoland McGrath 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <signal.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <errno.h> 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h> 4376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h> 4476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h> 4576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <string.h> 4619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#include <limits.h> 4770b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath 4876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(IA64) && defined(LINUX) 49134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath# include <asm/ptrace_offsets.h> 50134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 51134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath 52134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef USE_PROCFS 53134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#include <poll.h> 54134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 55134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath 56134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef SVR4 57134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#include <sys/stropts.h> 58134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef HAVE_MP_PROCFS 59134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifdef HAVE_SYS_UIO_H 60134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#include <sys/uio.h> 61134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 62134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 63134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#endif 647b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 657b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkermanint debug = 0, followfork = 0, followvfork = 0, interactive = 0; 667b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkermanint rflag = 0, tflag = 0, dtime = 0, cflag = 0; 677b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkermanint iflag = 0, xflag = 0, qflag = 0; 68bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanint pflag_seen = 0; 69bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 70bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman/* Sometimes we want to print only succeeding syscalls. */ 71bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanint not_failing_only = 0; 7276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *username = NULL; 74ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkermanuid_t run_uid; 751d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughesgid_t run_gid; 769ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkermanint acolumn = DEFAULT_ACOLUMN; 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 791d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hugheschar *outfname = NULL; 8096d5a76109b4f1d1f4c9c76641e6ec896108083dDenys VlasenkoFILE *outf; 81418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkostruct tcb **tcbtab; 82418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkounsigned int nprocs, tcbtabsize; 8396d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkochar *progname; 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char version[]; 8541c48227a86a176da333f713d5047240885f25ccRoland McGrathextern char **environ; 86b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levin 87b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic struct tcb *pid2tcb P((int pid)); 88ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic int trace P((void)); 89ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic void cleanup P((void)); 90ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic void interrupt P((int sig)); 91ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic sigset_t empty_set, blocked_set; 92ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 93ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifdef HAVE_SIG_ATOMIC_T 94ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic volatile sig_atomic_t interrupted; 95ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#else /* !HAVE_SIG_ATOMIC_T */ 96ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifdef __STDC__ 97ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic volatile int interrupted; 98ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#else /* !__STDC__ */ 99ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic int interrupted; 100ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif /* !__STDC__ */ 10176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_SIG_ATOMIC_T */ 10217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 10317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig#ifdef USE_PROCFS 10417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 105a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic struct tcb *pfd2tcb P((int pfd)); 106a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic void reaper P((int sig)); 10796d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkostatic void rebuild_pollv P((void)); 10896d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkostatic struct pollfd *pollv; 109a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin 110b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levin#ifndef HAVE_POLLABLE_PROCFS 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poll_open P((void)); 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poller P((int pfd)); 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 116b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levin int fd; 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 118ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath int pid; 119ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath}; 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 1220a463880341945df08b6dc79134dc78cc38dc283Roland McGrathstatic int proc_poll_pipe[2] = { -1, -1 }; 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 12576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_MP_PROCFS 12776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define POLLWANT POLLWRNORM 12876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 12976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define POLLWANT POLLPRI 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* USE_PROCFS */ 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage(ofp, exitval) 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanFILE *ofp; 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint exitval; 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 138bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman fprintf(ofp, "\ 13976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ 14076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman [-p pid] ... [-s strsize] [-u username] [command [arg ...]]\n\ 14176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman or: strace -c [-e expr] ... [-O overhead] [-S sortby] [command [arg ...]]\n\ 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 143ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath-f -- follow forks, -ff -- with output into separate files\n\ 14476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-F -- attempt to follow vforks, -h -- print help message\n\ 14576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 14876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-T -- print time spent in each syscall, -V -- print version\n\ 14976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 15076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 15176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 15276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 15776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 15976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-z -- print only succeeding syscalls\n\ 161ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman", DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 1629ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman exit(exitval); 1639ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 1649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 1659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#ifdef SVR4 166bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef MIPS 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 175de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrathmain(argc, argv) 176de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrathint argc; 177ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkochar *argv[]; 178de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath{ 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern int optind; 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern char *optarg; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[BUFSIZ]; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Allocate the initial tcbtab. */ 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcbtabsize = argc; /* Surely enough for all -p args. */ 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]); 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]); 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp) 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]]; 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 194ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko progname = argv[0]; 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 1; 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 198de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath qualify("abbrev=all"); 199de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath qualify("verbose=all"); 200de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath qualify("signal=all"); 20117f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig set_sortby(DEFAULT_SORTBY); 202de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath set_personality(DEFAULT_PERSONALITY); 203de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath while ((c = getopt(argc, argv, 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:")) != EOF) { 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cflag++; 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'F': 21710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin followvfork++; 21810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 21910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'h': 22010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin usage(stdout, 0); 22110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 22210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'i': 22310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin iflag++; 22410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 22510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'q': 22610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin qflag++; 22710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 22810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'r': 22910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin rflag++; 23010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin tflag++; 23110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 23210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 't': 23310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin tflag++; 23410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 23510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'T': 23610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin dtime++; 23710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 23810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'x': 23910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin xflag++; 24010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 24110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'v': 24210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin qualify("abbrev=none"); 24310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 24410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'V': 24510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin printf("%s\n", version); 24610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(0); 24710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 24810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'z': 24910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin not_failing_only = 1; 25010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 25110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'a': 25210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin acolumn = atoi(optarg); 25310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 25410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'e': 25510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin qualify(optarg); 25610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 25710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'o': 25810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin outfname = strdup(optarg); 25910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 26010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'O': 2614bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath set_overhead(atoi(optarg)); 2624bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath break; 2634bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath case 'p': 2644bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath if ((pid = atoi(optarg)) == 0) { 2654bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath fprintf(stderr, "%s: Invalid process id: %s\n", 2664bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath progname, optarg); 26710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 26810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 26910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == getpid()) { 27010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname); 27110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 27210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 2734bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath if ((tcp = alloctcb(pid)) == NULL) { 27410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "%s: tcb table full, please recompile strace\n", 27510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin progname); 27610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 27710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 27810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin tcp->flags |= TCB_ATTACHED; 27910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin pflag_seen++; 28010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 28110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 's': 28210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin max_strlen = atoi(optarg); 28310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 28410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'S': 28510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin set_sortby(optarg); 28610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 28710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin case 'u': 28810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin username = strdup(optarg); 28910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 29010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin default: 29110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin usage(stderr, 1); 29210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin break; 29310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 29410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 29510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 29610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* See if they want to run as another user. */ 29710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (username != NULL) { 29810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin struct passwd *pent; 29910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 30010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (getuid() != 0 || geteuid() != 0) { 30110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, 30210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin "%s: you must be root to use the -u option\n", 30310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin progname); 30410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 30510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 30610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if ((pent = getpwnam(username)) == NULL) { 30710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "%s: cannot find user `%s'\n", 30810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin progname, optarg); 30910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 31010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 31110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin run_uid = pent->pw_uid; 31210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin run_gid = pent->pw_gid; 31310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 31410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin else { 31510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin run_uid = getuid(); 31610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin run_gid = getgid(); 31710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 31810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 31910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef SVR4 32010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin setreuid(geteuid(), getuid()); 32110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 32210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 32310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* See if they want to pipe the output. */ 32410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (outfname && (outfname[0] == '|' || outfname[0] == '!')) { 32510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if ((outf = popen(outfname + 1, "w")) == NULL) { 32610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "%s: can't popen '%s': %s\n", 32710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin progname, outfname + 1, strerror(errno)); 32810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 32910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 33010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin free(outfname); 33110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin outfname = NULL; 33210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 33310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 33410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* Check if they want to redirect the output. */ 33510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (outfname) { 33610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin long f; 33710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 33810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if ((outf = fopen(outfname, "w")) == NULL) { 33910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "%s: can't fopen '%s': %s\n", 34010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin progname, outfname, strerror(errno)); 34110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 34210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 34310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 34410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if ((f=fcntl(fileno(outf), F_GETFD)) < 0 ) { 34510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin perror("failed to get flags for outputfile"); 34610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 34710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 34810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 34910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (fcntl(fileno(outf), F_SETFD, f|FD_CLOEXEC) < 0 ) { 35010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin perror("failed to set flags for outputfile"); 35110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin exit(1); 35210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 35310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 35410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 35510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef SVR4 35610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin setreuid(geteuid(), getuid()); 35710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 35810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 35910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (!outfname) { 36010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin qflag = 1; 36110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin setvbuf(outf, buf, _IOLBF, BUFSIZ); 36210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 36310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin else if (optind < argc) 36410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin interactive = 0; 36510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin else 36602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath qflag = 1; 36702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 36802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (c = 0; c < tcbtabsize; c++) { 36902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[c]; 37002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Reinitialize the output since it may have changed. */ 37102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 37202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 37302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 37402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 37502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (proc_open(tcp, 1) < 0) { 37602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "trouble opening proc file\n"); 37702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 37802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 37902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 38002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 381ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 382ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("attach: ptrace(PTRACE_ATTACH, ...)"); 383ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko droptcb(tcp); 384ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko continue; 385ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 386ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif /* !USE_PROCFS */ 387ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!qflag) 388ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko fprintf(stderr, 389ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "Process %u attached - interrupt to quit\n", 390ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid); 391ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 392ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 393ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (optind < argc) { 394ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct stat statbuf; 395ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko char *filename; 396ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko char pathname[MAXPATHLEN]; 397ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 39802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[optind]; 39902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) 40002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 40102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 40202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 40302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 40402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 40502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 40602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 40702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 40802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 40902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 41002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 41102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char *path; 41202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 41302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 41402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 41502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(path, ':')) { 41602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath n = strchr(path, ':') - path; 41702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 41802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 419ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko else 42002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 42102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 42202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath getcwd(pathname, MAXPATHLEN); 42302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 42402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 42502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 42602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 42702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 42802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 42902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 43002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 43102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 43202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0) 43302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 43402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 43502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 43602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 43702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "%s: %s: command not found\n", 43802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath progname, filename); 43902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 44002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 441418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko switch (pid = fork()) { 44202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath case -1: 44302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("strace: fork"); 44402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath cleanup(); 44502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 44602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 44702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath case 0: { 44802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 44902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (outf != stderr) close (fileno (outf)); 45002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef MIPS 45102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Kludge for SGI, see proc_open for details. */ 45202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = foobar; 45302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = 0; 45402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&sa.sa_mask); 45502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGINT, &sa, NULL); 45602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* MIPS */ 45702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef FREEBSD 45802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pause(); 45902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* FREEBSD */ 46002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath kill(getpid(), SIGSTOP); /* stop HERE */ 46102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* FREEBSD */ 46202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* !USE_PROCFS */ 46302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (outf!=stderr) 46402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath close(fileno (outf)); 46502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 46602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 46702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("strace: ptrace(PTRACE_TRACEME, ...)"); 46802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return -1; 46902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 47002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (debug) 47102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath kill(getpid(), SIGSTOP); 47202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 47302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (username != NULL || geteuid() == 0) { 47402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 47502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 47602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 47702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 47802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 47902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 48002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 48102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 482ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 483ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It is important to set groups before we 484ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * lose privileges on setuid. 485ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 486ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (username != NULL) { 487ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (initgroups(username, run_gid) < 0) { 488ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("initgroups"); 489ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko exit(1); 490ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 491ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (setregid(run_gid, run_egid) < 0) { 492ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("setregid"); 493ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko exit(1); 494ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 495ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (setreuid(run_uid, run_euid) < 0) { 49602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("setreuid"); 49702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 49802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 49902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 50002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 50102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 50202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 50302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 50402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 50502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, &argv[optind]); 50602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("strace: exec"); 50702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath _exit(1); 50802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 50902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 51002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath default: 51102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if ((tcp = alloctcb(pid)) == NULL) { 51202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "tcb table full\n"); 51302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath cleanup(); 51402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 51502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 51602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 51702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (proc_open(tcp, 0) < 0) { 51802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, "trouble opening proc file\n"); 51902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath cleanup(); 52002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 52102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 52202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_PROCFS */ 52302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef USE_PROCFS 52402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fake_execve(tcp, pathname, &argv[optind], environ); 52502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !USE_PROCFS */ 52602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 52702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 52802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 52902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (pflag_seen == 0) 53002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath usage(stderr, 1); 53102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 53202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&empty_set); 53302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&blocked_set); 53402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = SIG_IGN; 53502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigemptyset(&sa.sa_mask); 53602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = 0; 53702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGTTOU, &sa, NULL); 53802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGTTIN, &sa, NULL); 53902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) { 54002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaddset(&blocked_set, SIGHUP); 54102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaddset(&blocked_set, SIGINT); 54202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaddset(&blocked_set, SIGQUIT); 54302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaddset(&blocked_set, SIGPIPE); 54402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaddset(&blocked_set, SIGTERM); 54502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = interrupt; 54602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef SUNOS4 54702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* POSIX signals on sunos4.1 are a little broken. */ 54802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_flags = SA_INTERRUPT; 54902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* SUNOS4 */ 55002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 55102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGHUP, &sa, NULL); 55202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGINT, &sa, NULL); 55302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGQUIT, &sa, NULL); 55402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGPIPE, &sa, NULL); 55502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGTERM, &sa, NULL); 55602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 55702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = reaper; 55802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGCHLD, &sa, NULL); 55902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else 56002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 56102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath definitely works without losing track of children. The user 56202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath should not have given us a bogus state to inherit, but he might 56302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 56402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath to children, but probably noone really needs that. */ 56502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sa.sa_handler = SIG_DFL; 56602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigaction(SIGCHLD, &sa, NULL); 56702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_PROCFS */ 56802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 56902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (trace() < 0) 57002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(1); 57102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath cleanup(); 57202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath exit(0); 573a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin} 574ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 57502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathvoid 57602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathnewoutf(tcp) 57702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstruct tcb *tcp; 578ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko{ 579ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko char name[MAXPATHLEN]; 580ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko FILE *fp; 581ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 582ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (outfname && followfork > 1) { 58302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(name, "%s.%u", outfname, tcp->pid); 58402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef SVR4 58502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(geteuid(), getuid()); 58602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif 58702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fp = fopen(name, "w"); 58802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef SVR4 58902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(geteuid(), getuid()); 59002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif 59102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (fp == NULL) { 59202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("fopen"); 59302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return; 59402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 595ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko tcp->outf = fp; 59602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 59702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return; 59802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 59902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 60002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstruct tcb * 601ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkoalloctcb(pid) 602ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkoint pid; 603ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko{ 604ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko int i; 605ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct tcb *tcp; 606ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 607ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko for (i = 0; i < tcbtabsize; i++) { 60802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[i]; 60902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if ((tcp->flags & TCB_INUSE) == 0) { 61002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid = pid; 61102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->parent = NULL; 61202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->nchildren = 0; 61302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->flags = TCB_INUSE | TCB_STARTUP; 61402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; /* Initialise to current out file */ 61502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->stime.tv_sec = 0; 61602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->stime.tv_usec = 0; 61702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pfd = -1; 61802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath nprocs++; 61902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return tcp; 62002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 62102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 62202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return NULL; 62302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 62402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 62502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_PROCFS 62602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathint 62702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathproc_open(tcp, attaching) 62802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstruct tcb *tcp; 62902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathint attaching; 63002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 63102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char proc[32]; 63202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath long arg; 63302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef SVR4 63402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int i; 63502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sysset_t syscalls; 63602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigset_t signals; 63702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fltset_t faults; 63802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif 63902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef HAVE_POLLABLE_PROCFS 64002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath static int last_pfd; 641ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#endif 642ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 643ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifdef HAVE_MP_PROCFS 644ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* Open the process pseudo-files in /proc. */ 645ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sprintf(proc, "/proc/%d/ctl", tcp->pid); 646ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 647ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("strace: open(\"/proc/...\", ...)"); 648ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 649ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 650ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 651ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("F_GETFD"); 652ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 653ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 654ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 655ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("F_SETFD"); 656ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 657ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 658ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sprintf(proc, "/proc/%d/status", tcp->pid); 659ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 660ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("strace: open(\"/proc/...\", ...)"); 661ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 662ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 663ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) { 664ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("F_GETFD"); 66502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return -1; 66602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 66702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) { 66802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("F_SETFD"); 66902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return -1; 67002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 671ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sprintf(proc, "/proc/%d/as", tcp->pid); 672ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 673ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("strace: open(\"/proc/...\", ...)"); 674ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 675ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 676ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) { 677ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("F_GETFD"); 67802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return -1; 679ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 680ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) { 681ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("F_SETFD"); 682ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 68302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 684ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#else 68502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Open the process pseudo-file in /proc. */ 68602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef FREEBSD 68776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 68808b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) { 68976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* FREEBSD */ 69076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 69176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->pfd = open(proc, O_RDWR)) < 0) { 69206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin#endif /* FREEBSD */ 69376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 69476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 69576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 69676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 69708b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin perror("F_GETFD"); 69808b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin return -1; 699ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 700ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 701418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko perror("F_SETFD"); 70208b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin return -1; 70308b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin } 70408b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin#endif 705418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko#ifdef FREEBSD 70608b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin sprintf(proc, "/proc/%d/regs", tcp->pid); 70708b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 70808b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin perror("strace: open(\"/proc/.../regs\", ...)"); 709ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath return -1; 710ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 711ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (cflag) { 71276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 71376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 714138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath perror("strace: open(\"/proc/.../status\", ...)"); 715138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath return -1; 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else 71876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd_status = -1; 71976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* FREEBSD */ 72076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 721ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!attaching) { 722ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 723ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Wait for the child to pause. Because of a race 724ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * condition we have to poll for the event. 725ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 72676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 72776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL_STATUS (tcp) < 0) { 72876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 72976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 73076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 73176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 73276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 73376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 734ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 735ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko#ifndef FREEBSD 736ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* Stop the process so that we own the stop. */ 737ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 738ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko perror("strace: PIOCSTOP"); 739ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return -1; 74041c48227a86a176da333f713d5047240885f25ccRoland McGrath } 74106350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin#endif 74206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin#ifdef PIOCSET 74376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 74476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 74576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 74676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 74776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 74876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 75676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef FREEBSD 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* FREEBSD */ 76676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCGFL"); 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg &= ~PF_LINGER; 7729c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFL"); 77476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77517f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig } 77617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig#endif /* FREEBSD */ 77717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig#endif /* !PIOCSET */ 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef FREEBSD 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Enable all syscall entries we care about. */ 78076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman premptyset(&syscalls); 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 1; i < MAX_QUALS; ++i) { 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i > (sizeof syscalls) * CHAR_BIT) break; 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i); 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_execve); 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork) { 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_fork); 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SYS_forkall 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_forkall); 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 791de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath#ifdef SYS_fork1 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_fork1); 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 79476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SYS_rfork1 79576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_rfork1); 79676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 79754a4767f8609abfe2d7cb1802bc9e8dca97dd08fWichert Akkerman#ifdef SYS_rforkall 79876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman praddset (&syscalls, SYS_rforkall); 79976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 800418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko } 80176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 80276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 80376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 80476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 80576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Enable the syscall exits. */ 806dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 807dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath perror("PIOSEXIT"); 808dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath return -1; 809dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 810dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath /* Enable signals we care about. */ 811dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath premptyset(&signals); 81276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 1; i < MAX_QUALS; ++i) { 81376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i > (sizeof signals) * CHAR_BIT) break; 81476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i); 81576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 81676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 81776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 81876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 819de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath } 820de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath /* Enable faults we care about */ 821de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath premptyset(&faults); 822de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath for (i = 1; i < MAX_QUALS; ++i) { 823de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if (i > (sizeof faults) * CHAR_BIT) break; 824de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i); 825de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath } 82676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 82776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 82876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 82976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* FREEBSD */ 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set events flags. */ 832d0c4c0cb881facd0ccf16b0c266875a8bf3e56aaRoland McGrath arg = S_SIG | S_SCE | S_SCX ; 833ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 834ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath perror("PIOCBIS"); 83506350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin return -1; 83606350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin } 83706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin#endif /* FREEBSD */ 838cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (!attaching) { 839cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath#ifdef MIPS 840cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath /* 841cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath * The SGI PRSABORT doesn't work for pause() so 842cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath * we send it a caught signal to wake it up. 843cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath */ 844cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath kill(tcp->pid, SIGINT); 84576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PRSABORT 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PRSABORT; 84976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 85076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 85176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 85276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 85376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 85476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !MIPS*/ 85576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef FREEBSD 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 85709553f85cd97c4ad35cdf316c8e65621b9e86712Roland McGrath kill(tcp->pid, SIGCONT); 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 85976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 86076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 86176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL_WSTOP (tcp) < 0) { 86276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 86376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 86476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 86576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 86676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman get_scno(tcp); 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->scno == SYS_execve) 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 87037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath } 87137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* Set it running: maybe execve will be next. */ 87237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath#ifndef FREEBSD 87337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath arg = 0; 87437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 87537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath#else /* FREEBSD */ 87637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 87737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath#endif /* FREEBSD */ 87837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath perror("PIOCRUN"); 87937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath return -1; 88037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath } 88137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath#ifdef FREEBSD 88237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* handle the case where we "opened" the child before 88310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin it did the kill -STOP */ 88437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (tcp->status.PR_WHY == PR_SIGNALLED && 88554b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 88610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin kill(tcp->pid, SIGCONT); 88710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 88854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef FREEBSD 89076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 89137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath#else /* FREEBSD */ 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } else { 89337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (attaching < 2) { 89476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* We are attaching to an already running process. 89576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Try to figure out the state of the process in syscalls, 896369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath * to handle the first event well. 89754cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath * This is done by having a look at the "wchan" property of the 89854cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath * process, which tells where it is stopped (if it is). */ 89954cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath FILE * status; 90054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath char wchan[20]; /* should be enough */ 90154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 90254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath sprintf(proc, "/proc/%d/status", tcp->pid); 90354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath status = fopen(proc, "r"); 90454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath if (status && 90554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 90654cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath "%*d,%*d %*d,%*d %19s", wchan) == 1) && 90754cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 90854cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath strcmp(wchan, "stopevent")) { 90954cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* The process is asleep in the middle of a syscall. 91054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Fake the syscall entry event */ 91176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 91276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 91376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman trace_syscall(tcp); 91476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (status) 91676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(status); 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } /* otherwise it's a fork being followed */ 91876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* FREEBSD */ 92076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 92176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 92276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 92376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 92476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 92576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 92676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 92776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 92876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 92976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 93076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 93176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 93276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* USE_PROCFS */ 93476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 93576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 936bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanpid2tcb(pid) 93776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 93876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 939553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath int i; 940553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath struct tcb *tcp; 941553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 942553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath for (i = 0; i < tcbtabsize; i++) { 943553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath tcp = tcbtab[i]; 944553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (pid && tcp->pid != pid) 945553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath continue; 946553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (tcp->flags & TCB_INUSE) 947bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return tcp; 94876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 949ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko return NULL; 95002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 95102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef USE_PROCFS 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 955a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinpfd2tcb(pfd) 956a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinint pfd; 957a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin{ 958a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin int i; 959a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin struct tcb *tcp; 960a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin 961a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin for (i = 0, tcp = tcbtab; i < tcbtabsize; i++, tcp++) { 962a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (tcp->pfd != pfd) 963a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin continue; 964a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (tcp->flags & TCB_INUSE) 965a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin return tcp; 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 968418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko} 969418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 9707b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath#endif /* USE_PROCFS */ 9717b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 9727b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrathvoid 9737b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrathdroptcb(tcp) 9747b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrathstruct tcb *tcp; 9757b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 9767b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath if (tcp->pid == 0) 9777b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath return; 9787b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath nprocs--; 9797b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcp->pid = 0; 9807b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcp->flags = 0; 9817b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 98276860f60d73bbdcc98725b6f8d7997ad0746cac2Dmitry V. Levin if (tcp->pfd != -1) { 98376860f60d73bbdcc98725b6f8d7997ad0746cac2Dmitry V. Levin close(tcp->pfd); 984418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp->pfd = -1; 985418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko#ifdef FREEBSD 9867b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath if (tcp->pfd_reg != -1) { 9877b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath close(tcp->pfd_reg); 9887b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcp->pfd_reg = -1; 9897b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath } 9907b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath if (tcp->pfd_status != -1) { 9917b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath close(tcp->pfd_status); 9927b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcp->pfd_status = -1; 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif /* !FREEBSD */ 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef USE_PROCFS 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 999418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (tcp->parent != NULL) { 1000418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp->parent->nchildren--; 1001418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp->parent = NULL; 1002ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 1003ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = 0; 10080962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath} 1009e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1010e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifndef USE_PROCFS 1011e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1012e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstatic int 101376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanresume(tcp) 101476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 101576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 101676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp == NULL) 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (!(tcp->flags & TCB_SUSPENDED)) { 102010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid); 102176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 102376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 1024418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1025418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) { 1026418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko perror("resume: ptrace(PTRACE_SYSCALL, ...)"); 102776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 102876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1029bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 103076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 1031418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko fprintf(stderr, "Process %u resumed\n", tcp->pid); 103276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 103376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 103476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1035bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 103619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes 103719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes/* detach traced process; continue with sig */ 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 103976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 1040bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermandetach(tcp, sig) 104176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 104276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 104376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 104476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1045ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef LINUX 10469ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int status; 10479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 10489ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 10499ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->flags & TCB_BPTSET) 10509ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sig = SIGKILL; 10519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 105210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifdef LINUX 10539ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* 10549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman * Linux wrongly insists the child be stopped 10559ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman * before detaching. Arghh. We go through hoops 10569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman * to make a clean break of things. 10579ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman */ 10589ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#if defined(SPARC) 10599ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#undef PTRACE_DETACH 106010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#define PTRACE_DETACH PTRACE_SUNDETACH 10619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 10629ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 10639ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* On a clear day, you can see forever. */ 10649ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 10659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman else if (errno != ESRCH) { 10669ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Shouldn't happen. */ 10679ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 106810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 10699ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman else if (kill(tcp->pid, 0) < 0) { 10709ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (errno != ESRCH) 10719ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("detach: checking sanity"); 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1073bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else if (kill(tcp->pid, SIGSTOP) < 0) { 107476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno != ESRCH) 107576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: stopping child"); 1076bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1077bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else { 1078bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman for (;;) { 1079bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef __WALL 108076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno == ECHILD) /* Already gone. */ 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 108310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (errno != EINVAL) { 10849ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("detach: waiting"); 10859ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman break; 10869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 1087bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* __WALL */ 1088bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* No __WALL here. */ 1089bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (waitpid(tcp->pid, &status, 0) < 0) { 1090bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (errno != ECHILD) { 1091bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("detach: waiting"); 1092bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 1093bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1094bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef __WCLONE 1095bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* If no processes, try clones. */ 1096bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (wait4(tcp->pid, &status, __WCLONE, 1097bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman NULL) < 0) { 1098bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (errno != ECHILD) 1099bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("detach: waiting"); 1100bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 1101bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* __WCLONE */ 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __WALL 110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 11099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman break; 111076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 111276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, 11139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->pid, (char *) 1, sig)) < 0) { 1114bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (errno != ESRCH) 111576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* I died trying. */ 1117bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 111876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 111916a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman } 112076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1, 112176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman WSTOPSIG(status) == SIGTRAP ? 112276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 0 : WSTOPSIG(status))) < 0) { 1123553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (errno != ESRCH) 112476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_CONT, ...)"); 112576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 112676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11279ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 112876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 112976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 113076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 113176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 11339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (sig && kill(tcp->pid, sig) < 0) 113476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: kill"); 113576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = 0; 113676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0) 113776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 1138553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* SUNOS4 */ 113976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 114076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef USE_PROCFS 114176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (waiting_parent(tcp)) 114276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman error = resume(tcp->parent); 114376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !USE_PROCFS */ 114476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 114576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 114676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 1147bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1148bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman droptcb(tcp); 1149bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return error; 1150bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman} 1151bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1152bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 1153bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1154bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanstatic void 1155bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanreaper(sig) 1156bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanint sig; 1157bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman{ 1158bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int pid; 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 1160bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 116119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 116219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#if 0 116319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes struct tcb *tcp; 116419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes 116519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes tcp = pid2tcb(pid); 116619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (tcp) 116719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes droptcb(tcp); 116819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 116919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 117019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes} 117119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes 117219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif /* USE_PROCFS */ 1173553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 117419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughesstatic void 117519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughescleanup() 117619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes{ 117719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 117819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes struct tcb *tcp; 117919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes 118019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 0; i < tcbtabsize; i++) { 118119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes tcp = tcbtab[i]; 118219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (!(tcp->flags & TCB_INUSE)) 118319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes continue; 118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 118719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (tcp_last && 118819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes (!outfname || followfork < 2 || tcp_last == tcp)) { 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" <unfinished ...>\n"); 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 119176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 119219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (tcp->flags & TCB_ATTACHED) 119319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes detach(tcp, 0); 119419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes else { 119519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes kill(tcp->pid, SIGCONT); 119619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes kill(tcp->pid, SIGTERM); 119719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 11989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 119976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 120076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 120176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 120219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes 120319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughesstatic void 120419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughesinterrupt(sig) 120519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughesint sig; 120619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes{ 120719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes interrupted = 1; 12089ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 120976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 121076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 121176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1212bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#if !HAVE_DECL_SYS_ERRLIST 1213bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanextern int sys_nerr; 1214bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanextern char *sys_errlist[]; 1215bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* HAVE_DECL_SYS_ERRLIST */ 1216bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1217bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanconst char * 1218bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanstrerror(errno) 1219bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanint errno; 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno < 1 || errno >= sys_nerr) { 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown error %d", errno); 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 122676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_errlist[errno]; 1228553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath} 122976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12309ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif /* HAVE_STERRROR */ 12319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 123276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 123376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 123476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 1235553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#if !HAVE_DECL_SYS_SIGLIST 1236bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanextern char *sys_siglist[]; 1237bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman extern char *_sys_siglist[]; 1238bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else 1239bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 1240553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* SYS_SIGLIST_DECLARED */ 124176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 12439ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkermanstrsignal(sig) 124476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 124676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 12479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 1248bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (sig < 1 || sig >= NSIG) { 1249bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 125076989d7a16cb9683d0a75a6261f18ced66d0c04aRoland McGrath return buf; 125176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 1254bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else 12559ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return sys_siglist[sig]; 12569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 1257bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman} 1258bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1259553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* HAVE_STRSIGNAL */ 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef USE_PROCFS 126276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1263bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanstatic void 1264bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanrebuild_pollv() 1265bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman{ 1266bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int i, j; 1267bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct tcb *tcp; 1268bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1269553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (pollv != NULL) 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman free (pollv); 1271bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pollv = (struct poll *) malloc(nprocs * sizeof pollv[0]); 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv == NULL) { 1273bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman fprintf(stderr, "strace: out of memory for poll vector\n"); 1274bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman exit(1); 1275553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath } 12762e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman 12772e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman for (i = j = 0, tcp = tcbtab; i < tcbtabsize; i++, tcp++) { 12782e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 12792e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 12802e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman pollv[j].fd = tcp->pfd; 12812e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman pollv[j].events = POLLWANT; 12822e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman j++; 1283553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath } 12842e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (j != nprocs) { 12852e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 12862e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman exit(1); 12872e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 12882e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman} 12892e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman 12902e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 12912e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman 12922e4ffe59b588159eb80e236f068278ba47735932Wichert Akkermanstatic void 12932e4ffe59b588159eb80e236f068278ba47735932Wichert Akkermanproc_poll_open() 12942e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman{ 12952e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman int arg; 12962e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman int i; 12972e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman 12982e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 12992e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman perror("pipe"); 1300bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman exit(1); 1301bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) { 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_GETFD"); 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) { 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_SETFD"); 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 1315bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanproc_poll(pollv, nfds, timeout) 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct pollfd *pollv; 1317e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathint nfds; 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint timeout; 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1324ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 1325ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath return n; 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "panic: short read: %d\n", n); 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 1334bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pollv[i].revents = 0; 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 133876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 133976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanwakeup_handler(sig) 1342ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrathint sig; 1343ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath{ 134476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 134576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poller(pfd) 134876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pfd; 134976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 1352bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sigset_t blocked_set, empty_set; 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef FREEBSD 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct procfs_status pfs; 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* FREEBSD */ 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1360e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath switch (fork()) { 1361e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath case -1: 1362e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath perror("fork"); 1363e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath _exit(0); 1364e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath case 0: 1365e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath break; 1366e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath default: 1367e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return; 1368e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1369e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 1372eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman sigemptyset(&sa.sa_mask); 1373e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGHUP, &sa, NULL); 1374e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGINT, &sa, NULL); 1375e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGQUIT, &sa, NULL); 1376e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGPIPE, &sa, NULL); 1377e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGTERM, &sa, NULL); 1378e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sa.sa_handler = wakeup_handler; 1379e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigaction(SIGUSR1, &sa, NULL); 1380e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath sigemptyset(&blocked_set); 13810962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath sigaddset(&blocked_set, SIGUSR1); 13820962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 13830962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath sigemptyset(&empty_set); 13840962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath 1385276ceb33f20fc41403e46684e441230296f6a433Roland McGrath if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 1386276ceb33f20fc41403e46684e441230296f6a433Roland McGrath perror("getrlimit(RLIMIT_NOFILE, ...)"); 1387276ceb33f20fc41403e46684e441230296f6a433Roland McGrath _exit(0); 1388276ceb33f20fc41403e46684e441230296f6a433Roland McGrath } 1389276ceb33f20fc41403e46684e441230296f6a433Roland McGrath n = rl.rlim_cur; 1390276ceb33f20fc41403e46684e441230296f6a433Roland McGrath for (i = 0; i < n; i++) { 1391276ceb33f20fc41403e46684e441230296f6a433Roland McGrath if (i != pfd && i != proc_poll_pipe[1]) 1392276ceb33f20fc41403e46684e441230296f6a433Roland McGrath close(i); 1393276ceb33f20fc41403e46684e441230296f6a433Roland McGrath } 1394276ceb33f20fc41403e46684e441230296f6a433Roland McGrath 1395e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath pollinfo.fd = pfd; 1396e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath pollinfo.pid = getpid(); 1397e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath for (;;) { 1398e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath#ifndef FREEBSD 139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* FREEBSD */ 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 1402bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 1403bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman { 1404bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman switch (errno) { 1405bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case EINTR: 1406bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman continue; 1407bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case EBADF: 1408bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pollinfo.revents = POLLERR; 1409bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 1410bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOENT: 1411553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath pollinfo.revents = POLLHUP; 1412bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 1413e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath default: 141476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 141576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1416eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 1417822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman _exit(0); 141876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1419eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman pollinfo.revents = POLLWANT; 142076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 142176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1423bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman} 142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 143276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 143476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 1437e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* 1438e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath * The previous process is ready to run again. We'll 1439e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath * let it do so if it is currently in a syscall. This 1440e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath * heuristic improves the readability of the trace. 144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1442732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko tcp = pfd2tcb(pollv[last].fd); 144376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp && (tcp->flags & TCB_INSYSCALL)) 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 144776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 144876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 14501bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (pollv[j].revents & (POLLHUP | POLLERR)) { 14511bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath tcp = pfd2tcb(pollv[j].fd); 14521bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (!tcp) { 14531bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath fprintf(stderr, "strace: lost proc\n"); 14541bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath exit(1); 14551bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath } 14561bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath droptcb(tcp); 14571bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath return -1; 14581bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath } 14591bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (pollv[j].revents & POLLWANT) { 14601bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath last = j; 14611bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath return pollv[j].fd; 14621bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath } 14631bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath } 14641bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath fprintf(stderr, "strace: nothing ready\n"); 14651bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath exit(1); 14661bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath} 14671bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath 14681bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrathstatic int 14691bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrathtrace() 14701bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath{ 14711bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifdef POLL_HACK 14721bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath struct tcb *in_syscall = NULL; 14731bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#endif 14741bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath struct tcb *tcp; 14751bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int pfd; 14761bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int what; 14771bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath int ioctl_result = 0, ioctl_errno = 0; 14781bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath long arg; 14791bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath 14801bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath for (;;) { 14811bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (interactive) 14821bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 14831bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath 14841bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (nprocs == 0) 14851bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath break; 14861bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath 14871bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath switch (nprocs) { 14881bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath case 1: 14891bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifndef HAVE_POLLABLE_PROCFS 14901bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (proc_poll_pipe[0] == -1) { 14911bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#endif 14921bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath tcp = pid2tcb(0); 14931bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (!tcp) 14941bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath continue; 14951bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath pfd = tcp->pfd; 14961bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (pfd == -1) 14971bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath continue; 14981bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath break; 14991bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifndef HAVE_POLLABLE_PROCFS 15001bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath } 15011bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath /* fall through ... */ 15021bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#endif /* !HAVE_POLLABLE_PROCFS */ 15031bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath default: 15041bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifdef HAVE_POLLABLE_PROCFS 15051bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifdef POLL_HACK 15061bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath /* On some systems (e.g. UnixWare) we get too much ugly 15071bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath "unfinished..." stuff when multiple proceses are in 15081bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath syscalls. Here's a nasty hack */ 15091bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath 15101bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath if (in_syscall) { 15111bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath struct pollfd pv; 15121bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath tcp = in_syscall; 15131bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath in_syscall = NULL; 15141bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath pv.fd = tcp->pfd; 1515bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pv.events = POLLWANT; 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((what = poll (&pv, 1, 1)) < 0) { 15170a463880341945df08b6dc79134dc78cc38dc283Roland McGrath if (interrupted) 15180a463880341945df08b6dc79134dc78cc38dc283Roland McGrath return 0; 15190a463880341945df08b6dc79134dc78cc38dc283Roland McGrath continue; 15200a463880341945df08b6dc79134dc78cc38dc283Roland McGrath } 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto FOUND; 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 1528ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath if (interrupted) 15291bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath return 0; 1530a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath continue; 1531a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath } 1532a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath#else /* !HAVE_POLLABLE_PROCFS */ 1533a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath if (proc_poll(pollv, nprocs, INFTIM) < 0) { 1534a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath if (interrupted) 1535a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath return 0; 1536a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath continue; 1537a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath } 1538ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif /* !HAVE_POLLABLE_PROCFS */ 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 15467bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if ((tcp = pfd2tcb(pfd)) == NULL) { 15477bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath fprintf(stderr, "unknown pfd: %u\n", pfd); 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 15497bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 15507bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#ifdef POLL_HACK 15517bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath FOUND: 15527bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 155302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Get the status of the process. */ 155402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!interrupted) { 155502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifndef FREEBSD 155602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ioctl_result = IOCTL_WSTOP (tcp); 155702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#else /* FREEBSD */ 155802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Thanks to some scheduling mystery, the first poller 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sometimes waits for the already processed end of fork 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 15617bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (proc_poll_pipe[0] != -1) 15627bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath ioctl_result = IOCTL_STATUS (tcp); 15637bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else 15647bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath ioctl_result = IOCTL_WSTOP (tcp); 15657bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* FREEBSD */ 1566134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath ioctl_errno = errno; 1567134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath#ifndef HAVE_POLLABLE_PROCFS 1568134813ae1ecf7f214440a5a09d5eff15a71bf8e6Roland McGrath if (proc_poll_pipe[0] != -1) { 15697bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (ioctl_result < 0) 15707bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath kill(poller_pid, SIGKILL); 15717bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else 157202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath kill(poller_pid, SIGUSR1); 157302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 157402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* !HAVE_POLLABLE_PROCFS */ 15757bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 15767bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (interrupted) 15777bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath return 0; 157802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 157902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 1580ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15827508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (ioctl_result < 0) { 15837508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* Find out what happened if it failed. */ 15847508cb4678141d146d819120f6b5b428c103882eRoland McGrath switch (ioctl_errno) { 15857508cb4678141d146d819120f6b5b428c103882eRoland McGrath case EINTR: 15867508cb4678141d146d819120f6b5b428c103882eRoland McGrath case EBADF: 158776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 15887508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef FREEBSD 15897508cb4678141d146d819120f6b5b428c103882eRoland McGrath case ENOTTY: 15907508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 15917508cb4678141d146d819120f6b5b428c103882eRoland McGrath case ENOENT: 15927508cb4678141d146d819120f6b5b428c103882eRoland McGrath droptcb(tcp); 15937508cb4678141d146d819120f6b5b428c103882eRoland McGrath continue; 15947508cb4678141d146d819120f6b5b428c103882eRoland McGrath default: 15957508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("PIOCWSTOP"); 15967508cb4678141d146d819120f6b5b428c103882eRoland McGrath exit(1); 15977508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 15987508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 15997508cb4678141d146d819120f6b5b428c103882eRoland McGrath 16007508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef FREEBSD 16017508cb4678141d146d819120f6b5b428c103882eRoland McGrath if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 16027508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* discard first event for a syscall we never entered */ 16037508cb4678141d146d819120f6b5b428c103882eRoland McGrath IOCTL (tcp->pfd, PIOCRUN, 0); 16047508cb4678141d146d819120f6b5b428c103882eRoland McGrath continue; 16057508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16067508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 16077508cb4678141d146d819120f6b5b428c103882eRoland McGrath 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 16097508cb4678141d146d819120f6b5b428c103882eRoland McGrath tcp->flags &= ~TCB_STARTUP; 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 1615732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko struct timeval stime; 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef FREEBSD 161776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char buf[1024]; 1618732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko int len; 161996d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko 1620732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 1621732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko buf[len] = '\0'; 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sscanf(buf, 162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 1624ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko &stime.tv_sec, &stime.tv_usec); 16257bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } else 162676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !FREEBSD */ 162876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 162976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 163076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !FREEBSD */ 163176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 1632732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko tcp->stime = stime; 163376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman what = tcp->status.PR_WHAT; 1635bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman switch (tcp->status.PR_WHY) { 16361bfd31032538222fa7d6b5d1741f1a4efa0eb739Roland McGrath#ifndef FREEBSD 1637e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath case PR_REQUESTED: 1638e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->status.PR_FLAGS & PR_ASLEEP) { 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 1643a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath } 1644a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath } 16450a463880341945df08b6dc79134dc78cc38dc283Roland McGrath break; 16460a463880341945df08b6dc79134dc78cc38dc283Roland McGrath#endif /* !FREEBSD */ 16470a463880341945df08b6dc79134dc78cc38dc283Roland McGrath case PR_SYSENTRY: 16480a463880341945df08b6dc79134dc78cc38dc283Roland McGrath#ifdef POLL_HACK 1649a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath in_syscall = tcp; 1650a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath#endif 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 165276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 1654bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman exit(1); 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 165676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 165876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) { 165976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 166076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) ---", 166176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman signame(what), strsignal(what)); 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PR_INFO 166476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->status.PR_INFO.si_signo == what) { 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" siginfo="); 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printsiginfo(&tcp->status.PR_INFO, 1); 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 1674bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_FAULT)) { 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("=== FAULT %d ===", what); 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef FREEBSD 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: /* handle case we polled for nothing */ 1682ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath continue; 1683ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath#endif 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY); 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = 0; 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef FREEBSD 1691ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 1692ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko#else 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) { 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !USE_PROCFS */ 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantrace() 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int wait_errno; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __WALL 17146d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath static int wait4_options = __WALL; 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 17176d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (nprocs != 0) { 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __WALL 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL); 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* this kernel does not support __WALL */ 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait4_options &= ~__WALL; 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = 0; 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait4(-1, &status, wait4_options, 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cflag ? &ru : NULL); 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* most likely a "cloned" process */ 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait4(-1, &status, __WCLONE, 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cflag ? &ru : NULL); 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == -1) { 17368f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath fprintf(stderr, "strace: clone wait4 " 17376d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath "failed: %s\n", strerror(errno)); 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17398f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath } 17408f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#else 17418f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath pid = wait4(-1, &status, 0, cflag ? &ru : NULL); 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* __WALL */ 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 174776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == -1) { 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (wait_errno) { 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ECHILD: 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 1762bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman * version of SunOS sometimes reports 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 1769ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath exit(1); 1770ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath#endif 1771c012d223a6b915f06ef32b8aaa52b984015d192eRoland McGrath return 0; 1772ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath default: 177346100d07257824da2ae1147da0324b5788c95501Roland McGrath errno = wait_errno; 1774ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath perror("strace: wait"); 1775ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath return -1; 1776ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 1777ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath } 1778ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath if (debug) 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, " [wait(%#x) = %u]\n", status, pid); 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pid' in our table. */ 17829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp = pid2tcb(pid)) == NULL) { 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 /* XXX davidm */ /* WTA: disabled again */ 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcpchild; 178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcpchild = alloctcb(pid)) == NULL) { 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, " [tcb table full]\n"); 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(pid, SIGKILL); /* XXX */ 178976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 179076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcpchild->flags |= TCB_ATTACHED; 179276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman newoutf(tcpchild); 179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->nchildren++; 179476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %d attached\n", pid); 179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "unknown pid: %u\n", pid); 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSTOPPED(status)) 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_CONT, pid, (char *) 1, 0); 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* set current output file */ 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !LINUX */ 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 181176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 181276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 181476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Apparently, doing any ptrace() call on a stopped 181576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process, provokes the kernel to report the process 181676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * status again on a subsequent wait(), even if the 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process has not been actually restarted. 181876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we have inspected the arguments of suspended 181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * processes we end up here testing for this case. 182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 182476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 182576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 182676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 182776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("+++ killed by %s +++", 182876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman signame(WTERMSIG(status))); 182976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 183276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 183376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 183576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 183676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u exited\n", pid); 183776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 183876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 183976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "PANIC: attached pid %u exited\n", 184076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid); 184176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 184276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 184376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 184476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 184576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 184676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 184776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 184876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 184976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 185076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u stopped, [%s]\n", 1851bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman pid, signame(WSTOPSIG(status))); 1852bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1853bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->flags & TCB_STARTUP) { 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * This flag is there to keep us in sync. 185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Next time this process stops it should 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * really be entering a system call. 1858a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin */ 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 186076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) { 186176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 186276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interestingly, the process may stop 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * with STOPSIG equal to some other signal 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * than SIGSTOP if we happend to attach 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * just before the process takes a signal. 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "pid %u not stopped\n", pid); 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 187276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 187376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 187476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 187576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 187676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* A child of us stopped at exec */ 187776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGTRAP && followvfork) 187876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fixvfork(tcp); 187976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 188076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 1882a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (clearbpt(tcp) < 0) /* Pretty fatal */ { 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 188476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 188576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 188676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto tracing; 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) != SIGTRAP) { 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP && 1893bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman (tcp->flags & TCB_SIGTRAPPED)) { 1894bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* 1895bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman * Trapped attempt to block SIGTRAP 1896bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman * Hope we are back in control now. 1897bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman */ 18989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 189976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid, (char *) 1, 0) < 0) { 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 190476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 190676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 190876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 190976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman unsigned long addr = 0, pc = 0; 191076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PT_GETSIGINFO 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman# define PSR_RI 41 191276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct siginfo si; 191376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman unsigned long psr; 19149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 191576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman upeek(pid, PT_CR_IPSR, &psr); 191676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman upeek(pid, PT_CR_IIP, &pc); 191776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 191976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PT_GETSIGINFO, pid, 0, (long) &si); 192076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman addr = (unsigned long) si.si_addr; 192176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 192276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 192376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) @ %lx (%lx) ---", 192476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman signame(WSTOPSIG(status)), 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strsignal(WSTOPSIG(status)), pc, addr); 192676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_ATTACHED) && 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman !sigishandled(tcp, WSTOPSIG(status))) { 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 19319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman continue; 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman WSTOPSIG(status)) < 0) { 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 194376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_KILL, 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid, (char *) 1, SIGTERM); 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_EXITING) { 195376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 19549ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman detach(tcp, 0); 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) { 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: ptrace(PTRACE_CONT, ...)"); 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 196176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u suspended\n", pid); 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 19669dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 1967d870b3c31a0139b335a66a829169bacc74624c44John Hughes tracing: 19689dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) { 196976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 197076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 197276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 197476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !USE_PROCFS */ 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int curcol; 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <stdarg.h> 198376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a, b) 198476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <varargs.h> 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a) 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(fmt, va_alist) 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanva_dcl 199676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20009dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman VA_START(args, fmt); 20019dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (outf) 20029dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman curcol += vfprintf(outf, fmt, args); 20039dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman va_end(args); 2004553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath return; 20059dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman} 20069dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 20079dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkermanvoid 20089dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkermanprintleader(tcp) 20099dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkermanstruct tcb *tcp; 20109dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman{ 20119dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) { 20129dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp_last->flags |= TCB_REPRINT; 20139dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tprintf(" <unfinished ...>\n"); 20149dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 20159dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman curcol = 0; 20169dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 20179dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tprintf("%-5d ", tcp->pid); 20189dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (nprocs > 1 && !outfname) 20199dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 20209dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (tflag) { 20219dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman char str[sizeof("HH:MM:SS")]; 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 204376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 204476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 2045b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes } 20469dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 2047b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes if (iflag) 204876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 204976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 2050bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 20519ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkermanvoid 2052bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermantabto(col) 2053bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanint col; 2054bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman{ 2055bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (curcol < col) 2056bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tprintf("%*s", col - curcol, ""); 2057bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman} 2058bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 2059bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkermanvoid 2060553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrathprinttrailer(tcp) 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\n"); 206476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_MP_PROCFS 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint mp_ioctl (int fd, int cmd, void *arg, int size) { 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct iovec iov[2]; 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n = 1; 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iov[0].iov_base = &cmd; 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iov[0].iov_len = sizeof cmd; 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (arg) { 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ++n; 207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iov[1].iov_base = arg; 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iov[1].iov_len = size; 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return writev (fd, iov, n); 2083bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman} 2084bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 2085553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman