strace.c revision ce0d15442eec017b1dcbfdd14ac92e73c39c586a
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 332ee6e45f36566e8735b35ffad40bfcc626a25a98Wichert Akkerman#include <sys/types.h> 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 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> 4776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 487b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#if defined(IA64) && defined(LINUX) 497b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 507b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 517b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 52bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 53bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#include <poll.h> 54bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 55bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 5676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 5776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stropts.h> 58ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 591d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#ifdef HAVE_SYS_UIO_H 609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#include <sys/uio.h> 619ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 6276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 631d08dcf46dd4b2cfe3e27723c05b0aec9955c591John Hughes#endif 6476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 6576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint debug = 0, followfork = 0, followvfork = 0, interactive = 0; 6676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint rflag = 0, tflag = 0, dtime = 0, cflag = 0; 6776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint iflag = 0, xflag = 0, qflag = 0; 6876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pflag_seen = 0; 6976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7017f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 7117f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvigint not_failing_only = 0; 7217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 7376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *username = NULL; 7476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanuid_t run_uid; 7576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermangid_t run_gid; 7676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 7776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint acolumn = DEFAULT_ACOLUMN; 7876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint max_strlen = DEFAULT_STRLEN; 7976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *outfname = NULL; 8076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanFILE *outf; 81ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstruct tcb **tcbtab; 82ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathunsigned int nprocs, tcbtabsize; 8376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *progname; 8476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char **environ; 8576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 8676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int trace P((void)); 8776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void cleanup P((void)); 8876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void interrupt P((int sig)); 8976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 9076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 9176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 9276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 9376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_SIG_ATOMIC_T */ 9476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 9576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 9676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !__STDC__ */ 9776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int interrupted; 9876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !__STDC__ */ 9976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_SIG_ATOMIC_T */ 10076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 101bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 10276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb *pfd2tcb P((int pfd)); 10476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void reaper P((int sig)); 10576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void rebuild_pollv P((void)); 106ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrathstatic struct pollfd *pollv; 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 10976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poll_open P((void)); 11176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void proc_poller P((int pfd)); 11276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct proc_pollfd { 11476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int fd; 11576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int revents; 11676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 11776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman}; 11876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int poller_pid; 12076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int proc_poll_pipe[2] = { -1, -1 }; 12176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 12276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 12376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 124ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 1259ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLWRNORM 1269ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 1279ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#define POLLWANT POLLPRI 1289ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 129bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 13076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 13276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage(ofp, exitval) 13376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert AkkermanFILE *ofp; 13476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint exitval; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 13676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 13776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanusage: strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ 138de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ 139de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 140de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath or: strace -c [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ 141de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath [command [arg ...]]\n\ 14276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 14376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-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\ 160de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 161de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 162de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath" /* this is broken, so don't document it 16317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 164de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath */ 165de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 16676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 16776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SVR4 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 17276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanfoobar() 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SVR4 */ 17776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 17976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanmain(argc, argv) 18076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint argc; 18176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *argv[]; 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern int optind; 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman extern char *optarg; 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 18676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int c, pid = 0; 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 18876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[BUFSIZ]; 19076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 191ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 192ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 193ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab = (struct tcb **) malloc (tcbtabsize * sizeof tcbtab[0]); 194ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab[0] = (struct tcb *) calloc (tcbtabsize, sizeof *tcbtab[0]); 195ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp) 196ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]]; 197ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname = argv[0]; 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 1; 20176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 20276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 20376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(DEFAULT_SORTBY); 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_personality(DEFAULT_PERSONALITY); 20776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 208de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath "+cdfFhiqrtTvVxza:e:o:O:p:s:S:u:E:")) != EOF) { 20976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 21076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cflag++; 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman debug++; 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'F': 22176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followvfork++; 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 22476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 22576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 22776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman iflag++; 22876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 22976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag++; 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rflag++; 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 23776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 23876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 23976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 24076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman dtime++; 24176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 24376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 24476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 24676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 24776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 24876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 2499c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 25076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 25217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 25317f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 25417f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 25576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 25676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 25776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 25876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 25976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 26076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 26276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 26376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 26576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 26676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 26776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 268de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if ((pid = atoi(optarg)) <= 0) { 26976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: Invalid process id: %s\n", 27076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, optarg); 27176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 27276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == getpid()) { 27454a4767f8609abfe2d7cb1802bc9e8dca97dd08fWichert Akkerman fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname); 27576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 27676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 27776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = alloctcb(pid)) == NULL) { 278de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath fprintf(stderr, "%s: out of memory\n", 27976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname); 28076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 28176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 28276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags |= TCB_ATTACHED; 28376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pflag_seen++; 28476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 28576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 28676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 28776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 28876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 28976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 29076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 29176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 29276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 29376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 294de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 295de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath if (putenv(optarg) < 0) { 296de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath fprintf(stderr, "%s: out of memory\n", 297de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath progname); 298de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath exit(1); 299de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath } 300de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 30176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 30276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 30376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 30476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 30676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 307ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath if (optind == argc && !pflag_seen) 308ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 309ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 31076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 31176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 31276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 31376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 31476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 31576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 31676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "%s: you must be root to use the -u option\n", 31776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname); 31876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 31976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((pent = getpwnam(username)) == NULL) { 32176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: cannot find user `%s'\n", 32276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, optarg); 32376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 32476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 32676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 32776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 32876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 32976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 33076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 33176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 33276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 33476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 33576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 33676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 33776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 33876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 33954b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman long f; 34054b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 34137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 34237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 34337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 34437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 34537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 34637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 34737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (followfork > 1) { 34837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath fprintf(stderr, "\ 34937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath%s: piping the output and -ff are mutually exclusive options\n", 35037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath progname); 35137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath exit(1); 35237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath } 35337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath 35437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if ((outf = popen(outfname + 1, "w")) == NULL) { 35537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath fprintf(stderr, "%s: can't popen '%s': %s\n", 35637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath progname, outfname + 1, 35737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath strerror(errno)); 35837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath exit(1); 35937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath } 36037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath } 36137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath else if ((outf = fopen(outfname, "w")) == NULL) { 36276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: can't fopen '%s': %s\n", 36376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, outfname, strerror(errno)); 36476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 36576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 36654b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 36754b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman if ((f=fcntl(fileno(outf), F_GETFD)) < 0 ) { 36854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman perror("failed to get flags for outputfile"); 36954b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman exit(1); 37054b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 37154b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman 37254b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman if (fcntl(fileno(outf), F_SETFD, f|FD_CLOEXEC) < 0 ) { 37354b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman perror("failed to set flags for outputfile"); 37454b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman exit(1); 37554b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 37676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 37776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 37876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 37976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 38076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 38176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 38237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (!outfname || outfname[0] == '|' || outfname[0] == '!') 38376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 38437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname && optind < argc) { 38576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interactive = 0; 38676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 387369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 38876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 389ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (c = 0; c < tcbtabsize; c++) { 390ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[c]; 39176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Reinitialize the output since it may have changed. */ 39276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; 39376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 39476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 395bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 39676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_open(tcp, 1) < 0) { 39776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "trouble opening proc file\n"); 39876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 39976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 40076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 401bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 40276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 40376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("attach: ptrace(PTRACE_ATTACH, ...)"); 40476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 40576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 40676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 407bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 40876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 40976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 41076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "Process %u attached - interrupt to quit\n", 41176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid); 41276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 41376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 414ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath if (!pflag_seen) { 41576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct stat statbuf; 41676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *filename; 41776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char pathname[MAXPATHLEN]; 41876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 41976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman filename = argv[optind]; 42076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strchr(filename, '/')) 42176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname, filename); 42276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef USE_DEBUGGING_EXEC 42376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 42476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Debuggers customarily check the current directory 42576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * first regardless of the path but doing that gives 42676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * security geeks a panic attack. 42776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 42876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (stat(filename, &statbuf) == 0) 42976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname, filename); 43076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* USE_DEBUGGING_EXEC */ 43176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 43276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char *path; 43376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int m, n, len; 43476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 43576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (path = getenv("PATH"); path && *path; path += m) { 43676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (strchr(path, ':')) { 43776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = strchr(path, ':') - path; 43876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman m = n + 1; 43976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 44076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 44176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman m = n = strlen(path); 44276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n == 0) { 44376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman getcwd(pathname, MAXPATHLEN); 44476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len = strlen(pathname); 44576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 44676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 44776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strncpy(pathname, path, n); 44876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman len = n; 44976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 45076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (len && pathname[len - 1] != '/') 45176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pathname[len++] = '/'; 45276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strcpy(pathname + len, filename); 453ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath if (stat(pathname, &statbuf) == 0 && 454ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath /* Accept only regular files 455ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath with some execute bits set. 456ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath XXX not perfect, might still fail */ 457ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath S_ISREG(statbuf.st_mode) && 458ed64516fa4f4ce25308a1f2ad3b84f8734c3e783Roland McGrath (statbuf.st_mode & 0111)) 45976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 46076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (stat(pathname, &statbuf) < 0) { 46376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "%s: %s: command not found\n", 46476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman progname, filename); 46576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 46676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 46776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (pid = fork()) { 46876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 46976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: fork"); 47076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 47176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 47276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 47376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: { 474bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 475bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (outf != stderr) close (fileno (outf)); 47676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 47776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Kludge for SGI, see proc_open for details. */ 47876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = foobar; 47976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 48076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 48176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 48276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* MIPS */ 483bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 48476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pause(); 485bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 486bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(getpid(), SIGSTOP); /* stop HERE */ 487553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 488bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 489553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (outf!=stderr) 4907987cdf192632516d6ba493b0a9943f5a3a7c362Wichert Akkerman close(fileno (outf)); 491bd4125c6bcd20e8f014b682b31d6fc5d0fef3ed0Wichert Akkerman 49276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 49376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: ptrace(PTRACE_TRACEME, ...)"); 49476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 49576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 49676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 49776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(getpid(), SIGSTOP); 49876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 49976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL || geteuid() == 0) { 50076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman uid_t run_euid = run_uid; 50176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gid_t run_egid = run_gid; 50276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 50376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (statbuf.st_mode & S_ISUID) 50476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_euid = statbuf.st_uid; 50576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (statbuf.st_mode & S_ISGID) 50676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_egid = statbuf.st_gid; 50776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 50876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 50976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * It is important to set groups before we 51076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * lose privileges on setuid. 51176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 5125ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (username != NULL) { 5135ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (initgroups(username, run_gid) < 0) { 5145ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("initgroups"); 5155ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5165ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 5175ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (setregid(run_gid, run_egid) < 0) { 5185ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("setregid"); 5195ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5205ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 5215ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman if (setreuid(run_uid, run_euid) < 0) { 5225ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman perror("setreuid"); 5235ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman exit(1); 5245ae21ead9f83597452f9a0517e8a51fa4823f921Wichert Akkerman } 52576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 52776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 52876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(run_uid, run_uid); 529bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 53076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 53176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman execv(pathname, &argv[optind]); 53276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: exec"); 53376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(1); 53476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 53576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 53676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 53776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = alloctcb(pid)) == NULL) { 53876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "tcb table full\n"); 53976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 54076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 54176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 542bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 54376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_open(tcp, 0) < 0) { 54476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "trouble opening proc file\n"); 54576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 54676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 54776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 548bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 549bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 55076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fake_execve(tcp, pathname, &argv[optind], environ); 551bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 55276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 55376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 55576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 55676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 55776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 55876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 55976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 56076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 56176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTOU, &sa, NULL); 56276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTTIN, &sa, NULL); 56376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) { 56476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGHUP); 56576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGINT); 56676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGQUIT); 56776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGPIPE); 56876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGTERM); 56976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interrupt; 57076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 57176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* POSIX signals on sunos4.1 are a little broken. */ 57276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = SA_INTERRUPT; 57376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 57476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 57576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 57676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 57776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 57876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 57976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 580bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 58176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = reaper; 58276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGCHLD, &sa, NULL); 583553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 584553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 585553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 586553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 587553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 588553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 589553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 590553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 591bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 59276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace() < 0) 59476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 59576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 59676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 59776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 59876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 59976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 60076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermannewoutf(tcp) 60176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 60276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 60376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char name[MAXPATHLEN]; 60476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman FILE *fp; 60576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 60676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname && followfork > 1) { 60776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(name, "%s.%u", outfname, tcp->pid); 60876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 60976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 61076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 61176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fp = fopen(name, "w"); 61276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef SVR4 61376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setreuid(geteuid(), getuid()); 61476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 61576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (fp == NULL) { 61676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("fopen"); 61776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 61876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 61976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = fp; 62076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 62176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 62276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 62376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 62476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 62576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanalloctcb(pid) 62676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 62776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 62876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 62976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 63076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 631ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 632ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 63376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 63476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 63576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->parent = NULL; 63676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->nchildren = 0; 6370962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath tcp->nzombies = 0; 638e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 639e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->nclone_threads = tcp->nclone_detached = 0; 640e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->nclone_waiting = 0; 641e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 64276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags = TCB_INUSE | TCB_STARTUP; 64376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 64476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime.tv_sec = 0; 64576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime.tv_usec = 0; 64676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 64776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 64876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 64976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 65176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 65276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 65376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 654bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 65576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint 65676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_open(tcp, attaching) 65776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 65876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint attaching; 65976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 66076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char proc[32]; 66176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman long arg; 662bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef SVR4 66319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes int i; 66419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes sysset_t syscalls; 66576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t signals; 66676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fltset_t faults; 667bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif 66876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 66976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last_pfd; 67076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 67176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 672ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 6739ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman /* Open the process pseudo-files in /proc. */ 6749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/ctl", tcp->pid); 6759ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 6769ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 6779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6799ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 6809ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 6819ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6829ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6839ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 6849ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 6859ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6869ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 6889ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 6899ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 6909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6919ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6929ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd_stat, F_GETFD)) < 0) { 6939ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 6949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6959ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 6969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd_stat, F_SETFD, arg|FD_CLOEXEC) < 0) { 6979ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 6989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 6999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman sprintf(proc, "/proc/%d/as", tcp->pid); 7019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 7029ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 7039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd_as, F_GETFD)) < 0) { 7069ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 7079ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7089ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd_as, F_SETFD, arg|FD_CLOEXEC) < 0) { 7109ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 7119ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#else 71476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Open the process pseudo-file in /proc. */ 715bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 71676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(proc, "/proc/%d", tcp->pid); 71776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->pfd = open(proc, O_RDWR|O_EXCL)) < 0) { 718bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 719bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/mem", tcp->pid); 720bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd = open(proc, O_RDWR)) < 0) { 721bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 72276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: open(\"/proc/...\", ...)"); 72376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 72476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7259ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if ((arg = fcntl(tcp->pfd, F_GETFD)) < 0) { 7269ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_GETFD"); 7279ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7289ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7299ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (fcntl(tcp->pfd, F_SETFD, arg|FD_CLOEXEC) < 0) { 7309ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman perror("F_SETFD"); 7319ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return -1; 7329ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 7339ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 734bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 735bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/regs", tcp->pid); 736bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 737bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../regs\", ...)"); 738bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 739bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 740bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (cflag) { 741bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 742bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 743bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("strace: open(\"/proc/.../status\", ...)"); 744bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 745bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 746bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 747bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 748bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 74976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman rebuild_pollv(); 75076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 75176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 75276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Wait for the child to pause. Because of a race 75376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * condition we have to poll for the event. 75476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 75576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 7569ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL_STATUS (tcp) < 0) { 75776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTATUS"); 75876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 75976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 7609ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) 761bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman break; 76276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 76376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 764bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 76576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Stop the process so that we own the stop. */ 76616a03d2e97415afe6cf34172a0aea97a95a0b160Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 76776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: PIOCSTOP"); 76876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 76976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 770553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 77176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef PIOCSET 77276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set Run-on-Last-Close. */ 77376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_RLC; 7749ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 77576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSET PR_RLC"); 77676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 77776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 77876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set or Reset Inherit-on-Fork. */ 77976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman arg = PR_FORK; 7809ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 78176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{SET,RESET} PR_FORK"); 78276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 78376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 78476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !PIOCSET */ 785553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 78676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 78776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSRLC"); 78876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 78976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 79076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 79176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOC{S,R}FORK"); 79276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 79376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 794bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 795bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 796bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 797bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCGFL"); 798bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 799bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 800bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg &= ~PF_LINGER; 801bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 802bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCSFL"); 803bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 804bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 805bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 80676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !PIOCSET */ 807bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 80819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable all syscall entries we care about. */ 80919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&syscalls); 81019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 81119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof syscalls) * CHAR_BIT) break; 81219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i); 81319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 81419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_execve); 81519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (followfork) { 81619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_fork); 81719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_forkall 81819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_forkall); 81919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 820553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef SYS_fork1 82119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_fork1); 82219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 82319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rfork1 82419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_rfork1); 82519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 82619e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#ifdef SYS_rforkall 82719e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes praddset (&syscalls, SYS_rforkall); 82819e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes#endif 82919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 83019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 83176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSENTRY"); 83276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 83376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable the syscall exits. */ 83519e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 83676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOSEXIT"); 83776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 83876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 83919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable signals we care about. */ 84019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&signals); 84119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 84219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof signals) * CHAR_BIT) break; 84319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i); 84419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 8459ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 84676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSTRACE"); 84776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 84876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 84919e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes /* Enable faults we care about */ 85019e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes premptyset(&faults); 85119e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes for (i = 1; i < MAX_QUALS; ++i) { 85219e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (i > (sizeof faults) * CHAR_BIT) break; 85319e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i); 85419e49984acc8f12dfaf0b7835ad17ca24f854c47John Hughes } 8559ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 85676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCSFAULT"); 85776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 85876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 859bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 860bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* set events flags. */ 861bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman arg = S_SIG | S_SCE | S_SCX ; 862bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 863bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman perror("PIOCBIS"); 864bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman return -1; 865bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 866bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 86776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!attaching) { 86876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef MIPS 86976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 87076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The SGI PRSABORT doesn't work for pause() so 87176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * we send it a caught signal to wake it up. 87276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 87376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGINT); 87476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !MIPS */ 875553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifdef PRSABORT 87676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* The child is in a pause(), abort it. */ 8779ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = PRSABORT; 8789ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 87976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 88076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 88176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 882553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 883bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !MIPS*/ 884bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 885bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* wake up the child if it received the SIGSTOP */ 886bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 887553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 88876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 88976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Wait for the child to do something. */ 8909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL_WSTOP (tcp) < 0) { 89176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 89276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 89376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 8949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_WHY == PR_SYSENTRY) { 895bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->flags &= ~TCB_INSYSCALL; 896bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman get_scno(tcp); 897bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->scno == SYS_execve) 89876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 89976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 90076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Set it running: maybe execve will be next. */ 901bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 9029ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 9039ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 904bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 905bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 906553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 90776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 90876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 90976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 910bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 911bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* handle the case where we "opened" the child before 912bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman it did the kill -STOP */ 913bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->status.PR_WHY == PR_SIGNALLED && 914bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->status.PR_WHAT == SIGSTOP) 915bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman kill(tcp->pid, SIGCONT); 916553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 91776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 918bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 91976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 920bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 921bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else { 922553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath if (attaching < 2) { 9232e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* We are attaching to an already running process. 9242e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * Try to figure out the state of the process in syscalls, 9252e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * to handle the first event well. 9262e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * This is done by having a look at the "wchan" property of the 9272e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman * process, which tells where it is stopped (if it is). */ 9282e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman FILE * status; 9292e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman char wchan[20]; /* should be enough */ 930553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 9312e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman sprintf(proc, "/proc/%d/status", tcp->pid); 9322e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman status = fopen(proc, "r"); 9332e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status && 9342e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 9352e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman "%*d,%*d %*d,%*d %19s", wchan) == 1) && 9362e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 9372e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman strcmp(wchan, "stopevent")) { 9382e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* The process is asleep in the middle of a syscall. 9392e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman Fake the syscall entry event */ 9402e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 9412e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 9422e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman trace_syscall(tcp); 9432e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 9442e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if (status) 9452e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman fclose(status); 9462e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } /* otherwise it's a fork being followed */ 947bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 948bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 94976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 95076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) 95176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 95276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1) { 95376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poll_open(); 95476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(last_pfd); 95576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman proc_poller(tcp->pfd); 95676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 95776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last_pfd = tcp->pfd; 95876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 95976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 96076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 96176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 962bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 96376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 964e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstruct tcb * 96576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanpid2tcb(pid) 96676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pid; 96776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 96876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 96976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 97076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 971ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 972ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 97376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid && tcp->pid != pid) 97476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 97576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 97676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 97776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 97876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 97976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 98076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 981bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 98276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 98376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic struct tcb * 98476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanpfd2tcb(pfd) 98576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pfd; 98676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 98776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 98876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 989ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = 0; i < tcbtabsize; i++) { 990ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 99176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != pfd) 99276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 99376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_INUSE) 99476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 99576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 99676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 99776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 99876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 999bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 100076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 100176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 100276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandroptcb(tcp) 100376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 100476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 100576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 100676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 1007e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 1008e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->nclone_threads > 0) { 1009e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* There are other threads left in this process, but this 1010e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath is the one whose PID represents the whole process. 1011e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath We need to keep this record around as a zombie until 1012e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath all the threads die. */ 1013e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->flags |= TCB_EXITING; 1014e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return; 1015e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1016e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 101776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 101876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = 0; 1019eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1020e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->parent != NULL) { 1021e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nchildren--; 1022e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath#ifdef TCB_CLONE_THREAD 1023e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->flags & TCB_CLONE_DETACHED) 1024e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nclone_detached--; 1025e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath if (tcp->flags & TCB_CLONE_THREAD) 1026e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent->nclone_threads--; 1027e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath#endif 10280962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath#ifdef TCB_CLONE_DETACHED 10290962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath if (!(tcp->flags & TCB_CLONE_DETACHED)) 10300962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath#endif 10310962345a5775e0eea75c3ec408fb4807e851e7f0Roland McGrath tcp->parent->nzombies++; 1032e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->parent = NULL; 1033e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath } 1034e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath 1035e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath tcp->flags = 0; 103676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pfd != -1) { 103776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(tcp->pfd); 103876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pfd = -1; 1039bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1040bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_reg != -1) { 1041bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_reg); 1042bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_reg = -1; 1043bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1044bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (tcp->pfd_status != -1) { 1045bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman close(tcp->pfd_status); 1046bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman tcp->pfd_status = -1; 1047bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } 1048553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* !FREEBSD */ 1049bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 1050e29341c02f4fb658a34bca1f36c5d587257970d6Roland McGrath rebuild_pollv(); /* Note, flags needs to be cleared by now. */ 105176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 105276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1053eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 1054822f0c9a84a4c992cc126766c83726e7275a5572Wichert Akkerman if (outfname && followfork > 1 && tcp->outf) 105576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fclose(tcp->outf); 1056eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 105776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = 0; 105876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 105976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1060bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 106176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 106376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanresume(tcp) 106476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 106576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 106676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp == NULL) 106776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 106876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 106976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_SUSPENDED)) { 107076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid); 107176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 107276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 107376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 1074e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 1075e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_CLONE_THREAD) 1076e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->parent->nclone_waiting--; 1077e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 107876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 107976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, tcp->pid, (char *) 1, 0) < 0) { 108076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("resume: ptrace(PTRACE_SYSCALL, ...)"); 108176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 108276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 108376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 108476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 108576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u resumed\n", tcp->pid); 108676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 108776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 108876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1089bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 109076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* detach traced process; continue with sig */ 109276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 109376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 109476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermandetach(tcp, sig) 109576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 109676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 109776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 109876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int error = 0; 1099ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#ifdef LINUX 1100e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath int status, resumed; 1101ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath#endif 110276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 110476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = SIGKILL; 110576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 110676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 110776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 110876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 11097bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 11107bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 111176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 11127bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 11137bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 11147bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 11157bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 111676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 111776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* On a clear day, you can see forever. */ 11187bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11197bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (errno != ESRCH) { 11207bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath /* Shouldn't happen. */ 11217bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: ptrace(PTRACE_DETACH, ...)"); 11227bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11237bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (kill(tcp->pid, 0) < 0) { 11247bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 11257bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: checking sanity"); 11267bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11277bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else if (kill(tcp->pid, SIGSTOP) < 0) { 11287bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath if (errno != ESRCH) 11297bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath perror("detach: stopping child"); 11307bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 11317bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath else { 113276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 11337508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 11347508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 11357508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 11367508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11377508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 113876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 11397508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11407508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11417508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 11427508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 11437508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 11447508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 11457508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 11467508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11477508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11487508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 11497508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 11507508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (wait4(tcp->pid, &status, __WCLONE, 11517508cb4678141d146d819120f6b5b428c103882eRoland McGrath NULL) < 0) { 11527508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 11537508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 11547508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 11557508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11567508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 11577508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 11587508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 115976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11607508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 116176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 116276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 116376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 116476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 116576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 116676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, 11677bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath tcp->pid, (char *) 1, sig)) < 0) { 116876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno != ESRCH) 116976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 117076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* I died trying. */ 117176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 117276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 117376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 117476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1, 11757bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath WSTOPSIG(status) == SIGTRAP ? 11767bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath 0 : WSTOPSIG(status))) < 0) { 117776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno != ESRCH) 117876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_CONT, ...)"); 117976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 118076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 118176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 118276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 11837bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif /* LINUX */ 118476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 118576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if defined(SUNOS4) 118676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 118776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig && kill(tcp->pid, sig) < 0) 118876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: kill"); 118976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sig = 0; 119076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) < 0) 119176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: ptrace(PTRACE_DETACH, ...)"); 119276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 119376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1194bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef USE_PROCFS 1195e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath resumed = 0; 1196e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1197e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* XXX This won't always be quite right (but it never was). 1198e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath A waiter with argument 0 or < -1 is waiting for any pid in 1199e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath a particular pgrp, which this child might or might not be 1200e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in. The waiter will only wake up if it's argument is -1 1201e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath or if it's waiting for tcp->pid's pgrp. It makes a 1202e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath difference to wake up a waiter when there might be more 1203e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath traced children, because it could get a false ECHILD 1204e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error. OTOH, if this was the last child in the pgrp, then 1205e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath it ought to wake up and get ECHILD. We would have to 1206e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath search the system for all pid's in the pgrp to be sure. 1207e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1208e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && (t->waitpid == -1 || 1209e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (t->waitpid == 0 && getpgid (tcp->pid) == getpgid (t->pid)) 1210e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath || (t->waitpid < 0 && t->waitpid == -getpid (t->pid))) 1211e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath */ 1212e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1213e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->parent && 1214e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (tcp->parent->flags & TCB_SUSPENDED) && 1215e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) { 1216e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error = resume(tcp->parent); 1217e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ++resumed; 1218e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1219e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_CLONE_THREAD 1220e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->parent && tcp->parent->nclone_waiting > 0) { 1221e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Some other threads of our parent are waiting too. */ 1222e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath unsigned int i; 1223e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1224e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Resume all the threads that were waiting for this PID. */ 1225e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1226e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1227e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t->parent == tcp->parent && t != tcp 1228e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && ((t->flags & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1229e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1230e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->waitpid == tcp->pid) { 1231e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error |= resume (t); 1232e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ++resumed; 1233e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1234e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1235e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (resumed == 0) 1236e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Noone was waiting for this PID in particular, 1237e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath so now we might need to resume some wildcarders. */ 1238e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1239e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1240e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t->parent == tcp->parent && t != tcp 1241e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && ((t->flags 1242e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1243e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1244e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->waitpid <= 0 1245e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ) { 1246e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath error |= resume (t); 1247e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath break; 1248e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1249e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1250e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1251e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 1252e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1253bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 125976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1262bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanreaper(sig) 126676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 127176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 127476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pid2tcb(pid); 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp) 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 127876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1282bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* USE_PROCFS */ 128376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermancleanup() 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1290ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1291ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (!outfname || followfork < 2 || tcp_last == tcp)) { 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" <unfinished ...>\n"); 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGTERM); 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 131076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 131176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermaninterrupt(sig) 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman interrupted = 1; 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13226d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 13256d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 132676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstrerror(errno) 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint errno; 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (errno < 1 || errno >= sys_nerr) { 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown error %d", errno); 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_errlist[errno]; 133876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 133976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 134276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 134376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 13448f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 13456d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 13478f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 13488f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 13498f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 135076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstrsignal(sig) 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static char buf[64]; 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 135876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 135976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 136076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 136176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 136276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1370bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef USE_PROCFS 137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanrebuild_pollv() 137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1377ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv != NULL) 1378ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath free (pollv); 1379c012d223a6b915f06ef32b8aaa52b984015d192eRoland McGrath pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]); 1380ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath if (pollv == NULL) { 1381ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath fprintf(stderr, "strace: out of memory for poll vector\n"); 1382ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath exit(1); 1383ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath } 1384ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 1385ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath for (i = j = 0; i < tcbtabsize; i++) { 1386ca16be8be9521b61bd2c5d945aa115519ebcb4daRoland McGrath struct tcb *tcp = tcbtab[i]; 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 138976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[j].fd = tcp->pfd; 13909ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollv[j].events = POLLWANT; 139176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j++; 139276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 139376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (j != nprocs) { 139476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 139576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 139676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 139876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 140276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poll_open() 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 140476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int arg; 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pipe(proc_poll_pipe) < 0) { 140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("pipe"); 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < 2; i++) { 141276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((arg = fcntl(proc_poll_pipe[i], F_GETFD)) < 0) { 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_GETFD"); 141476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 141576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (fcntl(proc_poll_pipe[i], F_SETFD, arg|FD_CLOEXEC) < 0) { 141776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("F_SETFD"); 141876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 141976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 142076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 142176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 142376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 142476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poll(pollv, nfds, timeout) 142576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct pollfd *pollv; 142676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint nfds; 142776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint timeout; 142876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 142976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 143076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 143176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 143276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 143476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return n; 143576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (n != sizeof(struct proc_pollfd)) { 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "panic: short read: %d\n", n); 143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 143876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[i].fd == pollinfo.fd) 144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = pollinfo.revents; 144276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 144376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollv[i].revents = 0; 144476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman poller_pid = pollinfo.pid; 144676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 1; 144776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 144876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 144976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanwakeup_handler(sig) 145176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint sig; 145276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 145376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 145476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 145576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 145676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanproc_poller(pfd) 145776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint pfd; 145876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 145976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct proc_pollfd pollinfo; 146076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 146176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigset_t blocked_set, empty_set; 146276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 146376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int n; 146476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rlimit rl; 1465bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1466bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman struct procfs_status pfs; 1467bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 146876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 146976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (fork()) { 147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case -1: 147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("fork"); 147276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 0: 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 147676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 147776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 147876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 147976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 148076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 148176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 148276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGHUP, &sa, NULL); 148376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGINT, &sa, NULL); 148476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGQUIT, &sa, NULL); 148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGPIPE, &sa, NULL); 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGTERM, &sa, NULL); 148776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = wakeup_handler; 148876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaction(SIGUSR1, &sa, NULL); 148976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 149076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigaddset(&blocked_set, SIGUSR1); 149176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 149276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 149376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 149476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 149576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("getrlimit(RLIMIT_NOFILE, ...)"); 149676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 149776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 149876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman n = rl.rlim_cur; 149976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < n; i++) { 150076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (i != pfd && i != proc_poll_pipe[1]) 150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman close(i); 150276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 150376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 150476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.fd = pfd; 150576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.pid = getpid(); 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 1507bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 1508bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 1509bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1510bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 1511bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* FREEBSD */ 15129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman { 151376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (errno) { 151476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 151576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 151676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLERR; 151876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 152076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pollinfo.revents = POLLHUP; 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 152276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 152376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("proc_poller: PIOCWSTOP"); 152476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 152676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman _exit(0); 152776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15289ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman pollinfo.revents = POLLWANT; 152976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigsuspend(&empty_set); 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 153376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchoose_pfd() 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i, j; 154076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 154176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static int last; 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 154476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (followfork < 2 && 15459ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman last < nprocs && (pollv[last].revents & POLLWANT)) { 154676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * The previous process is ready to run again. We'll 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * let it do so if it is currently in a syscall. This 154976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * heuristic improves the readability of the trace. 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[last].fd); 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp && (tcp->flags & TCB_INSYSCALL)) 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[last].fd; 155476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (i = 0; i < nprocs; i++) { 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Let competing children run round robin. */ 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman j = (i + last + 1) % nprocs; 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pollv[j].revents & (POLLHUP | POLLERR)) { 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pfd2tcb(pollv[j].fd); 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) { 156276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: lost proc\n"); 156376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 156676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 156776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 15689ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (pollv[j].revents & POLLWANT) { 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman last = j; 157076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return pollv[j].fd; 157176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: nothing ready\n"); 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 157576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantrace() 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 15809dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 1581d870b3c31a0139b335a66a829169bacc74624c44John Hughes struct tcb *in_syscall = NULL; 15829dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 158476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pfd; 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int what; 158676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int ioctl_result = 0, ioctl_errno = 0; 15879ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman long arg; 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 158976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 159176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 159276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 159576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (nprocs) { 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 1: 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 159976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] == -1) { 160076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp = pid2tcb(0); 160276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!tcp) 160376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 160476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = tcp->pfd; 160576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 160676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 160976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 161076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* fall through ... */ 161176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 161276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 161376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_POLLABLE_PROCFS 16149dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 16159dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman /* On some systems (e.g. UnixWare) we get too much ugly 16169dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman "unfinished..." stuff when multiple proceses are in 16179dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman syscalls. Here's a nasty hack */ 1618553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 16199dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (in_syscall) { 16209dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman struct pollfd pv; 16219dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman tcp = in_syscall; 16229dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = NULL; 16239dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.fd = tcp->pfd; 16249dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman pv.events = POLLWANT; 16259dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if ((what = poll (&pv, 1, 1)) < 0) { 16269dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman if (interrupted) 16279dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman return 0; 16289dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman continue; 16299dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16309dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman else if (what == 1 && pv.revents & POLLWANT) { 16319dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman goto FOUND; 16329dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16339dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman } 16349dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 16359dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman 163676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (poll(pollv, nprocs, INFTIM) < 0) { 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 164076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else /* !HAVE_POLLABLE_PROCFS */ 164276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll(pollv, nprocs, INFTIM) < 0) { 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 164476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 164576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 164676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 164776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 164876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pfd = choose_pfd(); 164976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pfd == -1) 165076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 165176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 165276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 165376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 165476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pfd' in our table. */ 165576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pfd2tcb(pfd)) == NULL) { 165676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "unknown pfd: %u\n", pfd); 165776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 165876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1659b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#ifdef POLL_HACK 16609dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman FOUND: 1661b664308560d655bc1fb333663eb0d0fb3395409fJohn Hughes#endif 166276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Get the status of the process. */ 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!interrupted) { 1664bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 16659ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ioctl_result = IOCTL_WSTOP (tcp); 1666bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* FREEBSD */ 1667bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman /* Thanks to some scheduling mystery, the first poller 1668bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sometimes waits for the already processed end of fork 1669bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman event. Doing a non blocking poll here solves the problem. */ 1670bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (proc_poll_pipe[0] != -1) 1671bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman ioctl_result = IOCTL_STATUS (tcp); 1672bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman else 1673bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman ioctl_result = IOCTL_WSTOP (tcp); 1674553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif /* FREEBSD */ 167576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ioctl_errno = errno; 167676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_POLLABLE_PROCFS 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (proc_poll_pipe[0] != -1) { 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) 167976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGKILL); 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(poller_pid, SIGUSR1); 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !HAVE_POLLABLE_PROCFS */ 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 168576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 169076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ioctl_result < 0) { 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Find out what happened if it failed. */ 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (ioctl_errno) { 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EBADF: 169676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1697bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1698bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case ENOTTY: 1699553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ENOENT: 170176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCWSTOP"); 170576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17092e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman#ifdef FREEBSD 17102e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 17112e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman /* discard first event for a syscall we never entered */ 17122e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman IOCTL (tcp->pfd, PIOCRUN, 0); 17132e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman continue; 17142e4ffe59b588159eb80e236f068278ba47735932Wichert Akkerman } 1715553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 1716553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* clear the just started flag */ 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval stime; 1725bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1726bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman char buf[1024]; 1727bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman int len; 1728bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman 1729bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 1730bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman buf[len] = '\0'; 1731bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman sscanf(buf, 1732bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 1733bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman &stime.tv_sec, &stime.tv_usec); 1734bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman } else 1735bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman stime.tv_sec = stime.tv_usec = 0; 1736553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else /* !FREEBSD */ 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_sec = tcp->status.pr_stime.tv_sec; 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 1739bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &stime, &tcp->stime); 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = stime; 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17439ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman what = tcp->status.PR_WHAT; 17449ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman switch (tcp->status.PR_WHY) { 1745bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifndef FREEBSD 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_REQUESTED: 17479ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (tcp->status.PR_FLAGS & PR_ASLEEP) { 17489ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman tcp->status.PR_WHY = PR_SYSENTRY; 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 175176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1755bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !FREEBSD */ 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSENTRY: 17579dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#ifdef POLL_HACK 17589dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman in_syscall = tcp; 17599dbf15466e9c178ac4090eba2c1232e2fe0706f9Wichert Akkerman#endif 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SYSEXIT: 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "syscall trouble\n"); 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_SIGNALLED: 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_SIGNAL)) { 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("--- %s (%s) ---", 1770ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(what), strsignal(what)); 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 17725826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#ifdef PR_INFO 17735826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes if (tcp->status.PR_INFO.si_signo == what) { 17745826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printleader(tcp); 17755826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes tprintf(" siginfo="); 17765826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printsiginfo(&tcp->status.PR_INFO, 1); 17775826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes printtrailer(tcp); 17785826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes } 17795826589d8e210c2d34c8ce496d5b7a0f54188ef0John Hughes#endif 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case PR_FAULTED: 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag && (qual_flags[what] & QUAL_FAULT)) { 178476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 178576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("=== FAULT %d ===", what); 178676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 178776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1789bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#ifdef FREEBSD 1790bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman case 0: /* handle case we polled for nothing */ 1791bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman continue; 1792553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 179376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 17949ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY); 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 179676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman arg = 0; 1799553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#ifndef FREEBSD 18009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 1801553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#else 1802bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) { 1803553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath#endif 180476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("PIOCRUN"); 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 180676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1811bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#else /* !USE_PROCFS */ 181276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1813e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 1814e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath/* Handle an exit detach or death signal that is taking all the 1815e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath related clone threads with it. This is called in three circumstances: 1816e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == -1 TCP has already died (TCB_ATTACHED is clear, strace is parent). 1817e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == 0 Continuing TCP will perform an exit_group syscall. 1818e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath SIG == other Continuing TCP with SIG will kill the process. 1819e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath*/ 1820e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathstatic int 1821e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathhandle_group_exit(struct tcb *tcp, int sig) 1822e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath{ 1823e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* We need to locate our records of all the clone threads 1824e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath related to TCP, either its children or siblings. */ 1825e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *leader = ((tcp->flags & TCB_CLONE_THREAD) 1826e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ? tcp->parent 1827e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath : tcp->nclone_detached > 0 1828e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ? tcp : NULL); 1829e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1830e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (sig < 0) { 1831e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) 1832e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, 1833e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath "PANIC: handle_group_exit: %d leader %d\n", 1834e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->pid, leader ? leader->pid : -1); 1835e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(tcp); /* Already died. */ 1836e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1837e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else { 1838e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_ATTACHED) { 1839e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) { 1840e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* We need to detach the leader so that the 1841e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath process death will be reported to its real 1842e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent. But we kill it first to prevent 1843e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath it doing anything before we kill the whole 1844e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath process in a moment. We can use 1845e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath PTRACE_KILL on a thread that's not already 1846e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath stopped. Then the value we pass in 1847e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath PTRACE_DETACH just sets the death 1848e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath signal reported to the real parent. */ 1849e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_KILL, leader->pid, 0, 0); 1850e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (debug) 1851e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, 1852e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath " [%d exit %d kills %d]\n", 1853e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->pid, sig, leader->pid); 1854e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath detach(leader, sig); 1855e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1856e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath detach(tcp, sig); 1857e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1858e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else if (ptrace(PTRACE_CONT, tcp->pid, (char *) 1, sig) < 0) { 1859e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath perror("strace: ptrace(PTRACE_CONT, ...)"); 1860e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath cleanup(); 1861e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return -1; 1862e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1863e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else { 1864e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL && leader != tcp) 1865e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(tcp); 1866e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* The leader will report to us as parent now, 1867e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath and then we'll get to the SIG==-1 case. */ 1868e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1869e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1870e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1871e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1872e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* Note that TCP and LEADER are no longer valid, 1873e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath but we can still compare against them. */ 1874e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (leader != NULL) { 1875e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath unsigned int i; 1876e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1877e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath struct tcb *t = tcbtab[i]; 1878e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (t != tcp && (t->flags & TCB_CLONE_DETACHED) 1879e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath && t->parent == leader) 1880e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath droptcb(t); 1881e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1882e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1883e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 1884e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1885e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath} 1886e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 1887e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath 188876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 188976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantrace() 189076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 189176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int pid; 189276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int wait_errno; 189376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int status; 189476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 189576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 189676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 18972f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#ifdef __WALL 18982f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman static int wait4_options = __WALL; 18992f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#endif 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 190276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while (nprocs != 0) { 190376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 190476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_SETMASK, &empty_set, NULL); 190576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 19062f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#ifdef __WALL 19072f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL); 19085bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 19092f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 19102f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 19112f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman errno = 0; 19122f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, wait4_options, 19132f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman cflag ? &ru : NULL); 19142f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19155bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 19162f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 19172f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman pid = wait4(-1, &status, __WCLONE, 19182f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman cflag ? &ru : NULL); 19192f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman if (pid == -1) { 19202f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman fprintf(stderr, "strace: clone wait4 " 19212f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman "failed: %s\n", strerror(errno)); 19222f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19232f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 19242f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#else 192576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait4(-1, &status, 0, cflag ? &ru : NULL); 19262f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman#endif /* __WALL */ 192776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* LINUX */ 192876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 192976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid = wait(&status); 193076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 193176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 193276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interactive) 193376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigprocmask(SIG_BLOCK, &blocked_set, NULL); 193476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (interrupted) 193676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (pid == -1) { 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (wait_errno) { 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case EINTR: 194176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 194276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case ECHILD: 194376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 194476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 194576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 194676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 194776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 194876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#if 0 195076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (nprocs == 0) 195176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 195276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "strace: proc miscount\n"); 195376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(1); 195476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 195576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman errno = wait_errno; 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: wait"); 195976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 196276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 196376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, " [wait(%#x) = %u]\n", status, pid); 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Look up `pid' in our table. */ 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp = pid2tcb(pid)) == NULL) { 1967e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef LINUX 1968e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (followfork || followvfork) { 1969e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 1970e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 1971e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 1972e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 1973e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 1974e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 1975e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 1976e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 1977e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 1978e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if ((tcp = alloctcb(pid)) == NULL) { 1979e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, " [tcb table full]\n"); 1980e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath kill(pid, SIGKILL); /* XXX */ 1981e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return 0; 1982e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 1983e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED; 1984e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath newoutf(tcp); 1985e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 1986e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, "\ 1987e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrathProcess %d attached (waiting for parent)\n", 1988e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 19898b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1990e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 1991e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 1992e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 19938b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman#endif 1994e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 1995e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath fprintf(stderr, "unknown pid: %u\n", pid); 1996e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 1997e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath ptrace(PTRACE_CONT, pid, (char *) 1, 0); 1998e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath exit(1); 1999e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* set current output file */ 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = tcp->outf; 200376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) { 200476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef LINUX 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 200776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* !LINUX */ 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Apparently, doing any ptrace() call on a stopped 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process, provokes the kernel to report the process 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * status again on a subsequent wait(), even if the 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * process has not been actually restarted. 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Since we have inspected the arguments of suspended 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * processes we end up here testing for this case. 201876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 202576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("+++ killed by %s +++", 2026ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(WTERMSIG(status))); 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2029e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2030e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, -1); 2031e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 2033e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 203576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 203776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 203876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u exited\n", pid); 203976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 204076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 204176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "PANIC: attached pid %u exited\n", 204276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid); 20430a396906981a03f93c07cb912585d0679dd50899Roland McGrath if (tcp == tcp_last) { 20440a396906981a03f93c07cb912585d0679dd50899Roland McGrath if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) 20450a396906981a03f93c07cb912585d0679dd50899Roland McGrath == TCB_INSYSCALL) 20460a396906981a03f93c07cb912585d0679dd50899Roland McGrath tprintf(" <unfinished ... exit status %d>\n", 20470a396906981a03f93c07cb912585d0679dd50899Roland McGrath WEXITSTATUS(status)); 20480a396906981a03f93c07cb912585d0679dd50899Roland McGrath tcp_last = NULL; 20490a396906981a03f93c07cb912585d0679dd50899Roland McGrath } 2050e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2051e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, -1); 2052e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 205376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 2054e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 205576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 205676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 205776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 205876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 206176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 206276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (debug) 206376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "pid %u stopped, [%s]\n", 2064ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons pid, signame(WSTOPSIG(status))); 206576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_STARTUP) { 206776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 206876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * This flag is there to keep us in sync. 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Next time this process stops it should 207076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * really be entering a system call. 207176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 207376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) { 207476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 207576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Interestingly, the process may stop 207676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * with STOPSIG equal to some other signal 207776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * than SIGSTOP if we happend to attach 207876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * just before the process takes a signal. 207976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "pid %u not stopped\n", pid); 208376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 208476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 208576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef SUNOS4 208976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* A child of us stopped at exec */ 209076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGTRAP && followvfork) 209176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fixvfork(tcp); 209276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* SUNOS4 */ 209376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 209476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) { 209576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (clearbpt(tcp) < 0) /* Pretty fatal */ { 209676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 209776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 209876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman goto tracing; 210276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 210476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) != SIGTRAP) { 210576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP && 210676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (tcp->flags & TCB_SIGTRAPPED)) { 210776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 210876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Trapped attempt to block SIGTRAP 210976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Hope we are back in control now. 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 211176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 211276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, 211376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman pid, (char *) 1, 0) < 0) { 211476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 211576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 211676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 211776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 211876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 211976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 212076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!cflag 212176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 21227b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long addr = 0, pc = 0; 21237b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#ifdef PT_GETSIGINFO 21247b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# define PSR_RI 41 21257b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman struct siginfo si; 21267b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman unsigned long psr; 21277b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 21287b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman upeek(pid, PT_CR_IPSR, &psr); 21297b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman upeek(pid, PT_CR_IIP, &pc); 21307b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 21317b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 21327b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman ptrace(PT_GETSIGINFO, pid, 0, (long) &si); 21337b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman addr = (unsigned long) si.si_addr; 21347b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 213576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 21367b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman tprintf("--- %s (%s) @ %lx (%lx) ---", 2137ce780fc9e6067b15b65ca2904c698c77503bf635Nate Sammons signame(WSTOPSIG(status)), 21387b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman strsignal(WSTOPSIG(status)), pc, addr); 213976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printtrailer(tcp); 214076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 214176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_ATTACHED) && 214276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman !sigishandled(tcp, WSTOPSIG(status))) { 2143e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2144e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath handle_group_exit(tcp, WSTOPSIG(status)); 2145e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#else 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, WSTOPSIG(status)); 2147e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 214876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 215176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman WSTOPSIG(status)) < 0) { 215276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_SUSPENDED; 215776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 215876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (trace_syscall(tcp) < 0) { 216076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 216176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 216276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 216376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman ptrace(PTRACE_KILL, 216476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid, (char *) 1, SIGTERM); 216576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 216676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 216776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 216876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 216976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_EXITING) { 2170e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#ifdef TCB_GROUP_EXITING 2171e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (tcp->flags & TCB_GROUP_EXITING) { 2172e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (handle_group_exit(tcp, 0) < 0) 2173e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath return -1; 2174e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath continue; 2175e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 2176e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath#endif 217776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_ATTACHED) 217876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman detach(tcp, 0); 217976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (ptrace(PTRACE_CONT, pid, (char *) 1, 0) < 0) { 218076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("strace: ptrace(PTRACE_CONT, ...)"); 218176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 218276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 218376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 218576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_SUSPENDED) { 218776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!qflag) 218876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u suspended\n", pid); 218976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 219076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 219176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tracing: 219276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) { 219376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("trace: ptrace(PTRACE_SYSCALL, ...)"); 219476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 219576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 219676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 219776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 219876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 219976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 220076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2201bf79f2e16b090ffe59cd1e1820935680a2da7b78Wichert Akkerman#endif /* !USE_PROCFS */ 220276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 220376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int curcol; 220476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 220576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 220676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <stdarg.h> 220776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a, b) 220876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 220976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <varargs.h> 221076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#define VA_START(a, b) va_start(a) 221176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 221276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 221376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 221476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef __STDC__ 221576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(const char *fmt, ...) 221676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 221776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantprintf(fmt, va_alist) 221876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanchar *fmt; 221976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanva_dcl 222076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 222176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 222276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_list args; 222376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 222476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman VA_START(args, fmt); 2225b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (outf) { 2226b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath int n = vfprintf(outf, fmt, args); 2227b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath if (n < 0 && outf != stderr) 2228b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath perror(outfname == NULL 2229b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath ? "<writing to pipe>" : outfname); 2230b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath else 2231b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath curcol += n; 2232b310a0c26b3b31d52aa4b25549e06113284bd5bbRoland McGrath } 223376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman va_end(args); 223476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 223576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 223676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 223776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprintleader(tcp) 223976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 224176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp_last && (!outfname || followfork < 2 || tcp_last == tcp)) { 224276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last->flags |= TCB_REPRINT; 224376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf(" <unfinished ...>\n"); 224476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 224576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman curcol = 0; 224676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((followfork == 1 || pflag_seen > 1) && outfname) 224776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%-5d ", tcp->pid); 224876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (nprocs > 1 && !outfname) 224976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("[pid %5u] ", tcp->pid); 225076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag) { 225176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman char str[sizeof("HH:MM:SS")]; 225276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct timeval tv, dtv; 225376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman static struct timeval otv; 225476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 225576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman gettimeofday(&tv, NULL); 225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (rflag) { 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (otv.tv_sec == 0) 225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&dtv, &tv, &otv); 226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%6ld.%06ld ", 226176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) dtv.tv_sec, (long) dtv.tv_usec); 226276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman otv = tv; 226376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else if (tflag > 2) { 226576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%ld.%06ld ", 226676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman (long) tv.tv_sec, (long) tv.tv_usec); 226776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman time_t local = tv.tv_sec; 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman strftime(str, sizeof(str), "%T", localtime(&local)); 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tflag > 1) 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s.%06ld ", str, (long) tv.tv_usec); 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%s ", str); 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (iflag) 227876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printcall(tcp); 227976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 228076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 228176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermantabto(col) 228376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanint col; 228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 228576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (curcol < col) 228676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("%*s", col - curcol, ""); 228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 228876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 228976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanprinttrailer(tcp) 229176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb *tcp; 229276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 229376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tprintf("\n"); 229476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp_last = NULL; 229576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 22969ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 2297ea78f0f77185f7d6d0b2055805139d96e1be816cWichert Akkerman#ifdef HAVE_MP_PROCFS 22989ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 22999ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkermanint mp_ioctl (int fd, int cmd, void *arg, int size) { 23009ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 23019ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman struct iovec iov[2]; 23029ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman int n = 1; 2303553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 23049ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_base = &cmd; 23059ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[0].iov_len = sizeof cmd; 23069ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman if (arg) { 23079ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman ++n; 23089ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_base = arg; 23099ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman iov[1].iov_len = size; 23109ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman } 2311553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath 23129ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman return writev (fd, iov, n); 23139ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman} 23149ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman 23159ce1a63eb20b069607c06f9645ac5a17b418a5f3Wichert Akkerman#endif 2316