134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project/* 234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * All rights reserved. 734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Redistribution and use in source and binary forms, with or without 934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * modification, are permitted provided that the following conditions 1034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * are met: 1134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 1234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * notice, this list of conditions and the following disclaimer. 1334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 1434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 1534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * documentation and/or other materials provided with the distribution. 1634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 3. The name of the author may not be used to endorse or promote products 1734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * derived from this software without specific prior written permission. 1834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 1934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * 30f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * $Id$ 3134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 3234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 3334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include "defs.h" 3434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 3534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/types.h> 3634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <signal.h> 3734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <errno.h> 3834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/param.h> 3934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <fcntl.h> 4034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/resource.h> 41f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef HAVE_ANDROID_OS 42f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#define wait4 __wait4 4334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/wait.h> 44f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 4534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/stat.h> 4634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <pwd.h> 4734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <grp.h> 4834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <string.h> 4934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <limits.h> 5034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <dirent.h> 5134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 52f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 53f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# include <asm/unistd.h> 54f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# if defined __NR_tgkill 55f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define my_tgkill(pid, tid, sig) syscall (__NR_tgkill, (pid), (tid), (sig)) 56f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# elif defined __NR_tkill 57f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define my_tgkill(pid, tid, sig) syscall (__NR_tkill, (tid), (sig)) 58f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# else 59f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* kill() may choose arbitrarily the target task of the process group 60f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown while we later wait on a that specific TID. PID process waits become 61f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown TID task specific waits for a process under ptrace(2). */ 62f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 63f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define my_tgkill(pid, tid, sig) kill ((tid), (sig)) 64f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# endif 65f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 66f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 6734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if defined(IA64) && defined(LINUX) 6834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project# include <asm/ptrace_offsets.h> 6934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 7034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 7134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 7234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <poll.h> 7334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 7434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 7534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SVR4 7634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/stropts.h> 7734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_MP_PROCFS 7834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_SYS_UIO_H 7934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <sys/uio.h> 8034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 8134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 8234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 83f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownextern char **environ; 84f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownextern int optind; 85f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownextern char *optarg; 8634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 8734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 88f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownint debug = 0, followfork = 0; 89f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownunsigned int ptrace_setoptions = 0; 90f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownint dtime = 0, xflag = 0, qflag = 0; 91f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Browncflag_t cflag = CFLAG_NONE; 92f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0; 93f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* 94f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * daemonized_tracer supports -D option. 95f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * With this option, strace forks twice. 96f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Unlike normal case, with -D *grandparent* process exec's, 97f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * becoming a traced process. Child exits (this prevents traced process 98f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * from having children it doesn't expect to have), and grandchild 99f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * attaches to grandparent similarly to strace -p PID. 100f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * This allows for more transparent interaction in cases 101f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * when process and its parent are communicating via signals, 102f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * wait() etc. Without -D, strace process gets lodged in between, 103f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * disrupting parent<->child link. 104f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 105f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic bool daemonized_tracer = 0; 10634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 10734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project/* Sometimes we want to print only succeeding syscalls. */ 10834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint not_failing_only = 0; 10934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 110f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int exit_code = 0; 111f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int strace_child = 0; 112f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 113f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic char *username = NULL; 11434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectuid_t run_uid; 11534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectgid_t run_gid; 11634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 11734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint acolumn = DEFAULT_ACOLUMN; 11834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint max_strlen = DEFAULT_STRLEN; 119f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic char *outfname = NULL; 12034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source ProjectFILE *outf; 121f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int curcol; 12234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb **tcbtab; 12334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectunsigned int nprocs, tcbtabsize; 124f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownconst char *progname; 12534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectextern char **environ; 12634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 127f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int detach(struct tcb *tcp, int sig); 128f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int trace(void); 129f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void cleanup(void); 130f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void interrupt(int sig); 13134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic sigset_t empty_set, blocked_set; 13234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 13334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_SIG_ATOMIC_T 13434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic volatile sig_atomic_t interrupted; 13534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !HAVE_SIG_ATOMIC_T */ 13634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic volatile int interrupted; 13734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_SIG_ATOMIC_T */ 13834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 13934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 14034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 141f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic struct tcb *pfd2tcb(int pfd); 142f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void reaper(int sig); 143f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void rebuild_pollv(void); 14434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic struct pollfd *pollv; 14534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 14634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 14734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 148f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void proc_poll_open(void); 149f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void proc_poller(int pfd); 15034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 15134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct proc_pollfd { 15234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int fd; 15334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int revents; 15434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int pid; 15534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project}; 15634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 15734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int poller_pid; 15834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int proc_poll_pipe[2] = { -1, -1 }; 15934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 16034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 16134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 16234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_MP_PROCFS 16334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#define POLLWANT POLLWRNORM 16434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 16534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#define POLLWANT POLLPRI 16634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 16734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* USE_PROCFS */ 16834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 16934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 17034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectusage(ofp, exitval) 17134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source ProjectFILE *ofp; 17234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint exitval; 17334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 17434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(ofp, "\ 175f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownusage: strace [-CdDffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ 17634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project [-p pid] ... [-s strsize] [-u username] [-E var=val] ...\n\ 17734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project [command [arg ...]]\n\ 178f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown or: strace -c [-D] [-e expr] ... [-O overhead] [-S sortby] [-E var=val] ...\n\ 17934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project [command [arg ...]]\n\ 18034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-c -- count time, calls, and errors for each syscall and report summary\n\ 181f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown-C -- like -c but also print regular output while processes are running\n\ 18234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-f -- follow forks, -ff -- with output into separate files\n\ 18334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-F -- attempt to follow vforks, -h -- print help message\n\ 18434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-i -- print instruction pointer at time of syscall\n\ 18534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-q -- suppress messages about attaching, detaching, etc.\n\ 18634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 18734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-T -- print time spent in each syscall, -V -- print version\n\ 18834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-v -- verbose mode: print unabbreviated argv, stat, termio[s], etc. args\n\ 18934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 19034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 19134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 19234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project options: trace, abbrev, verbose, raw, signal, read, or write\n\ 19334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-o file -- send trace output to FILE instead of stderr\n\ 19434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 19534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-p pid -- trace process with process id PID, may be repeated\n\ 196f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown-D -- run tracer process as a detached grandchild, not as parent\n\ 19734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 19834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 19934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-u username -- run command as username handling setuid and/or setgid\n\ 20034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-E var=val -- put var=val in the environment for command\n\ 20134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-E var -- remove var from the environment for command\n\ 20234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project" /* this is broken, so don't document it 20334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project-z -- print only succeeding syscalls\n\ 20434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 20534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 20634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(exitval); 20734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 20834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 20934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SVR4 21034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef MIPS 21134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 21234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectfoobar() 21334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 21434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 21534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* MIPS */ 21634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* SVR4 */ 21734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 218f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* Glue for systems without a MMU that cannot provide fork() */ 219f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef HAVE_FORK 220f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define strace_vforked 0 221f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else 222f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define strace_vforked 1 223f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define fork() vfork() 224f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 225f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 226f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int 227f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownset_cloexec_flag(int fd) 228f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 229f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int flags, newflags; 230f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 231f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((flags = fcntl(fd, F_GETFD, 0)) < 0) 232f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 233f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: fcntl F_GETFD: %s\n", 234f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 235f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 236f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 237f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 238f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown newflags = flags | FD_CLOEXEC; 239f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (flags == newflags) 240f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 241f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 242f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (fcntl(fd, F_SETFD, newflags) < 0) 243f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 244f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: fcntl F_SETFD: %s\n", 245f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 246f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 247f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 248f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 249f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 250f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 251f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 252f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* 253f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * When strace is setuid executable, we have to swap uids 254f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * before and after filesystem and process management operations. 255f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 256f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void 257f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownswap_uid(void) 258f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 259f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef SVR4 260f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int euid = geteuid(), uid = getuid(); 261f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 262f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (euid != uid && setreuid(euid, uid) < 0) 263f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 264f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: setreuid: %s\n", 265f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 266f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 267f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 268f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 269f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 270f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 271f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#if _LFS64_LARGEFILE 272f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define fopen_for_output fopen64 273f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else 274f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define fopen_for_output fopen 275f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 276f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 277f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic FILE * 278f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstrace_fopen(const char *path, const char *mode) 279f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 280f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown FILE *fp; 281f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 282f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 283f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((fp = fopen_for_output(path, mode)) == NULL) 284f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: can't fopen '%s': %s\n", 285f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, path, strerror(errno)); 286f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 287f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (fp && set_cloexec_flag(fileno(fp)) < 0) 288f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 289f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fclose(fp); 290f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fp = NULL; 291f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 292f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return fp; 293f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 294f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 295f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int popen_pid = -1; 296f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 297f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef _PATH_BSHELL 298f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define _PATH_BSHELL "/bin/sh" 299f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 300f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 301f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* 302f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * We cannot use standard popen(3) here because we have to distinguish 303f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * popen child process from other processes we trace, and standard popen(3) 304f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * does not export its child's pid. 305f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 306f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic FILE * 307f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstrace_popen(const char *command) 308f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 309f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int fds[2]; 310f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 311f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 312f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pipe(fds) < 0) 313f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 314f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: pipe: %s\n", 315f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 316f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 317f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return NULL; 318f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 319f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 320f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(fds[1]) < 0) 321f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 322f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[0]); 323f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[1]); 324f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 325f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return NULL; 326f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 327f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 328f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((popen_pid = fork()) == -1) 329f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 330f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: fork: %s\n", 331f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 332f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[0]); 333f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[1]); 334f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 335f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return NULL; 336f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 337f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 338f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (popen_pid) 339f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 340f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* parent */ 341f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[0]); 342f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown swap_uid(); 343f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return fdopen(fds[1], "w"); 344f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else 345f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 346f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* child */ 347f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fds[1]); 348f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (fds[0] && (dup2(fds[0], 0) || close(fds[0]))) 349f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 350f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: dup2: %s\n", 351f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, strerror(errno)); 352f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 353f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 354f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown execl(_PATH_BSHELL, "sh", "-c", command, NULL); 355f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: execl: %s: %s\n", 356f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, _PATH_BSHELL, strerror(errno)); 357f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 358f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 359f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 360f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 361f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int 362f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownnewoutf(struct tcb *tcp) 363f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 364f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (outfname && followfork > 1) { 365f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown char name[520 + sizeof(int) * 3]; 366f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown FILE *fp; 367f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 368f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sprintf(name, "%.512s.%u", outfname, tcp->pid); 369f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((fp = strace_fopen(name, "w")) == NULL) 370f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 371f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->outf = fp; 372f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 373f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 374f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 375f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 376f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void 377f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstartup_attach(void) 378f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 379f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int tcbi; 380f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *tcp; 381f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 382f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 383f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Block user interruptions as we would leave the traced 384f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * process stopped (process state T) if we would terminate in 385f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * between PTRACE_ATTACH and wait4 () on SIGSTOP. 386f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * We rely on cleanup () from this point on. 387f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 388f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interactive) 389f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigprocmask(SIG_BLOCK, &blocked_set, NULL); 390f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 391f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (daemonized_tracer) { 392f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pid_t pid = fork(); 393f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid < 0) { 394f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 395f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 396f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid) { /* parent */ 397f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 398f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Wait for child to attach to straced process 399f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * (our parent). Child SIGKILLs us after it attached. 400f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Parent's wait() is unblocked by our death, 401f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * it proceeds to exec the straced program. 402f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 403f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pause(); 404f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(0); /* paranoia */ 405f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 406f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 407f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 408f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 409f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = tcbtab[tcbi]; 410f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!(tcp->flags & TCB_INUSE) || !(tcp->flags & TCB_ATTACHED)) 411f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 412f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 413f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->flags & TCB_CLONE_THREAD) 414f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 415f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 416f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Reinitialize the output since it may have changed. */ 417f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->outf = outf; 418f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (newoutf(tcp) < 0) 419f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 420f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 421f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef USE_PROCFS 422f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (proc_open(tcp, 1) < 0) { 423f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "trouble opening proc file\n"); 424f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(tcp); 425f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 426f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 427f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else /* !USE_PROCFS */ 428f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# ifdef LINUX 429f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (followfork && !daemonized_tracer) { 430f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 431f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown DIR *dir; 432f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 433f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sprintf(procdir, "/proc/%d/task", tcp->pid); 434f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown dir = opendir(procdir); 435f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (dir != NULL) { 436f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown unsigned int ntid = 0, nerr = 0; 437f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct dirent *de; 438f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int tid; 439f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown while ((de = readdir(dir)) != NULL) { 440f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (de->d_fileno == 0) 441f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 442f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tid = atoi(de->d_name); 443f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tid <= 0) 444f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 445f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ++ntid; 446f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_ATTACH, tid, (char *) 1, 0) < 0) 447f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ++nerr; 448f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (tid != tcbtab[tcbi]->pid) { 449f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = alloctcb(tid); 450f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->flags |= TCB_ATTACHED|TCB_CLONE_THREAD|TCB_FOLLOWFORK; 451f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcbtab[tcbi]->nchildren++; 452f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcbtab[tcbi]->nclone_threads++; 453f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->parent = tcbtab[tcbi]; 454f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 455f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interactive) { 456f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigprocmask(SIG_SETMASK, &empty_set, NULL); 457f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interrupted) 458f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return; 459f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigprocmask(SIG_BLOCK, &blocked_set, NULL); 460f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 461f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 462f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown closedir(dir); 463f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ntid -= nerr; 464f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ntid == 0) { 465f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("attach: ptrace(PTRACE_ATTACH, ...)"); 466f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(tcp); 467f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 468f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 469f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!qflag) { 470f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, ntid > 1 471f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown? "Process %u attached with %u threads - interrupt to quit\n" 472f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown: "Process %u attached - interrupt to quit\n", 473f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcbtab[tcbi]->pid, ntid); 474f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 475f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 476f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } /* if (opendir worked) */ 477f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } /* if (-f) */ 478f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# endif 479f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_ATTACH, tcp->pid, (char *) 1, 0) < 0) { 480f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("attach: ptrace(PTRACE_ATTACH, ...)"); 481f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(tcp); 482f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 483f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 484f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* INTERRUPTED is going to be checked at the top of TRACE. */ 485f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 486f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (daemonized_tracer) { 487f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 488f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * It is our grandparent we trace, not a -p PID. 489f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Don't want to just detach on exit, so... 490f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 491f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->flags &= ~TCB_ATTACHED; 492f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 493f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Make parent go away. 494f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Also makes grandparent's wait() unblock. 495f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 496f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(getppid(), SIGKILL); 497f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 498f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 499f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* !USE_PROCFS */ 500f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!qflag) 501f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, 502f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "Process %u attached - interrupt to quit\n", 503f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->pid); 504f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 505f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 506f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interactive) 507f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigprocmask(SIG_SETMASK, &empty_set, NULL); 508f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 509f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 510f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void 511f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstartup_child (char **argv) 512f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 513f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct stat statbuf; 514f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *filename; 515f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown char pathname[MAXPATHLEN]; 516f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int pid = 0; 517f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *tcp; 518f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 519f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown filename = argv[0]; 520f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (strchr(filename, '/')) { 521f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (strlen(filename) > sizeof pathname - 1) { 522f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown errno = ENAMETOOLONG; 523f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("strace: exec"); 524f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 525f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 526f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strcpy(pathname, filename); 527f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 528f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef USE_DEBUGGING_EXEC 529f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 530f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Debuggers customarily check the current directory 531f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * first regardless of the path but doing that gives 532f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * security geeks a panic attack. 533f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 534f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (stat(filename, &statbuf) == 0) 535f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strcpy(pathname, filename); 536f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* USE_DEBUGGING_EXEC */ 537f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else { 538f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const char *path; 539f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int m, n, len; 540f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 541f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (path = getenv("PATH"); path && *path; path += m) { 542f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (strchr(path, ':')) { 543f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown n = strchr(path, ':') - path; 544f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown m = n + 1; 545f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 546f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else 547f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown m = n = strlen(path); 548f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (n == 0) { 549f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!getcwd(pathname, MAXPATHLEN)) 550f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 551f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown len = strlen(pathname); 552f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 553f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (n > sizeof pathname - 1) 554f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 555f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else { 556f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strncpy(pathname, path, n); 557f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown len = n; 558f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 559f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (len && pathname[len - 1] != '/') 560f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pathname[len++] = '/'; 561f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strcpy(pathname + len, filename); 562f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (stat(pathname, &statbuf) == 0 && 563f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Accept only regular files 564f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown with some execute bits set. 565f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown XXX not perfect, might still fail */ 566f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown S_ISREG(statbuf.st_mode) && 567f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (statbuf.st_mode & 0111)) 568f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 569f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 570f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 571f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (stat(pathname, &statbuf) < 0) { 572f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: %s: command not found\n", 573f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, filename); 574f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 575f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 576f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strace_child = pid = fork(); 577f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid < 0) { 578f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("strace: fork"); 579f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 580f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 581f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 582f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((pid != 0 && daemonized_tracer) /* parent: to become a traced process */ 583f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown || (pid == 0 && !daemonized_tracer) /* child: to become a traced process */ 584f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ) { 585f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pid = getpid(); 586f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef USE_PROCFS 587f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (outf != stderr) close (fileno (outf)); 588f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef MIPS 589f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Kludge for SGI, see proc_open for details. */ 590f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sa.sa_handler = foobar; 591f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sa.sa_flags = 0; 592f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigemptyset(&sa.sa_mask); 593f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigaction(SIGINT, &sa, NULL); 594f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* MIPS */ 595f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef FREEBSD 596f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pause(); 597f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else /* FREEBSD */ 598f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(pid, SIGSTOP); /* stop HERE */ 599f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* FREEBSD */ 600f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else /* !USE_PROCFS */ 601f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (outf!=stderr) 602f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown close(fileno (outf)); 603f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 604f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!daemonized_tracer) { 605f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_TRACEME, 0, (char *) 1, 0) < 0) { 606f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("strace: ptrace(PTRACE_TRACEME, ...)"); 607f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 608f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 609f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (debug) 610f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(pid, SIGSTOP); 611f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 612f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 613f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (username != NULL || geteuid() == 0) { 614f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown uid_t run_euid = run_uid; 615f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown gid_t run_egid = run_gid; 616f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 617f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (statbuf.st_mode & S_ISUID) 618f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown run_euid = statbuf.st_uid; 619f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (statbuf.st_mode & S_ISGID) 620f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown run_egid = statbuf.st_gid; 621f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 622f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 623f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * It is important to set groups before we 624f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * lose privileges on setuid. 625f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 626f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (username != NULL) { 627f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (initgroups(username, run_gid) < 0) { 628f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("initgroups"); 629f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 630f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 631f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (setregid(run_gid, run_egid) < 0) { 632f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("setregid"); 633f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 634f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 635f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (setreuid(run_uid, run_euid) < 0) { 636f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("setreuid"); 637f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 638f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 639f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 640f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 641f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else 642f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown setreuid(run_uid, run_uid); 643f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 644f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!daemonized_tracer) { 645f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 646f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Induce an immediate stop so that the parent 647f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * will resume us with PTRACE_SYSCALL and display 648f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * this execve call normally. 649f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Unless of course we're on a no-MMU system where 650f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * we vfork()-ed, so we cannot stop the child. 651f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 652f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!strace_vforked) 653f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(getpid(), SIGSTOP); 654f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else { 655f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct sigaction sv_sigchld; 656f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigaction(SIGCHLD, NULL, &sv_sigchld); 657f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 658f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Make sure it is not SIG_IGN, otherwise wait 659f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * will not block. 660f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 661f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown signal(SIGCHLD, SIG_DFL); 662f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 663f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Wait for grandchild to attach to us. 664f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * It kills child after that, and wait() unblocks. 665f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 666f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown alarm(3); 667f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown wait(NULL); 668f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown alarm(0); 669f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown sigaction(SIGCHLD, &sv_sigchld, NULL); 670f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 671f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* !USE_PROCFS */ 672f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 673f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown execv(pathname, argv); 674f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("strace: exec"); 675f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 676f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 677f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 678f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* We are the tracer. */ 679f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = alloctcb(daemonized_tracer ? getppid() : pid); 680f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (daemonized_tracer) { 681f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* We want subsequent startup_attach() to attach to it. */ 682f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->flags |= TCB_ATTACHED; 683f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 684f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef USE_PROCFS 685f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (proc_open(tcp, 0) < 0) { 686f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "trouble opening proc file\n"); 687f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 688f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 689f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 690f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif /* USE_PROCFS */ 691f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 692f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 693f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 694f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* 695f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 696f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 697f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * and then see which options are supported by the kernel. 698f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 699f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int 700f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Browntest_ptrace_setoptions(void) 701f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 702f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int pid, expected_grandchild = 0, found_grandchild = 0; 703f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown const unsigned int test_options = PTRACE_O_TRACECLONE | 704f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PTRACE_O_TRACEFORK | 705f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PTRACE_O_TRACEVFORK; 706f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 707f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((pid = fork()) < 0) 708f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 709f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (pid == 0) { 710f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0) 711f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 712f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(getpid(), SIGSTOP); 713f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(fork() < 0); 714f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 715f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 716f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown while (1) { 717f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int status, tracee_pid; 718f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 719f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tracee_pid = wait(&status); 720f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tracee_pid == -1) { 721f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (errno == EINTR) 722f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 723f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (errno == ECHILD) 724f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 725f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("test_ptrace_setoptions"); 726f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 727f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 728f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tracee_pid != pid) { 729f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown found_grandchild = tracee_pid; 730f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 && 731f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown errno != ESRCH) 732f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(tracee_pid, SIGKILL); 733f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 734f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (WIFSTOPPED(status)) { 735f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown switch (WSTOPSIG(status)) { 736f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case SIGSTOP: 737f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_SETOPTIONS, pid, 738f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown NULL, test_options) < 0) { 739f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(pid, SIGKILL); 740f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 741f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 742f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 743f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case SIGTRAP: 744f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (status >> 16 == PTRACE_EVENT_FORK) { 745f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown long msg = 0; 746f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 747f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_GETEVENTMSG, pid, 748f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown NULL, (long) &msg) == 0) 749f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown expected_grandchild = msg; 750f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 751f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 752f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 753f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 && 754f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown errno != ESRCH) 755f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown kill(pid, SIGKILL); 756f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 757f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 758f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (expected_grandchild && expected_grandchild == found_grandchild) 759f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ptrace_setoptions |= test_options; 760f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 761f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 762f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 763f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 76434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint 765f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownmain(int argc, char *argv[]) 76634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 76734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 76834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int c, pid = 0; 769f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int optF = 0; 77034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct sigaction sa; 77134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 77234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static char buf[BUFSIZ]; 77334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 774f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname = argv[0] ? argv[0] : "strace"; 775f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 77634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Allocate the initial tcbtab. */ 77734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcbtabsize = argc; /* Surely enough for all -p args. */ 778f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcbtab = calloc(tcbtabsize, sizeof tcbtab[0])) == NULL) { 779f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: out of memory\n", progname); 780f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 781f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 782f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcbtab[0] = calloc(tcbtabsize, sizeof tcbtab[0][0])) == NULL) { 783f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: out of memory\n", progname); 784f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 785f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 78634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (tcp = tcbtab[0]; tcp < &tcbtab[0][tcbtabsize]; ++tcp) 78734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcbtab[tcp - tcbtab[0]] = &tcbtab[0][tcp - tcbtab[0]]; 78834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 78934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project outf = stderr; 79034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project interactive = 1; 791f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown set_sortby(DEFAULT_SORTBY); 792f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown set_personality(DEFAULT_PERSONALITY); 79334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify("trace=all"); 79434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify("abbrev=all"); 79534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify("verbose=all"); 79634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify("signal=all"); 79734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project while ((c = getopt(argc, argv, 798f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "+cCdfFhiqrtTvVxz" 799f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef USE_PROCFS 800f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "D" 801f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 802f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "a:e:o:O:p:s:S:u:E:")) != EOF) { 80334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (c) { 80434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'c': 805f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag == CFLAG_BOTH) { 806f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: -c and -C are mutually exclusive options\n", 807f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 808f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 809f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 810f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cflag = CFLAG_ONLY_STATS; 811f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 812f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case 'C': 813f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag == CFLAG_ONLY_STATS) { 814f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: -c and -C are mutually exclusive options\n", 815f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 816f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 817f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 818f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cflag = CFLAG_BOTH; 81934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 82034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'd': 82134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project debug++; 82234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 823f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef USE_PROCFS 824f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case 'D': 825f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown daemonized_tracer = 1; 82634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 827f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 82834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'F': 829f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown optF = 1; 830f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 831f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown case 'f': 832f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown followfork++; 83334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 83434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'h': 83534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project usage(stdout, 0); 83634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 83734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'i': 83834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project iflag++; 83934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 84034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'q': 84134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qflag++; 84234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 84334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'r': 84434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project rflag++; 84534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tflag++; 84634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 84734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 't': 84834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tflag++; 84934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 85034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'T': 85134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project dtime++; 85234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 85334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'x': 85434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project xflag++; 85534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 85634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'v': 85734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify("abbrev=none"); 85834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 85934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'V': 86034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 86134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(0); 86234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 86334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'z': 86434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project not_failing_only = 1; 86534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 86634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'a': 86734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project acolumn = atoi(optarg); 86834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 86934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'e': 87034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qualify(optarg); 87134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 87234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'o': 87334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project outfname = strdup(optarg); 87434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 87534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'O': 87634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project set_overhead(atoi(optarg)); 87734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 87834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'p': 87934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((pid = atoi(optarg)) <= 0) { 88034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "%s: Invalid process id: %s\n", 88134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project progname, optarg); 88234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 88334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 88434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pid == getpid()) { 88534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "%s: I'm sorry, I can't let you do that, Dave.\n", progname); 88634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 88734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 888f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = alloc_tcb(pid, 0); 88934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags |= TCB_ATTACHED; 89034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pflag_seen++; 89134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 89234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 's': 89334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project max_strlen = atoi(optarg); 89434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (max_strlen < 0) { 89534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, 89634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "%s: invalid -s argument: %s\n", 89734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project progname, optarg); 89834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 89934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 90034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 90134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'S': 90234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project set_sortby(optarg); 90334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 90434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'u': 90534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project username = strdup(optarg); 90634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 90734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 'E': 90834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (putenv(optarg) < 0) { 90934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "%s: out of memory\n", 91034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project progname); 91134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 91234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 91334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 91434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 91534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project usage(stderr, 1); 91634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 91734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 91834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 91934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 920f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((optind == argc) == !pflag_seen) 92134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project usage(stderr, 1); 92234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 923f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pflag_seen && daemonized_tracer) { 924f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, 925f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "%s: -D and -p are mutually exclusive options\n", 926f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 927f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 928f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 929f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 930f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!followfork) 931f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown followfork = optF; 932f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 933f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (followfork > 1 && cflag) { 934f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, 935f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "%s: (-c or -C) and -ff are mutually exclusive options\n", 936f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 937f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 938f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 939f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 94034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* See if they want to run as another user. */ 94134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (username != NULL) { 94234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct passwd *pent; 94334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 94434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (getuid() != 0 || geteuid() != 0) { 94534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, 94634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "%s: you must be root to use the -u option\n", 94734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project progname); 94834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 94934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 95034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((pent = getpwnam(username)) == NULL) { 95134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "%s: cannot find user `%s'\n", 952f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname, username); 95334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 95434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 95534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project run_uid = pent->pw_uid; 95634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project run_gid = pent->pw_gid; 95734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 95834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else { 95934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project run_uid = getuid(); 96034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project run_gid = getgid(); 96134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 96234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 963f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 964f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (followfork) { 965f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (test_ptrace_setoptions() < 0) { 966f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, 967f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "Test for options supported by PTRACE_SETOPTIONS " 968f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "failed, giving up using this feature.\n"); 969f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ptrace_setoptions = 0; 970f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 971f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (debug) 972f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "ptrace_setoptions = %#x\n", 973f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ptrace_setoptions); 974f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 97534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 97634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 97734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Check if they want to redirect the output. */ 97834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (outfname) { 97934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* See if they want to pipe the output. */ 98034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (outfname[0] == '|' || outfname[0] == '!') { 98134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 98234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * We can't do the <outfname>.PID funny business 98334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * when using popen, so prohibit it. 98434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 98534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (followfork > 1) { 98634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "\ 98734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project%s: piping the output and -ff are mutually exclusive options\n", 98834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project progname); 98934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 99034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 99134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 992f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((outf = strace_popen(outfname + 1)) == NULL) 99334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 99434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 995f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (followfork <= 1 && 996f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (outf = strace_fopen(outfname, "w")) == NULL) 99734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 99834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 99934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 100034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!outfname || outfname[0] == '|' || outfname[0] == '!') 100134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project setvbuf(outf, buf, _IOLBF, BUFSIZ); 100234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (outfname && optind < argc) { 100334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project interactive = 0; 100434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project qflag = 1; 100534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 100634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1007f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Valid states here: 1008f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown optind < argc pflag_seen outfname interactive 1009f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1 0 0 1 1010f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 0 1 0 1 1011f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1 0 1 0 1012f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 0 1 1 1 1013f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 101434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1015f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* STARTUP_CHILD must be called before the signal handlers get 1016f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown installed below as they are inherited into the spawned process. 1017f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Also we do not need to be protected by them as during interruption 1018f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown in the STARTUP_CHILD mode we kill the spawned process anyway. */ 1019f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (!pflag_seen) 1020f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown startup_child(&argv[optind]); 102134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 102234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&empty_set); 102334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&blocked_set); 102434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = SIG_IGN; 102534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&sa.sa_mask); 102634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_flags = 0; 102734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGTTOU, &sa, NULL); 102834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGTTIN, &sa, NULL); 102934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interactive) { 103034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGHUP); 103134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGINT); 103234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGQUIT); 103334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGPIPE); 103434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGTERM); 103534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = interrupt; 103634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SUNOS4 103734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* POSIX signals on sunos4.1 are a little broken. */ 103834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_flags = SA_INTERRUPT; 103934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* SUNOS4 */ 104034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 104134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGHUP, &sa, NULL); 104234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGINT, &sa, NULL); 104334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGQUIT, &sa, NULL); 104434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGPIPE, &sa, NULL); 104534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGTERM, &sa, NULL); 104634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 104734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = reaper; 104834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGCHLD, &sa, NULL); 104934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 105034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Make sure SIGCHLD has the default action so that waitpid 105134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project definitely works without losing track of children. The user 105234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project should not have given us a bogus state to inherit, but he might 105334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project have. Arguably we should detect SIG_IGN here and pass it on 105434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project to children, but probably noone really needs that. */ 105534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = SIG_DFL; 105634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGCHLD, &sa, NULL); 105734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* USE_PROCFS */ 105834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1059f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pflag_seen || daemonized_tracer) 1060f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown startup_attach(); 1061f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 106234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (trace() < 0) 106334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 106434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 1065f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fflush(NULL); 1066f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (exit_code > 0xff) { 1067f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Child was killed by a signal, mimic that. */ 1068f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit_code &= 0xff; 1069f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown signal(exit_code, SIG_DFL); 1070f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown raise(exit_code); 1071f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Paranoia - what if this signal is not fatal? 1072f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Exit with 128 + signo then. */ 1073f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit_code += 128; 1074f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1075f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(exit_code); 107634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 107734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 107834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 1079f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownexpand_tcbtab(void) 108034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 108134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Allocate some more TCBs and expand the table. 108234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project We don't want to relocate the TCBs because our 108334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project callers have pointers and it would be a pain. 108434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project So tcbtab is a table of pointers. Since we never 108534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project free the TCBs, we allocate a single chunk of many. */ 108634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb **newtab = (struct tcb **) 108734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]); 108834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize, 108934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sizeof *newtcbs); 109034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 109134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (newtab == NULL || newtcbs == NULL) { 1092f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: expand_tcbtab: out of memory\n", 1093f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 1094f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 1095f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 109634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 109734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = tcbtabsize; i < 2 * tcbtabsize; ++i) 109834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project newtab[i] = &newtcbs[i - tcbtabsize]; 109934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcbtabsize *= 2; 110034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcbtab = newtab; 110134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 110234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 110334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb * 1104f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownalloc_tcb(int pid, int command_options_parsed) 110534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 110634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 110734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 110834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1109f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (nprocs == tcbtabsize) 1110f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown expand_tcbtab(); 1111f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 111234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < tcbtabsize; i++) { 111334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp = tcbtab[i]; 111434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->flags & TCB_INUSE) == 0) { 111534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pid = pid; 111634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->parent = NULL; 111734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->nchildren = 0; 111834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->nzombies = 0; 111934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_CLONE_THREAD 1120f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->nclone_threads = 0; 112134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->nclone_waiting = 0; 112234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 112334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags = TCB_INUSE | TCB_STARTUP; 112434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->outf = outf; /* Initialise to current out file */ 1125f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->curcol = 0; 112634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->stime.tv_sec = 0; 112734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->stime.tv_usec = 0; 112834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pfd = -1; 112934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project nprocs++; 1130f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (command_options_parsed) 1131f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown newoutf(tcp); 113234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return tcp; 113334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 113434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1135f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "%s: bug in alloc_tcb\n", progname); 1136f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 1137f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 113834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 113934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 114034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 114134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint 1142f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownproc_open(struct tcb *tcp, int attaching) 114334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 114434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project char proc[32]; 114534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project long arg; 114634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SVR4 114734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 114834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sysset_t syscalls; 114934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigset_t signals; 115034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fltset_t faults; 115134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 115234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 115334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static int last_pfd; 115434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 115534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 115634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_MP_PROCFS 115734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Open the process pseudo-files in /proc. */ 115834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/ctl", tcp->pid); 115934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->pfd = open(proc, O_WRONLY|O_EXCL)) < 0) { 116034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/...\", ...)"); 116134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 116234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1163f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(tcp->pfd) < 0) { 116434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 116534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 116634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/status", tcp->pid); 116734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->pfd_stat = open(proc, O_RDONLY|O_EXCL)) < 0) { 116834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/...\", ...)"); 116934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 117034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1171f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(tcp->pfd_stat) < 0) { 117234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 117334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 117434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/as", tcp->pid); 117534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->pfd_as = open(proc, O_RDONLY|O_EXCL)) < 0) { 117634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/...\", ...)"); 117734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 117834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1179f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(tcp->pfd_as) < 0) { 118034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 118134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 118234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 118334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Open the process pseudo-file in /proc. */ 118434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 118534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d", tcp->pid); 1186f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->pfd = open(proc, O_RDWR|O_EXCL); 118734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 118834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/mem", tcp->pid); 1189f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->pfd = open(proc, O_RDWR); 119034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 1191f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->pfd < 0) { 119234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/...\", ...)"); 119334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 119434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1195f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(tcp->pfd) < 0) { 119634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 119734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 119834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 119934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 120034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/regs", tcp->pid); 120134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->pfd_reg = open(proc, O_RDONLY)) < 0) { 120234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/.../regs\", ...)"); 120334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 120434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 120534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (cflag) { 120634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/status", tcp->pid); 120734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->pfd_status = open(proc, O_RDONLY)) < 0) { 120834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: open(\"/proc/.../status\", ...)"); 120934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 121034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 121134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } else 121234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pfd_status = -1; 121334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 121434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project rebuild_pollv(); 121534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!attaching) { 121634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 121734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Wait for the child to pause. Because of a race 121834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * condition we have to poll for the event. 121934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 122034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (;;) { 122134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL_STATUS (tcp) < 0) { 122234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: PIOCSTATUS"); 122334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 122434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 122534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->status.PR_FLAGS & PR_ASLEEP) 122634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 122734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 122834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 122934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 123034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Stop the process so that we own the stop. */ 123134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSTOP, (char *)NULL) < 0) { 123234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: PIOCSTOP"); 123334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 123434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 123534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 123634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef PIOCSET 123734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Set Run-on-Last-Close. */ 123834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = PR_RLC; 123934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSET, &arg) < 0) { 124034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCSET PR_RLC"); 124134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 124234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 124334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Set or Reset Inherit-on-Fork. */ 124434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = PR_FORK; 124534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, followfork ? PIOCSET : PIOCRESET, &arg) < 0) { 124634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOC{SET,RESET} PR_FORK"); 124734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 124834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 124934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !PIOCSET */ 125034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 125134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl(tcp->pfd, PIOCSRLC) < 0) { 125234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCSRLC"); 125334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 125434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 125534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl(tcp->pfd, followfork ? PIOCSFORK : PIOCRFORK) < 0) { 125634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOC{S,R}FORK"); 125734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 125834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 125934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 126034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* just unset the PF_LINGER flag for the Run-on-Last-Close. */ 126134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl(tcp->pfd, PIOCGFL, &arg) < 0) { 126234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCGFL"); 1263f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 126434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 126534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg &= ~PF_LINGER; 126634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl(tcp->pfd, PIOCSFL, arg) < 0) { 1267f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror("PIOCSFL"); 1268f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 126934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 127034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 127134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !PIOCSET */ 127234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 127334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Enable all syscall entries we care about. */ 127434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project premptyset(&syscalls); 127534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 1; i < MAX_QUALS; ++i) { 127634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (i > (sizeof syscalls) * CHAR_BIT) break; 127734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (qual_flags [i] & QUAL_TRACE) praddset (&syscalls, i); 127834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 127934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_execve); 128034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (followfork) { 128134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_fork); 128234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SYS_forkall 128334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_forkall); 128434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 128534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SYS_fork1 128634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_fork1); 128734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 128834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SYS_rfork1 128934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_rfork1); 129034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 129134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SYS_rforkall 129234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project praddset (&syscalls, SYS_rforkall); 129334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 129434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 129534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSENTRY, &syscalls) < 0) { 129634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCSENTRY"); 129734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 129834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 129934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Enable the syscall exits. */ 130034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSEXIT, &syscalls) < 0) { 130134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOSEXIT"); 130234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 130334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 130434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Enable signals we care about. */ 130534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project premptyset(&signals); 130634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 1; i < MAX_QUALS; ++i) { 130734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (i > (sizeof signals) * CHAR_BIT) break; 130834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (qual_flags [i] & QUAL_SIGNAL) praddset (&signals, i); 130934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 131034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSTRACE, &signals) < 0) { 131134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCSTRACE"); 131234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 131334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 131434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Enable faults we care about */ 131534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project premptyset(&faults); 131634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 1; i < MAX_QUALS; ++i) { 131734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (i > (sizeof faults) * CHAR_BIT) break; 131834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (qual_flags [i] & QUAL_FAULT) praddset (&faults, i); 131934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 132034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCSFAULT, &faults) < 0) { 132134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCSFAULT"); 132234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 132334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 132434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 132534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* set events flags. */ 132634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = S_SIG | S_SCE | S_SCX ; 132734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if(ioctl(tcp->pfd, PIOCBIS, arg) < 0) { 132834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCBIS"); 132934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 133034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 133134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 133234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!attaching) { 133334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef MIPS 133434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 133534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * The SGI PRSABORT doesn't work for pause() so 133634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * we send it a caught signal to wake it up. 133734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 133834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(tcp->pid, SIGINT); 133934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !MIPS */ 134034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef PRSABORT 134134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* The child is in a pause(), abort it. */ 134234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = PRSABORT; 134334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) { 134434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCRUN"); 134534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 134634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 134734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 134834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !MIPS*/ 134934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 135034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* wake up the child if it received the SIGSTOP */ 135134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(tcp->pid, SIGCONT); 135234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 135334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (;;) { 135434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Wait for the child to do something. */ 135534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL_WSTOP (tcp) < 0) { 135634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCWSTOP"); 135734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 135834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 135934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->status.PR_WHY == PR_SYSENTRY) { 136034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~TCB_INSYSCALL; 136134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project get_scno(tcp); 136234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (known_scno(tcp) == SYS_execve) 136334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 136434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 136534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Set it running: maybe execve will be next. */ 136634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 136734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = 0; 136834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCRUN, &arg) < 0) { 136934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 137034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (IOCTL(tcp->pfd, PIOCRUN, 0) < 0) { 137134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 137234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCRUN"); 137334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 137434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 137534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 137634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* handle the case where we "opened" the child before 137734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project it did the kill -STOP */ 137834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->status.PR_WHY == PR_SIGNALLED && 137934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->status.PR_WHAT == SIGSTOP) 138034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(tcp->pid, SIGCONT); 138134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 138234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 138334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 138434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 138534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 138634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } else { 138734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (attaching < 2) { 138834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* We are attaching to an already running process. 138934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Try to figure out the state of the process in syscalls, 139034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * to handle the first event well. 139134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * This is done by having a look at the "wchan" property of the 139234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * process, which tells where it is stopped (if it is). */ 139334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project FILE * status; 139434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project char wchan[20]; /* should be enough */ 139534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 139634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(proc, "/proc/%d/status", tcp->pid); 139734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project status = fopen(proc, "r"); 139834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (status && 139934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project (fscanf(status, "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d" 140034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "%*d,%*d %*d,%*d %19s", wchan) == 1) && 140134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project strcmp(wchan, "nochan") && strcmp(wchan, "spread") && 140234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project strcmp(wchan, "stopevent")) { 140334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* The process is asleep in the middle of a syscall. 140434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project Fake the syscall entry event */ 140534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~(TCB_INSYSCALL|TCB_STARTUP); 140634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->status.PR_WHY = PR_SYSENTRY; 140734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project trace_syscall(tcp); 140834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 140934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (status) 141034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fclose(status); 141134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } /* otherwise it's a fork being followed */ 141234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 141334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 141434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 141534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (proc_poll_pipe[0] != -1) 141634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project proc_poller(tcp->pfd); 141734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else if (nprocs > 1) { 141834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project proc_poll_open(); 141934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project proc_poller(last_pfd); 142034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project proc_poller(tcp->pfd); 142134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 142234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project last_pfd = tcp->pfd; 142334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 142434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 142534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 142634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 142734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* USE_PROCFS */ 142834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 142934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb * 1430f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownpid2tcb(int pid) 143134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 143234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 1433f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1434f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid <= 0) 1435f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return NULL; 143634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 143734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < tcbtabsize; i++) { 1438f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *tcp = tcbtab[i]; 1439f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 144034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return tcp; 144134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1442f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 144334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return NULL; 144434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 144534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 144634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 144734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 144834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic struct tcb * 1449f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownfirst_used_tcb(void) 1450f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 1451f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int i; 1452f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *tcp; 1453f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (i = 0; i < tcbtabsize; i++) { 1454f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = tcbtab[i]; 1455f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->flags & TCB_INUSE) 1456f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return tcp; 1457f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1458f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return NULL; 1459f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 1460f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1461f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic struct tcb * 146234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectpfd2tcb(pfd) 146334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint pfd; 146434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 146534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 146634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 146734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < tcbtabsize; i++) { 146834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp = tcbtab[i]; 146934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->pfd != pfd) 147034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 147134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_INUSE) 147234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return tcp; 147334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 147434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return NULL; 147534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 147634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 147734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* USE_PROCFS */ 147834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 147934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 148034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectdroptcb(tcp) 148134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb *tcp; 148234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 148334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->pid == 0) 148434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return; 148534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_CLONE_THREAD 148634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->nclone_threads > 0) { 148734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* There are other threads left in this process, but this 148834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project is the one whose PID represents the whole process. 148934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project We need to keep this record around as a zombie until 149034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project all the threads die. */ 149134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags |= TCB_EXITING; 149234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return; 149334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 149434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 149534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project nprocs--; 149634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pid = 0; 149734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 149834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->parent != NULL) { 149934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->parent->nchildren--; 150034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_CLONE_THREAD 150134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_CLONE_THREAD) 150234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->parent->nclone_threads--; 150334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 1504f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->parent->nzombies++; 1505f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 1506f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Update `tcp->parent->parent->nchildren' and the other fields 1507f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown like NCLONE_DETACHED, only for zombie group leader that has 1508f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown already reported and been short-circuited at the top of this 1509f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown function. The same condition as at the top of DETACH. */ 1510f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcp->flags & TCB_CLONE_THREAD) && 1511f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->parent->nclone_threads == 0 && 1512f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (tcp->parent->flags & TCB_EXITING)) 1513f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(tcp->parent); 151434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 151534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->parent = NULL; 151634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 151734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 151834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags = 0; 151934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->pfd != -1) { 152034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project close(tcp->pfd); 152134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pfd = -1; 152234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 152334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->pfd_reg != -1) { 152434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project close(tcp->pfd_reg); 152534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pfd_reg = -1; 152634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 152734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->pfd_status != -1) { 152834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project close(tcp->pfd_status); 152934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pfd_status = -1; 153034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 153134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !FREEBSD */ 153234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 153334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project rebuild_pollv(); /* Note, flags needs to be cleared by now. */ 153434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 153534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 153634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 153734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (outfname && followfork > 1 && tcp->outf) 153834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fclose(tcp->outf); 153934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 154034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->outf = 0; 154134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 154234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 154334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef USE_PROCFS 154434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 154534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 154634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectresume(tcp) 154734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb *tcp; 154834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 154934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp == NULL) 155034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 155134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 155234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!(tcp->flags & TCB_SUSPENDED)) { 155334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "PANIC: pid %u not suspended\n", tcp->pid); 155434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 155534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 155634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~TCB_SUSPENDED; 155734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_CLONE_THREAD 155834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_CLONE_THREAD) 155934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->parent->nclone_waiting--; 156034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 156134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1562f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) 156334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 156434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 156534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!qflag) 156634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "Process %u resumed\n", tcp->pid); 156734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 156834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 156934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1570f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int 1571f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownresume_from_tcp (struct tcb *tcp) 1572f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 1573f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int error = 0; 1574f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int resumed = 0; 1575f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1576f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* XXX This won't always be quite right (but it never was). 1577f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown A waiter with argument 0 or < -1 is waiting for any pid in 1578f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown a particular pgrp, which this child might or might not be 1579f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown in. The waiter will only wake up if it's argument is -1 1580f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown or if it's waiting for tcp->pid's pgrp. It makes a 1581f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown difference to wake up a waiter when there might be more 1582f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown traced children, because it could get a false ECHILD 1583f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error. OTOH, if this was the last child in the pgrp, then 1584f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown it ought to wake up and get ECHILD. We would have to 1585f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown search the system for all pid's in the pgrp to be sure. 1586f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1587f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && (t->waitpid == -1 || 1588f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (t->waitpid == 0 && getpgid (tcp->pid) == getpgid (t->pid)) 1589f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown || (t->waitpid < 0 && t->waitpid == -getpid (t->pid))) 1590f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 1591f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1592f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->parent && 1593f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (tcp->parent->flags & TCB_SUSPENDED) && 1594f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (tcp->parent->waitpid <= 0 || tcp->parent->waitpid == tcp->pid)) { 1595f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error = resume(tcp->parent); 1596f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ++resumed; 1597f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1598f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef TCB_CLONE_THREAD 1599f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->parent && tcp->parent->nclone_waiting > 0) { 1600f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Some other threads of our parent are waiting too. */ 1601f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown unsigned int i; 1602f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1603f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Resume all the threads that were waiting for this PID. */ 1604f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (i = 0; i < tcbtabsize; i++) { 1605f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *t = tcbtab[i]; 1606f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (t->parent == tcp->parent && t != tcp 1607f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && ((t->flags & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1608f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1609f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && t->waitpid == tcp->pid) { 1610f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error |= resume (t); 1611f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ++resumed; 1612f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1613f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1614f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (resumed == 0) 1615f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Noone was waiting for this PID in particular, 1616f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown so now we might need to resume some wildcarders. */ 1617f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown for (i = 0; i < tcbtabsize; i++) { 1618f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *t = tcbtab[i]; 1619f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (t->parent == tcp->parent && t != tcp 1620f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && ((t->flags 1621f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown & (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1622f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown == (TCB_CLONE_THREAD|TCB_SUSPENDED)) 1623f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && t->waitpid <= 0 1624f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ) { 1625f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error |= resume (t); 1626f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown break; 1627f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1628f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1629f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1630f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 1631f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1632f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return error; 1633f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 1634f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 163534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !USE_PROCFS */ 163634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1637f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown/* detach traced process; continue with sig 1638f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown Never call DETACH twice on the same process as both unattached and 1639f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown attached-unstopped processes give the same ESRCH. For unattached process we 1640f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown would SIGSTOP it and wait for its SIGSTOP notification forever. */ 164134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 164234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 164334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectdetach(tcp, sig) 164434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb *tcp; 164534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint sig; 164634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 164734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int error = 0; 164834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 1649f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown int status, catch_sigstop; 1650f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *zombie = NULL; 1651f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1652f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* If the group leader is lingering only because of this other 1653f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown thread now dying, then detach the leader as well. */ 1654f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcp->flags & TCB_CLONE_THREAD) && 1655f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->parent->nclone_threads == 1 && 1656f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (tcp->parent->flags & TCB_EXITING)) 1657f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown zombie = tcp->parent; 165834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 165934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 166034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_BPTSET) 1661f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown clearbpt(tcp); 166234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 166334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 166434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 166534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Linux wrongly insists the child be stopped 166634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * before detaching. Arghh. We go through hoops 166734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * to make a clean break of things. 166834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 166934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if defined(SPARC) 167034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#undef PTRACE_DETACH 167134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#define PTRACE_DETACH PTRACE_SUNDETACH 167234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 1673f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 1674f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * On TCB_STARTUP we did PTRACE_ATTACH but still did not get the 1675f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * expected SIGSTOP. We must catch exactly one as otherwise the 1676f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * detached process would be left stopped (process state T). 1677f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 1678f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown catch_sigstop = (tcp->flags & TCB_STARTUP); 167934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, sig)) == 0) { 168034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* On a clear day, you can see forever. */ 168134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 168234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else if (errno != ESRCH) { 168334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Shouldn't happen. */ 168434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: ptrace(PTRACE_DETACH, ...)"); 168534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1686f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (my_tgkill((tcp->flags & TCB_CLONE_THREAD ? tcp->parent->pid 1687f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown : tcp->pid), 1688f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->pid, 0) < 0) { 168934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno != ESRCH) 169034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: checking sanity"); 169134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1692f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (!catch_sigstop && my_tgkill((tcp->flags & TCB_CLONE_THREAD 1693f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ? tcp->parent->pid : tcp->pid), 1694f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->pid, SIGSTOP) < 0) { 169534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno != ESRCH) 169634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: stopping child"); 169734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1698f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else 1699f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown catch_sigstop = 1; 1700f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (catch_sigstop) { 170134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (;;) { 170234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef __WALL 170334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (wait4(tcp->pid, &status, __WALL, NULL) < 0) { 170434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno == ECHILD) /* Already gone. */ 170534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 170634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno != EINVAL) { 170734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: waiting"); 170834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 170934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 171034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* __WALL */ 171134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* No __WALL here. */ 171234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (waitpid(tcp->pid, &status, 0) < 0) { 171334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno != ECHILD) { 171434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: waiting"); 171534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 171634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 171734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef __WCLONE 171834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* If no processes, try clones. */ 171934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (wait4(tcp->pid, &status, __WCLONE, 172034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project NULL) < 0) { 172134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno != ECHILD) 172234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: waiting"); 172334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 172434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 172534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* __WCLONE */ 172634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 172734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef __WALL 172834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 172934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 173034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!WIFSTOPPED(status)) { 173134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Au revoir, mon ami. */ 173234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 173334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 173434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WSTOPSIG(status) == SIGSTOP) { 1735f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ptrace_restart(PTRACE_DETACH, tcp, sig); 173634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 173734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 1738f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error = ptrace_restart(PTRACE_CONT, tcp, 1739f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown WSTOPSIG(status) == SIGTRAP ? 0 1740f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown : WSTOPSIG(status)); 1741f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (error < 0) 174234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 174334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 174434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 174534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* LINUX */ 174634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 174734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if defined(SUNOS4) 174834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* PTRACE_DETACH won't respect `sig' argument, so we post it here. */ 174934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (sig && kill(tcp->pid, sig) < 0) 175034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("detach: kill"); 175134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sig = 0; 1752f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error = ptrace_restart(PTRACE_DETACH, tcp, sig); 175334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* SUNOS4 */ 175434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 175534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef USE_PROCFS 1756f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown error |= resume_from_tcp (tcp); 175734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 175834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 175934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!qflag) 176034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "Process %u detached\n", tcp->pid); 176134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 176234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 1763f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 1764f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 1765f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (zombie != NULL) { 1766f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* TCP no longer exists therefore you must not detach () it. */ 1767f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(zombie); 1768f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 1769f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 1770f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 177134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return error; 177234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 177334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 177434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 177534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 1776f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic void reaper(int sig) 177734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 177834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int pid; 177934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int status; 178034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 178134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 178234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 178334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 178434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 178534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* USE_PROCFS */ 178634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 178734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 178834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectcleanup() 178934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 179034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 179134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 179234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 179334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < tcbtabsize; i++) { 179434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp = tcbtab[i]; 179534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!(tcp->flags & TCB_INUSE)) 179634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 179734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (debug) 179834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, 179934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "cleanup: looking at pid %u\n", tcp->pid); 180034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp_last && 180134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project (!outfname || followfork < 2 || tcp_last == tcp)) { 1802f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf(" <unfinished ...>"); 1803f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 180434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 180534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_ATTACHED) 180634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project detach(tcp, 0); 180734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else { 180834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(tcp->pid, SIGCONT); 180934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(tcp->pid, SIGTERM); 181034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 181134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 181234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (cflag) 181334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project call_summary(outf); 181434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 181534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 181634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 181734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectinterrupt(sig) 181834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint sig; 181934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 182034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project interrupted = 1; 182134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 182234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 182334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_STRERROR 182434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 182534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if !HAVE_DECL_SYS_ERRLIST 182634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectextern int sys_nerr; 182734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectextern char *sys_errlist[]; 182834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* HAVE_DECL_SYS_ERRLIST */ 182934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 183034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectconst char * 183134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstrerror(errno) 183234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint errno; 183334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 183434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static char buf[64]; 183534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 183634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (errno < 1 || errno >= sys_nerr) { 183734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(buf, "Unknown error %d", errno); 183834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return buf; 183934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 184034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return sys_errlist[errno]; 184134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 184234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 184334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* HAVE_STERRROR */ 184434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 184534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_STRSIGNAL 184634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 184734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 184834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectextern char *sys_siglist[]; 184934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 185034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 185134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectextern char *_sys_siglist[]; 185234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 185334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 185434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectconst char * 185534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstrsignal(sig) 185634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint sig; 185734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 185834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static char buf[64]; 185934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 186034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (sig < 1 || sig >= NSIG) { 186134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sprintf(buf, "Unknown signal %d", sig); 186234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return buf; 186334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 186434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE__SYS_SIGLIST 186534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return _sys_siglist[sig]; 186634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 186734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return sys_siglist[sig]; 186834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 186934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 187034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 187134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* HAVE_STRSIGNAL */ 187234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 187334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef USE_PROCFS 187434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 187534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 187634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectrebuild_pollv() 187734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 187834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i, j; 187934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 188034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pollv != NULL) 188134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project free (pollv); 188234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollv = (struct pollfd *) malloc(nprocs * sizeof pollv[0]); 188334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pollv == NULL) { 188434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "%s: out of memory\n", progname); 188534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 188634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 188734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 188834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = j = 0; i < tcbtabsize; i++) { 188934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp = tcbtab[i]; 189034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!(tcp->flags & TCB_INUSE)) 189134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 189234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollv[j].fd = tcp->pfd; 189334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollv[j].events = POLLWANT; 189434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project j++; 189534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 189634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (j != nprocs) { 189734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "strace: proc miscount\n"); 189834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 189934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 190034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 190134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 190234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 190334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 190434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 190534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectproc_poll_open() 190634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 190734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 190834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 190934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pipe(proc_poll_pipe) < 0) { 191034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("pipe"); 191134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 191234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 191334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < 2; i++) { 1914f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (set_cloexec_flag(proc_poll_pipe[i]) < 0) { 191534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 191634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 191734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 191834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 191934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 192034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 192134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectproc_poll(pollv, nfds, timeout) 192234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct pollfd *pollv; 192334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint nfds; 192434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint timeout; 192534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 192634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 192734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int n; 192834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct proc_pollfd pollinfo; 192934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 193034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((n = read(proc_poll_pipe[0], &pollinfo, sizeof(pollinfo))) < 0) 193134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return n; 193234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (n != sizeof(struct proc_pollfd)) { 193334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "panic: short read: %d\n", n); 193434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 193534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 193634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < nprocs; i++) { 193734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pollv[i].fd == pollinfo.fd) 193834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollv[i].revents = pollinfo.revents; 193934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else 194034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollv[i].revents = 0; 194134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 194234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project poller_pid = pollinfo.pid; 194334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 1; 194434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 194534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 194634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 194734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectwakeup_handler(sig) 194834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint sig; 194934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 195034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 195134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 195234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic void 195334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectproc_poller(pfd) 195434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint pfd; 195534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 195634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct proc_pollfd pollinfo; 195734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct sigaction sa; 195834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigset_t blocked_set, empty_set; 195934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i; 196034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int n; 196134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct rlimit rl; 196234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 196334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct procfs_status pfs; 196434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 196534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 196634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (fork()) { 196734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case -1: 196834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("fork"); 1969f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 197034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 0: 197134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 197234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 197334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return; 197434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 197534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 197634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = interactive ? SIG_DFL : SIG_IGN; 197734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_flags = 0; 197834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&sa.sa_mask); 197934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGHUP, &sa, NULL); 198034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGINT, &sa, NULL); 198134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGQUIT, &sa, NULL); 198234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGPIPE, &sa, NULL); 198334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGTERM, &sa, NULL); 198434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sa.sa_handler = wakeup_handler; 198534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaction(SIGUSR1, &sa, NULL); 198634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&blocked_set); 198734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigaddset(&blocked_set, SIGUSR1); 198834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigprocmask(SIG_BLOCK, &blocked_set, NULL); 198934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigemptyset(&empty_set); 199034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 199134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { 199234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("getrlimit(RLIMIT_NOFILE, ...)"); 1993f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown _exit(1); 199434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 199534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project n = rl.rlim_cur; 199634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < n; i++) { 199734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (i != pfd && i != proc_poll_pipe[1]) 199834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project close(i); 199934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 200034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 200134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollinfo.fd = pfd; 200234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollinfo.pid = getpid(); 200334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (;;) { 200434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 2005f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ioctl(pfd, PIOCWSTOP, NULL) < 0) 2006f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else 2007f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ioctl(pfd, PIOCWSTOP, &pfs) < 0) 2008f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 200934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project { 201034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (errno) { 201134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case EINTR: 201234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 201334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case EBADF: 201434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollinfo.revents = POLLERR; 201534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 201634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case ENOENT: 201734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollinfo.revents = POLLHUP; 201834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 201934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 202034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("proc_poller: PIOCWSTOP"); 202134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 202234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 202334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project _exit(0); 202434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 202534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pollinfo.revents = POLLWANT; 202634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project write(proc_poll_pipe[1], &pollinfo, sizeof(pollinfo)); 202734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigsuspend(&empty_set); 202834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 202934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 203034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 203134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 203234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 203334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 203434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectchoose_pfd() 203534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 203634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int i, j; 203734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 203834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 203934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static int last; 204034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 204134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (followfork < 2 && 204234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project last < nprocs && (pollv[last].revents & POLLWANT)) { 204334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 204434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * The previous process is ready to run again. We'll 204534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * let it do so if it is currently in a syscall. This 204634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * heuristic improves the readability of the trace. 204734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 204834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp = pfd2tcb(pollv[last].fd); 204934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp && (tcp->flags & TCB_INSYSCALL)) 205034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return pollv[last].fd; 205134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 205234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 205334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (i = 0; i < nprocs; i++) { 205434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Let competing children run round robin. */ 205534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project j = (i + last + 1) % nprocs; 205634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pollv[j].revents & (POLLHUP | POLLERR)) { 205734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp = pfd2tcb(pollv[j].fd); 205834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!tcp) { 205934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "strace: lost proc\n"); 206034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 206134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 206234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 206334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 206434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 206534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pollv[j].revents & POLLWANT) { 206634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project last = j; 206734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return pollv[j].fd; 206834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 206934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 207034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "strace: nothing ready\n"); 207134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 207234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 207334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 207434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 207534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projecttrace() 207634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 207734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef POLL_HACK 207834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *in_syscall = NULL; 207934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 208034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 208134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int pfd; 208234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int what; 208334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int ioctl_result = 0, ioctl_errno = 0; 208434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project long arg; 208534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 208634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project for (;;) { 208734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interactive) 208834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigprocmask(SIG_SETMASK, &empty_set, NULL); 208934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 209034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (nprocs == 0) 209134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 209234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 209334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (nprocs) { 209434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 1: 209534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 209634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (proc_poll_pipe[0] == -1) { 209734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 2098f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = first_used_tcb(); 209934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!tcp) 210034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 210134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pfd = tcp->pfd; 210234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pfd == -1) 210334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 210434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 210534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 210634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 210734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* fall through ... */ 210834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 210934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 211034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_POLLABLE_PROCFS 211134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef POLL_HACK 211234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* On some systems (e.g. UnixWare) we get too much ugly 211334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "unfinished..." stuff when multiple proceses are in 211434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project syscalls. Here's a nasty hack */ 211534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 211634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (in_syscall) { 211734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct pollfd pv; 211834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp = in_syscall; 211934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project in_syscall = NULL; 212034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pv.fd = tcp->pfd; 212134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pv.events = POLLWANT; 212234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((what = poll (&pv, 1, 1)) < 0) { 212334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interrupted) 212434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 212534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 212634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 212734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else if (what == 1 && pv.revents & POLLWANT) { 212834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project goto FOUND; 212934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 213034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 213134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 213234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 213334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (poll(pollv, nprocs, INFTIM) < 0) { 213434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interrupted) 213534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 213634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 213734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 213834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !HAVE_POLLABLE_PROCFS */ 213934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (proc_poll(pollv, nprocs, INFTIM) < 0) { 214034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interrupted) 214134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 214234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 214334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 214434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 214534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pfd = choose_pfd(); 214634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pfd == -1) 214734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 214834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 214934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 215034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 215134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Look up `pfd' in our table. */ 215234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp = pfd2tcb(pfd)) == NULL) { 215334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "unknown pfd: %u\n", pfd); 215434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 215534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 215634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef POLL_HACK 215734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project FOUND: 215834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 215934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Get the status of the process. */ 216034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!interrupted) { 216134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 216234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ioctl_result = IOCTL_WSTOP (tcp); 216334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* FREEBSD */ 216434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Thanks to some scheduling mystery, the first poller 216534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sometimes waits for the already processed end of fork 216634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project event. Doing a non blocking poll here solves the problem. */ 216734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (proc_poll_pipe[0] != -1) 216834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ioctl_result = IOCTL_STATUS (tcp); 216934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else 2170f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ioctl_result = IOCTL_WSTOP (tcp); 217134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* FREEBSD */ 217234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ioctl_errno = errno; 217334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef HAVE_POLLABLE_PROCFS 217434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (proc_poll_pipe[0] != -1) { 217534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl_result < 0) 217634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(poller_pid, SIGKILL); 217734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else 217834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project kill(poller_pid, SIGUSR1); 217934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 218034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !HAVE_POLLABLE_PROCFS */ 218134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 218234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interrupted) 218334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 218434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 218534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interactive) 218634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigprocmask(SIG_BLOCK, &blocked_set, NULL); 218734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 218834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (ioctl_result < 0) { 218934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Find out what happened if it failed. */ 219034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (ioctl_errno) { 219134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case EINTR: 219234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case EBADF: 219334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 219434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 219534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case ENOTTY: 219634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 219734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case ENOENT: 219834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 219934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 220034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 220134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCWSTOP"); 220234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 220334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 220434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 220534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 220634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 220734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp->flags & TCB_STARTUP) && (tcp->status.PR_WHY == PR_SYSEXIT)) { 220834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* discard first event for a syscall we never entered */ 220934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project IOCTL (tcp->pfd, PIOCRUN, 0); 221034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 221134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 221234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 221334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 221434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* clear the just started flag */ 221534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~TCB_STARTUP; 221634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 221734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* set current output file */ 221834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project outf = tcp->outf; 2219f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown curcol = tcp->curcol; 222034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 222134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (cflag) { 222234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct timeval stime; 222334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 222434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project char buf[1024]; 222534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int len; 222634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 222734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((len = pread(tcp->pfd_status, buf, sizeof(buf) - 1, 0)) > 0) { 222834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project buf[len] = '\0'; 222934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sscanf(buf, 223034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "%*s %*d %*d %*d %*d %*d,%*d %*s %*d,%*d %*d,%*d %ld,%ld", 223134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project &stime.tv_sec, &stime.tv_usec); 223234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } else 223334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project stime.tv_sec = stime.tv_usec = 0; 223434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !FREEBSD */ 223534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project stime.tv_sec = tcp->status.pr_stime.tv_sec; 223634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project stime.tv_usec = tcp->status.pr_stime.tv_nsec/1000; 223734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !FREEBSD */ 223834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tv_sub(&tcp->dtime, &stime, &tcp->stime); 223934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->stime = stime; 224034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 224134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project what = tcp->status.PR_WHAT; 224234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (tcp->status.PR_WHY) { 224334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 224434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case PR_REQUESTED: 224534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->status.PR_FLAGS & PR_ASLEEP) { 224634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->status.PR_WHY = PR_SYSENTRY; 224734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (trace_syscall(tcp) < 0) { 224834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "syscall trouble\n"); 224934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 225034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 225134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 225234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 225334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !FREEBSD */ 225434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case PR_SYSENTRY: 225534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef POLL_HACK 225634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project in_syscall = tcp; 225734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 225834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case PR_SYSEXIT: 225934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (trace_syscall(tcp) < 0) { 226034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "syscall trouble\n"); 226134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 226234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 226334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 226434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case PR_SIGNALLED: 2265f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag != CFLAG_ONLY_STATS 2266f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && (qual_flags[what] & QUAL_SIGNAL)) { 226734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printleader(tcp); 226834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("--- %s (%s) ---", 226934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project signame(what), strsignal(what)); 2270f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 227134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef PR_INFO 227234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->status.PR_INFO.si_signo == what) { 227334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printleader(tcp); 227434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf(" siginfo="); 227534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printsiginfo(&tcp->status.PR_INFO, 1); 2276f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 227734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 227834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 227934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 228034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 228134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case PR_FAULTED: 2282f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag != CFLAGS_ONLY_STATS 2283f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && (qual_flags[what] & QUAL_FAULT)) { 228434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printleader(tcp); 228534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("=== FAULT %d ===", what); 2286f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 228734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 228834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 228934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef FREEBSD 229034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case 0: /* handle case we polled for nothing */ 2291f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 229234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 229334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 229434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "odd stop %d\n", tcp->status.PR_WHY); 229534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 229634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project break; 229734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2298f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Remember current print column before continuing. */ 2299f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->curcol = curcol; 230034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project arg = 0; 230134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifndef FREEBSD 2302f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (IOCTL (tcp->pfd, PIOCRUN, &arg) < 0) 230334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 2304f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (IOCTL (tcp->pfd, PIOCRUN, 0) < 0) 230534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 2306f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown { 230734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("PIOCRUN"); 230834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 230934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 231034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 231134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 231234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 231334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 231434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else /* !USE_PROCFS */ 231534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 231634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 231734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project/* Handle an exit detach or death signal that is taking all the 231834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project related clone threads with it. This is called in three circumstances: 231934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project SIG == -1 TCP has already died (TCB_ATTACHED is clear, strace is parent). 232034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project SIG == 0 Continuing TCP will perform an exit_group syscall. 232134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project SIG == other Continuing TCP with SIG will kill the process. 232234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project*/ 232334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 232434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projecthandle_group_exit(struct tcb *tcp, int sig) 232534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 232634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* We need to locate our records of all the clone threads 232734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project related to TCP, either its children or siblings. */ 2328f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown struct tcb *leader = NULL; 2329f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 2330f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->flags & TCB_CLONE_THREAD) 2331f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown leader = tcp->parent; 233234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 233334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (sig < 0) { 2334f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (leader != NULL && leader != tcp 2335f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && !(leader->flags & TCB_GROUP_EXITING) 2336f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && !(tcp->flags & TCB_STARTUP) 2337f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ) { 233834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, 233934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "PANIC: handle_group_exit: %d leader %d\n", 234034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pid, leader ? leader->pid : -1); 2341f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2342f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* TCP no longer exists therefore you must not detach() it. */ 2343f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifndef USE_PROCFS 2344f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown resume_from_tcp(tcp); 2345f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 234634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); /* Already died. */ 234734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 234834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else { 2349f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Mark that we are taking the process down. */ 2350f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->flags |= TCB_EXITING | TCB_GROUP_EXITING; 235134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_ATTACHED) { 235234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project detach(tcp, sig); 235334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (leader != NULL && leader != tcp) 2354f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown leader->flags |= TCB_GROUP_EXITING; 2355f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else { 2356f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_restart(PTRACE_CONT, tcp, sig) < 0) { 2357f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 2358f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 2359f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2360f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (leader != NULL) { 2361f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown leader->flags |= TCB_GROUP_EXITING; 2362f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (leader != tcp) 2363f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown droptcb(tcp); 2364f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 236534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* The leader will report to us as parent now, 236634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project and then we'll get to the SIG==-1 case. */ 236734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 236834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 236934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 237034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 237134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 237234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 237334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 237434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2375f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 2376f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownstatic int 2377f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownhandle_ptrace_event(int status, struct tcb *tcp) 2378f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 2379f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (status >> 16 == PTRACE_EVENT_VFORK || 2380f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown status >> 16 == PTRACE_EVENT_CLONE || 2381f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown status >> 16 == PTRACE_EVENT_FORK) { 2382f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown long childpid; 2383f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 2384f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (do_ptrace(PTRACE_GETEVENTMSG, tcp, NULL, &childpid) < 0) { 2385f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (errno != ESRCH) { 2386f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "\ 2387f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown%s: handle_ptrace_event: ptrace cannot get new child's pid\n", 2388f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown progname); 2389f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown cleanup(); 2390f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit(1); 2391f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2392f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return -1; 2393f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2394f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return handle_new_child(tcp, childpid, 0); 2395f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2396f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 1; 2397f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown} 2398f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 2399f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 240034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstatic int 240134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projecttrace() 240234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 240334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int pid; 240434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int wait_errno; 240534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int status; 240634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct tcb *tcp; 240734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 240834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct rusage ru; 240934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef __WALL 241034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static int wait4_options = __WALL; 241134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 241234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* LINUX */ 241334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 241434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project while (nprocs != 0) { 2415f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interrupted) 2416f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 241734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interactive) 241834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigprocmask(SIG_SETMASK, &empty_set, NULL); 241934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 242034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef __WALL 242134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid = wait4(-1, &status, wait4_options, cflag ? &ru : NULL); 242234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 242334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* this kernel does not support __WALL */ 242434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project wait4_options &= ~__WALL; 242534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project errno = 0; 242634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid = wait4(-1, &status, wait4_options, 242734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cflag ? &ru : NULL); 242834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 242934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 243034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* most likely a "cloned" process */ 243134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid = wait4(-1, &status, __WCLONE, 243234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cflag ? &ru : NULL); 243334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pid == -1) { 243434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "strace: clone wait4 " 243534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project "failed: %s\n", strerror(errno)); 243634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 243734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 243834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 243934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid = wait4(-1, &status, 0, cflag ? &ru : NULL); 244034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* __WALL */ 244134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* LINUX */ 244234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef SUNOS4 244334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid = wait(&status); 244434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* SUNOS4 */ 244534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project wait_errno = errno; 244634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (interactive) 244734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project sigprocmask(SIG_BLOCK, &blocked_set, NULL); 244834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 244934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (pid == -1) { 245034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project switch (wait_errno) { 245134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case EINTR: 245234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 245334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project case ECHILD: 245434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 245534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * We would like to verify this case 245634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * but sometimes a race in Solbourne's 245734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * version of SunOS sometimes reports 245834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * ECHILD before sending us SIGCHILD. 245934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 246034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 246134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project default: 246234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project errno = wait_errno; 246334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project perror("strace: wait"); 246434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 246534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 246634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2467f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid == popen_pid) { 2468f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (WIFEXITED(status) || WIFSIGNALED(status)) 2469f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown popen_pid = -1; 2470f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown continue; 2471f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 247234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (debug) 247334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, " [wait(%#x) = %u]\n", status, pid); 247434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 247534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* Look up `pid' in our table. */ 247634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((tcp = pid2tcb(pid)) == NULL) { 247734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 2478f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (followfork) { 247934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* This is needed to go with the CLONE_PTRACE 248034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project changes in process.c/util.c: we might see 248134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project the child's initial trap before we see the 248234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project parent return from the clone syscall. 248334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project Leave the child suspended until the parent 248434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project returns from its system call. Only then 248534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project will we have the association of parent and 248634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project child so that we know how to do clearbpt 248734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project in the child. */ 2488f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp = alloctcb(pid); 248934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags |= TCB_ATTACHED | TCB_SUSPENDED; 249034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!qflag) 249134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "\ 249234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source ProjectProcess %d attached (waiting for parent)\n", 249334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid); 249434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 249534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else 249634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* This can happen if a clone call used 249734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project CLONE_PTRACE itself. */ 249834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 249934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project { 250034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "unknown pid: %u\n", pid); 250134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WIFSTOPPED(status)) 250234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ptrace(PTRACE_CONT, pid, (char *) 1, 0); 250334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project exit(1); 250434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 250534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 250634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* set current output file */ 250734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project outf = tcp->outf; 2508f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown curcol = tcp->curcol; 250934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (cflag) { 251034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef LINUX 251134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 251234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->stime = ru.ru_stime; 251334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !LINUX */ 251434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 251534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 251634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_SUSPENDED) { 251734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 251834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Apparently, doing any ptrace() call on a stopped 251934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * process, provokes the kernel to report the process 252034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * status again on a subsequent wait(), even if the 252134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * process has not been actually restarted. 252234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Since we have inspected the arguments of suspended 252334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * processes we end up here testing for this case. 252434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 252534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 252634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 252734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WIFSIGNALED(status)) { 2528f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid == strace_child) 2529f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit_code = 0x100 | WTERMSIG(status); 2530f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag != CFLAG_ONLY_STATS 253134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 253234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printleader(tcp); 253334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("+++ killed by %s %s+++", 253434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project signame(WTERMSIG(status)), 253534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef WCOREDUMP 253634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project WCOREDUMP(status) ? "(core dumped) " : 253734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 253834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ""); 2539f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 254034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 254134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 254234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project handle_group_exit(tcp, -1); 254334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 254434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 254534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 254634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 254734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 254834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WIFEXITED(status)) { 2549f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (pid == strace_child) 2550f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown exit_code = WEXITSTATUS(status); 255134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (debug) 2552f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown fprintf(stderr, "pid %u exited with %d\n", pid, WEXITSTATUS(status)); 2553f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcp->flags & (TCB_ATTACHED|TCB_STARTUP)) == TCB_ATTACHED 255434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 2555f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && !(tcp->parent && (tcp->parent->flags & TCB_GROUP_EXITING)) 2556f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown && !(tcp->flags & TCB_GROUP_EXITING) 255734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 2558f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ) { 255934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, 2560f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown "PANIC: attached pid %u exited with %d\n", 2561f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown pid, WEXITSTATUS(status)); 2562f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 256334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp == tcp_last) { 2564f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcp->flags & (TCB_INSYSCALL|TCB_REPRINT)) == TCB_INSYSCALL) 256534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf(" <unfinished ... exit status %d>\n", 256634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project WEXITSTATUS(status)); 256734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp_last = NULL; 256834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 256934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 257034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project handle_group_exit(tcp, -1); 257134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 257234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 257334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 257434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 257534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 257634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!WIFSTOPPED(status)) { 257734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 257834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 257934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 258034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 258134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (debug) 258234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "pid %u stopped, [%s]\n", 258334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pid, signame(WSTOPSIG(status))); 258434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2585f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_setoptions && (status >> 16)) { 2586f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (handle_ptrace_event(status, tcp) != 1) 2587f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown goto tracing; 2588f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2589f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown 2590f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* 2591f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Interestingly, the process may stop 2592f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * with STOPSIG equal to some other signal 2593f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * than SIGSTOP if we happend to attach 2594f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * just before the process takes a signal. 2595f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * A no-MMU vforked child won't send up a signal, 2596f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * so skip the first (lost) execve notification. 2597f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 2598f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if ((tcp->flags & TCB_STARTUP) && 2599f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown (WSTOPSIG(status) == SIGSTOP || strace_vforked)) { 260034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 260134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * This flag is there to keep us in sync. 260234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Next time this process stops it should 260334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * really be entering a system call. 260434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 260534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~TCB_STARTUP; 2606f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->flags & TCB_BPTSET) { 260734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 2608f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * One example is a breakpoint inherited from 2609f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * parent through fork (). 261034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 261134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (clearbpt(tcp) < 0) /* Pretty fatal */ { 261234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 261334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 261434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 261534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 261634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2617f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#ifdef LINUX 2618f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (followfork && (tcp->parent == NULL) && ptrace_setoptions) 2619f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_SETOPTIONS, tcp->pid, 2620f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown NULL, ptrace_setoptions) < 0 && 2621f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown errno != ESRCH) 2622f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ptrace_setoptions = 0; 2623f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#endif 262434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project goto tracing; 262534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 262634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 262734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WSTOPSIG(status) != SIGTRAP) { 262834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (WSTOPSIG(status) == SIGSTOP && 262934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project (tcp->flags & TCB_SIGTRAPPED)) { 263034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project /* 263134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Trapped attempt to block SIGTRAP 263234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project * Hope we are back in control now. 263334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project */ 263434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED); 2635f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) { 263634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 263734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 263834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 263934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 264034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2641f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (cflag != CFLAG_ONLY_STATS 264234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project && (qual_flags[WSTOPSIG(status)] & QUAL_SIGNAL)) { 2643f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown siginfo_t si; 2644f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 2645f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown long pc = 0; 2646f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown long psr = 0; 264734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2648f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown upeek(tcp, PT_CR_IPSR, &psr); 2649f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown upeek(tcp, PT_CR_IIP, &pc); 265034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2651f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define PSR_RI 41 265234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project pc += (psr >> PSR_RI) & 0x3; 2653f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define PC_FORMAT_STR " @ %lx" 2654f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define PC_FORMAT_ARG pc 2655f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown#else 2656f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define PC_FORMAT_STR "%s" 2657f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown# define PC_FORMAT_ARG "" 265834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 265934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printleader(tcp); 2660f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace(PTRACE_GETSIGINFO, pid, 0, &si) == 0) { 2661f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf("--- "); 2662f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printsiginfo(&si, verbose(tcp)); 2663f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf(" (%s)" PC_FORMAT_STR " ---", 2664f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strsignal(WSTOPSIG(status)), 2665f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PC_FORMAT_ARG); 2666f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else 2667f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf("--- %s by %s" PC_FORMAT_STR " ---", 2668f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown strsignal(WSTOPSIG(status)), 2669f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown signame(WSTOPSIG(status)), 2670f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown PC_FORMAT_ARG); 2671f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 267234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 267334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (((tcp->flags & TCB_ATTACHED) || 267434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->nclone_threads > 0) && 267534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project !sigishandled(tcp, WSTOPSIG(status))) { 267634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 267734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project handle_group_exit(tcp, WSTOPSIG(status)); 267834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#else 267934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project detach(tcp, WSTOPSIG(status)); 268034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 268134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 268234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2683f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_restart(PTRACE_SYSCALL, tcp, WSTOPSIG(status)) < 0) { 268434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 268534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 268634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 268734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->flags &= ~TCB_SUSPENDED; 268834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 268934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 2690f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* we handled the STATUS, we are permitted to interrupt now. */ 2691f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (interrupted) 2692f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return 0; 2693f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2694f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* ptrace() failed in trace_syscall() with ESRCH. 2695f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Likely a result of process disappearing mid-flight. 2696f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Observed case: exit_group() terminating 2697f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * all processes in thread group. In this case, threads 2698f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * "disappear" in an unpredictable moment without any 2699f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * notification to strace via wait(). 2700f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 2701f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp->flags & TCB_ATTACHED) { 2702f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp_last) { 2703f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Do we have dangling line "syscall(param, param"? 2704f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown * Finish the line then. We cannot 2705f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown */ 2706f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp_last->flags |= TCB_REPRINT; 2707f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf(" <unfinished ...>"); 2708f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown printtrailer(); 2709f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 271034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project detach(tcp, 0); 2711f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else { 271234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ptrace(PTRACE_KILL, 271334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp->pid, (char *) 1, SIGTERM); 271434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project droptcb(tcp); 271534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 271634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 271734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 271834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_EXITING) { 271934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef TCB_GROUP_EXITING 272034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_GROUP_EXITING) { 272134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (handle_group_exit(tcp, 0) < 0) 272234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 272334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 272434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 272534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 272634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_ATTACHED) 272734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project detach(tcp, 0); 2728f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown else if (ptrace_restart(PTRACE_CONT, tcp, 0) < 0) { 272934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 273034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 273134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 273234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 273334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 273434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tcp->flags & TCB_SUSPENDED) { 273534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (!qflag) 273634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project fprintf(stderr, "Process %u suspended\n", pid); 273734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project continue; 273834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 273934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tracing: 2740f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown /* Remember current print column before continuing. */ 2741f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp->curcol = curcol; 2742f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (ptrace_restart(PTRACE_SYSCALL, tcp, 0) < 0) { 274334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project cleanup(); 274434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return -1; 274534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 274634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 274734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return 0; 274834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 274934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 275034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif /* !USE_PROCFS */ 275134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 275234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#include <stdarg.h> 275334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 275434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 275534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projecttprintf(const char *fmt, ...) 275634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 275734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project va_list args; 275834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2759f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown va_start(args, fmt); 276034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (outf) { 276134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int n = vfprintf(outf, fmt, args); 2762f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (n < 0) { 2763f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (outf != stderr) 2764f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown perror(outfname == NULL 2765f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown ? "<writing to pipe>" : outfname); 2766f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else 276734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project curcol += n; 276834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 276934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project va_end(args); 277034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project return; 277134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 277234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 277334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 277434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectprintleader(tcp) 277534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectstruct tcb *tcp; 277634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 2777f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp_last) { 2778f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp_last->ptrace_errno) { 2779f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown if (tcp_last->flags & TCB_INSYSCALL) { 2780f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf(" <unavailable>)"); 2781f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tabto(acolumn); 2782f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 2783f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf("= ? <unavailable>\n"); 2784f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp_last->ptrace_errno = 0; 2785f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } else if (!outfname || followfork < 2 || tcp_last == tcp) { 2786f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tcp_last->flags |= TCB_REPRINT; 2787f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown tprintf(" <unfinished ...>\n"); 2788f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown } 278934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 279034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project curcol = 0; 279134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if ((followfork == 1 || pflag_seen > 1) && outfname) 279234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%-5d ", tcp->pid); 279334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else if (nprocs > 1 && !outfname) 279434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("[pid %5u] ", tcp->pid); 279534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tflag) { 279634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project char str[sizeof("HH:MM:SS")]; 279734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct timeval tv, dtv; 279834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project static struct timeval otv; 279934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 280034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project gettimeofday(&tv, NULL); 280134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (rflag) { 280234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (otv.tv_sec == 0) 280334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project otv = tv; 280434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tv_sub(&dtv, &tv, &otv); 280534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%6ld.%06ld ", 280634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project (long) dtv.tv_sec, (long) dtv.tv_usec); 280734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project otv = tv; 280834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 280934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else if (tflag > 2) { 281034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%ld.%06ld ", 281134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project (long) tv.tv_sec, (long) tv.tv_usec); 281234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 281334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else { 281434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project time_t local = tv.tv_sec; 281534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project strftime(str, sizeof(str), "%T", localtime(&local)); 281634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (tflag > 1) 281734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%s.%06ld ", str, (long) tv.tv_usec); 281834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project else 281934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%s ", str); 282034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 282134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 282234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (iflag) 282334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project printcall(tcp); 282434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 282534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 282634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 282734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projecttabto(col) 282834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectint col; 282934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 283034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (curcol < col) 283134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("%*s", col - curcol, ""); 283234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 283334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 283434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Projectvoid 2835f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownprinttrailer(void) 283634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project{ 283734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tprintf("\n"); 283834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project tcp_last = NULL; 283934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 284034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 284134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#ifdef HAVE_MP_PROCFS 284234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2843f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownint 2844f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brownmp_ioctl(int fd, int cmd, void *arg, int size) 2845f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown{ 284634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project struct iovec iov[2]; 284734d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project int n = 1; 284834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 284934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project iov[0].iov_base = &cmd; 285034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project iov[0].iov_len = sizeof cmd; 285134d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project if (arg) { 285234d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project ++n; 285334d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project iov[1].iov_base = arg; 285434d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project iov[1].iov_len = size; 285534d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project } 285634d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 2857f76f96e20f766e6bb91593885b1e800f8bc14a52Jeff Brown return writev(fd, iov, n); 285834d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project} 285934d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project 286034d6eabc451f16d5f168fc1595ee604f21bccc51The Android Open Source Project#endif 2861