strace.c revision 61e7aad9fa1a6a5bd5a586e6276767caf12b53f2
176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman/* 276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 54dc8a2aec63e4fb5ee2688544c4de323ed5de3efWichert Akkerman * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * All rights reserved. 776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Redistribution and use in source and binary forms, with or without 976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * modification, are permitted provided that the following conditions 1076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * are met: 1176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1. Redistributions of source code must retain the above copyright 1276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer. 1376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 2. Redistributions in binary form must reproduce the above copyright 1476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * notice, this list of conditions and the following disclaimer in the 1576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * documentation and/or other materials provided with the distribution. 1676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3. The name of the author may not be used to endorse or promote products 1776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * derived from this software without specific prior written permission. 1876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 1976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * 3076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * $Id$ 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 3276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko#include <stdarg.h> 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h> 4076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h> 4176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h> 4276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h> 4370b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath#include <dirent.h> 44f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#include <sys/utsname.h> 458470374cba7df0e70653d95c4f336a4082c68d82Denys Vlasenko#if defined(IA64) 467b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman# include <asm/ptrace_offsets.h> 477b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 48a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko/* In some libc, these aren't declared. Do it ourself: */ 4996d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenkoextern char **environ; 50418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern int optind; 51418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoextern char *optarg; 5296d5a76109b4f1d1f4c9c76641e6ec896108083dDenys Vlasenko 53a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko 54a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#if defined __NR_tkill 55a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 56a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#else 57a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko /* kill() may choose arbitrarily the target task of the process group 58a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko while we later wait on a that specific TID. PID process waits become 59a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko TID task specific waits for a process under ptrace(2). */ 60a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# warning "Neither tkill(2) nor tgkill(2) available, risk of strace hangs!" 61a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) kill((tid), (sig)) 62a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#endif 63a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko 64a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#undef KERNEL_VERSION 65a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) 66a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko 67a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkocflag_t cflag = CFLAG_NONE; 68a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int followfork = 0; 69f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0; 70a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int xflag = 0; 71a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool debug_flag = 0; 72a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool Tflag = 0; 73a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool qflag = 0; 743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */ 7575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP; 76a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic unsigned int tflag = 0; 77a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool iflag = 0; 78a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool rflag = 0; 79a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool print_pid_pfx = 0; 80b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 81b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* -I n */ 82b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkoenum { 83b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NOT_SET = 0, 84b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 85b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 86b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 87b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 88b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko NUM_INTR_OPTS 89b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko}; 90b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkostatic int opt_intr; 91b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* We play with signal mask only if this mode is active: */ 92b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko#define interactive (opt_intr == INTR_WHILE_WAIT) 93b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 94ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/* 95ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option. 96ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice. 97ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's, 98ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process 99ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild 100ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID. 101ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases 102ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals, 103ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between, 104ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link. 105ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 106ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0; 10776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 10831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 10931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 11031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize (post_attach_sigstop == 0) 11131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 11231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 11331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize 0 11431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 11531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 11617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 117a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool not_failing_only = 0; 11817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 1198a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */ 120a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool show_fd_path = 0; 1218a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 1228a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* are we filtering traces based on paths? */ 123a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool tracing_paths = 0; 1248a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 12561e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenkostatic bool detach_on_execve = 0; 12661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenkostatic bool skip_startup_execve = 0; 12761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko 128a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0; 129a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0; 13075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0; 131eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 132b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL; 133ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid; 134ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid; 13576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int max_strlen = DEFAULT_STRLEN; 137a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic unsigned int acolumn = DEFAULT_ACOLUMN; 138102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic char *acolumn_spaces; 139b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL; 140ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic FILE *outf; 141000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenkostruct tcb *printing_tcp = NULL; 142a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic unsigned int curcol; 143ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab; 1442b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize; 145ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname; 14676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 147f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkostatic char *os_release; /* from uname() */ 148f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1494c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkostatic int detach(struct tcb *tcp); 150e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic int trace(void); 151e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void); 152e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig); 15376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 15476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 15676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 157a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#else 15876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 159a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#endif 16076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 162cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 16376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 16476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 165b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkousage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 166b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 167cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko [-P path] [PROG [ARGS]]\n\ 168b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 169cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko [PROG [ARGS]]\n\ 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 171b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab-C -- like -c but also print regular output while processes are running\n\ 1723e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-d -- enable debug output to stderr\n\ 173b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 17476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 1753e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-F -- attempt to follow vforks (deprecated, use -f)\n\ 17676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 177b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-I interruptible\n\ 178b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1: no signals are blocked\n\ 179b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 2: fatal signals are blocked while decoding syscall (default)\n\ 180b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 181b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 182b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 18376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 185cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-T -- print time spent in each syscall\n\ 186cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 18776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 1888a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 189cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-h -- print help message\n\ 190cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-V -- print version\n\ 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 19276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 19376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 19476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 19676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 19876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 200de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 201de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2028a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 20361e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko" 20461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* this is broken, so don't document it 20517f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 20661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */ 20761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* experimental, don't document it yet (option letter may change in the future!) 20861e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko-b -- detach on successful execve\n\ 20961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */ 210de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 21475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 21575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 21675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 21775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 21875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 21975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 22075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 22175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 22275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 22375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 22475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 22682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko char *msg; 22782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 22844d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 22982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 23082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We want to print entire message with single fprintf to ensure 23182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * message integrity if stderr is shared with other programs. 23282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * Thus we use vasprintf + single fprintf. 23382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko */ 23482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko msg = NULL; 235cfad543087d98c5313fd7f006c0de69a1d87dc8eDenys Vlasenko if (vasprintf(&msg, fmt, p) >= 0) { 23682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 23782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 23882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 23982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s\n", progname, msg); 24082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko free(msg); 24182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } else { 24282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* malloc in vasprintf failed, try it without malloc */ 24382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: ", progname); 24482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vfprintf(stderr, fmt, p); 24582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 24682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, ": %s\n", strerror(err_no)); 24782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 24882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko putc('\n', stderr); 24982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } 25082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We don't switch stderr to buffered, thus fprintf(stderr) 25182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * always flushes its output and this is not necessary: */ 25282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* fflush(stderr); */ 25375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 25675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 25775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 25875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 25975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 2603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 26175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 2623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 26375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 26475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 26575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 26675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 26775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 26875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 26975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 27075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 27175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 27275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 27375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 27475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 27575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 27675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 27775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 27875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 27975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 28075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 28175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 28275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 28375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 28475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 2853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 2863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 2871d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void) 2881d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{ 2891d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko static bool recursed = 0; 2901d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (recursed) 2911d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko exit(1); 2921d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko recursed = 1; 2931d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko error_msg_and_die("Out of memory"); 2941d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko} 2951d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 296c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger/* Glue for systems without a MMU that cannot provide fork() */ 297c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#ifdef HAVE_FORK 298c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 0 299c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#else 300c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 1 301c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define fork() vfork() 302c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#endif 303c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger 30431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 30531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int 30631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkoptrace_attach_or_seize(int pid) 30731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 30831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int r; 30931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) 31031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return ptrace(PTRACE_ATTACH, pid, 0, 0); 31131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 31231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (r) 31331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 31431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 31531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 31631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 31731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 31831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 31931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 32031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 3211f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 32210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 32310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3241f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 3251f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 3261f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 3271f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 3281f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 3291f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 3301f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 3311f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 3321f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 3331f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 33410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 33510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 33610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 33710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 3381f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 33910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3401f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 34110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 34210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 34375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenkostatic void kill_save_errno(pid_t pid, int sig) 34475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko{ 34575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int saved_errno = errno; 34675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 34775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko (void) kill(pid, sig); 34875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko errno = saved_errno; 34975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko} 35075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 3512e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 3522e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprintf(const char *fmt, ...) 3532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 3542e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_list args; 3552e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 3562e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_start(args, fmt); 3572e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf) { 3582e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko int n = vfprintf(outf, fmt, args); 3592e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n < 0) { 3602e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf != stderr) 3612e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko perror(outfname == NULL 3622e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko ? "<writing to pipe>" : outfname); 3632e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } else 3642e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol += n; 3652e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 3662e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_end(args); 3672e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 3682e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 3692e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 3702e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprints(const char *str) 3712e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 3722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf) { 3732e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko int n = fputs(str, outf); 3742e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n >= 0) { 3752e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol += strlen(str); 3762e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko return; 3772e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 3782e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf != stderr) 3792e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko perror(outfname == NULL 3802e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko ? "<writing to pipe>" : outfname); 3812e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 3822e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 3832e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 3842e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 3857de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkoline_ended(void) 3867de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko{ 3877de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko curcol = 0; 3887de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko fflush(outf); 3897de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (!printing_tcp) 3907de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko return; 3917de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 3927de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = NULL; 3937de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko} 3947de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 3957de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkovoid 3962e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkoprintleader(struct tcb *tcp) 3972e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 3987de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* If -ff, "previous tcb we printed" is always the same as current, 3997de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * because we have per-tcb output files. 4007de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 4017de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (followfork >= 2) 4027de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = tcp; 4037de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 4042e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp) { 4057de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko outf = printing_tcp->outf; 4067de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko curcol = printing_tcp->curcol; 4072e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp->ptrace_errno) { 4082e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp->flags & TCB_INSYSCALL) { 4092e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(" <unavailable>) "); 4102e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tabto(); 4112e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4122e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints("= ? <unavailable>\n"); 4132e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printing_tcp->ptrace_errno = 0; 4147de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 4157de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 4167de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) { 4177de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* 4187de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 1: we have a shared log (i.e. not -ff), and last line 4197de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * wasn't finished (same or different tcb, doesn't matter). 4207de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 2: split log, we are the same tcb, but our last line 4217de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * didn't finish ("SIGKILL nuked us after syscall entry" etc). 4227de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 4232e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(" <unfinished ...>\n"); 4247de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->flags |= TCB_REPRINT; 4257de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 4262e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4272e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4282e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4292e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printing_tcp = tcp; 4307de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko outf = tcp->outf; 4312e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol = 0; 4322e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4332e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (print_pid_pfx) 4342e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%-5d ", tcp->pid); 4352e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (nprocs > 1 && !outfname) 4362e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("[pid %5u] ", tcp->pid); 4372e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4382e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag) { 4392e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko char str[sizeof("HH:MM:SS")]; 4402e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko struct timeval tv, dtv; 4412e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko static struct timeval otv; 4422e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4432e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko gettimeofday(&tv, NULL); 4442e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (rflag) { 4452e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (otv.tv_sec == 0) 4462e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 4472e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tv_sub(&dtv, &tv, &otv); 4482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%6ld.%06ld ", 4492e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) dtv.tv_sec, (long) dtv.tv_usec); 4502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 4512e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4522e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (tflag > 2) { 4532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%ld.%06ld ", 4542e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) tv.tv_sec, (long) tv.tv_usec); 4552e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4562e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else { 4572e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko time_t local = tv.tv_sec; 4582e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko strftime(str, sizeof(str), "%T", localtime(&local)); 4592e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag > 1) 4602e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s.%06ld ", str, (long) tv.tv_usec); 4612e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else 4622e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s ", str); 4632e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4642e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4652e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (iflag) 4662e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printcall(tcp); 4672e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 4682e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4692e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 4702e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotabto(void) 4712e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 4722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (curcol < acolumn) 4732e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(acolumn_spaces + curcol); 4742e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 4752e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 47610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 47710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * When strace is setuid executable, we have to swap uids 47810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * before and after filesystem and process management operations. 47910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 48010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 48110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinswap_uid(void) 48210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 48310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin int euid = geteuid(), uid = getuid(); 48410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4857b609d5ba0852e6c56ba311350ebd4412361777bDenys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 486cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 48710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 48810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 48910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4904bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#if _LFS64_LARGEFILE 4914bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen64 4924bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#else 4934bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen 4944bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#endif 4954bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 49610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 4973d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostrace_fopen(const char *path) 49810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 49910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin FILE *fp; 50010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 50110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 5023d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko fp = fopen_for_output(path, "w"); 5033d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko if (!fp) 5043d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 50510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 5063d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko set_cloexec_flag(fileno(fp)); 50710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin return fp; 50810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 50910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5107dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenkostatic int popen_pid = 0; 51110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 51210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef _PATH_BSHELL 51310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin# define _PATH_BSHELL "/bin/sh" 51410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 51510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 51610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 51710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * We cannot use standard popen(3) here because we have to distinguish 51810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * popen child process from other processes we trace, and standard popen(3) 51910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * does not export its child's pid. 52010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 52110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 52210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstrace_popen(const char *command) 52310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 5247dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko FILE *fp; 5257dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko int fds[2]; 52610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 52710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 52810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pipe(fds) < 0) 5297dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("pipe"); 53010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5317dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 53210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5337dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = vfork(); 5347dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == -1) 5357dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("vfork"); 53610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5377dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == 0) { 53810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* child */ 53910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin close(fds[1]); 5407dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (fds[0] != 0) { 5417dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (dup2(fds[0], 0)) 5427dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("dup2"); 5437dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 54410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 54510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin execl(_PATH_BSHELL, "sh", "-c", command, NULL); 5467dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 54710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 5487dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 5497dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko /* parent */ 5507dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 5517dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko swap_uid(); 5527dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko fp = fdopen(fds[1], "w"); 5537dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (!fp) 5541d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 5557dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko return fp; 55610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 55710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5583d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostatic void 55910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinnewoutf(struct tcb *tcp) 56010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 5617de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (outfname && followfork >= 2) { 5627a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char name[520 + sizeof(int) * 3]; 5637a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 5643d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko tcp->outf = strace_fopen(name); 56510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 56610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 56710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 568558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkostatic void 569558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkoprocess_opt_p_list(char *opt) 570e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko{ 571e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko while (*opt) { 572e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko /* 573e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". 574e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * pidof uses space as delim, pgrep uses newline. :( 575e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko */ 576e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko int pid; 577e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char *delim = opt + strcspn(opt, ", \n\t"); 578e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char c = *delim; 579e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 580e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = '\0'; 581e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko pid = atoi(opt); /* TODO: stricter parsing of the number? */ 582e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid <= 0) { 583e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko error_msg("Invalid process id: '%s'", opt); 584e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 585e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko return; 586e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 587e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid == strace_tracer_pid) { 588e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko error_msg("I'm sorry, I can't let you do that, Dave."); 589e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 590e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko return; 591e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 592e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 59375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko alloc_tcb(pid, 0); 594e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (c == '\0') 595e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko break; 596e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko opt = delim + 1; 597e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 598e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko} 599e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 60002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 60102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 60202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 60302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 60402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 60502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 60602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 60702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 60802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 6092e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * between PTRACE_ATTACH and wait4() on SIGSTOP. 610b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 61102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 61202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 61302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 61402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 615ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 616ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 617ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 618014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko perror_msg_and_die("fork"); 619ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 620ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 621ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 62275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 62375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 62475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 625ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 626ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 627ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 628ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 629ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 63075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 63175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 63275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 633ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 634ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 63502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 63602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 63744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko 63875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!(tcp->flags & TCB_INUSE)) 63975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; 64075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 641d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Is this a process we should attach to, but not yet attached? */ 64275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (tcp->flags & TCB_ATTACHED) 64375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; /* no, we already attached it */ 644d116a7338645af45090aecc331701e999148d284Denys Vlasenko 645d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Reinitialize the output since it may have changed */ 64602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 6473d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko newoutf(tcp); 64802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 649ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 6507a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 65102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 65202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 65302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 65402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 65502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 65602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 65702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct dirent *de; 658381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 65902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath while ((de = readdir(dir)) != NULL) { 660381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko struct tcb *cur_tcp; 661381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko int tid; 662381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 6637a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 66402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 66502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 66602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 66702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 66802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 66931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tid) < 0) { 67002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 671a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 672f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 673381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko continue; 674f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 675a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 676381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 677381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = tcp; 678381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (tid != tcp->pid) 679381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = alloctcb(tid); 68031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 68102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 68202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 683381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interactive) { 684381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 685381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interrupted) 686381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko goto ret; 687381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 688381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko } 6897a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 6907a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 69102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 69202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 69302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 69402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 69502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 6967a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 6977a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko? "Process %u attached with %u threads - interrupt to quit\n" 6987a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko: "Process %u attached - interrupt to quit\n", 69944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko tcp->pid, ntid); 70002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 70175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!(tcp->flags & TCB_ATTACHED)) { 702f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* -p PID, we failed to attach to PID itself 703f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * but did attach to some of its sibling threads. 704f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Drop PID's tcp. 705f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 706f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko droptcb(tcp); 707f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 70802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 7097a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 7107a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 71131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tcp->pid) < 0) { 71202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 71302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 71402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 71502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 71675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 717a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 718f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 719ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 720ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 721ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 722ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 723ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 724ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 725ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 726ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 727ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 72802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 72902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 73002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath "Process %u attached - interrupt to quit\n", 73102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 732f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 73302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 73444f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret: 73502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 73602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 73702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 73802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 73902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 7401201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 74102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 74202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct stat statbuf; 74302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 74402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 74502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int pid = 0; 74602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 74702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 74802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 74902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 75002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 75102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 752cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 75302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 75402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 75502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 75602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 75702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 75802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 75902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 76002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 76102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 76202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 76302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 76402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 76502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 76630145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 76702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 76802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 76902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 7704f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko const char *colon = strchr(path, ':'); 7714f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko if (colon) { 7724f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko n = colon - path; 77302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 77402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 77502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 77602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 77702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 77802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 77902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 78002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 78102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 78202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 78302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 78402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 78502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 78602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 78702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 78802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 78902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 79002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 79102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0 && 79202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 79302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 79402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 79502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 79602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 79702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 79802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 79902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 80002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 801cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 80202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 803a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin strace_child = pid = fork(); 804ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 805cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 806ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 80775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 80875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 809ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 810ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid = getpid(); 8112e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (outf != stderr) 8122e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko close(fileno(outf)); 81331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!daemonized_tracer && !use_seize) { 81431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 815cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 816ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 81702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 81802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 819ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (username != NULL) { 82002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 82102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 82202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 82302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 82402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 82502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 82602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 82702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 82802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * It is important to set groups before we 82902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * lose privileges on setuid. 83002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 831ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (initgroups(username, run_gid) < 0) { 832ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("initgroups"); 833ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 834ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setregid(run_gid, run_egid) < 0) { 835ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setregid"); 836ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 837ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setreuid(run_uid, run_euid) < 0) { 838ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setreuid"); 83902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 84002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 841ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko else if (geteuid() != 0) 84202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 84302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 844ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 845ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 8462e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Induce a ptrace stop. Tracer (our parent) 847ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will resume us with PTRACE_SYSCALL and display 8482e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * the immediately following execve syscall. 8492e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Can't do this on NOMMU systems, we are after 8502e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * vfork: parent is blocked, stopping would deadlock. 851ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 852c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if (!strace_vforked) 8532e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko kill(pid, SIGSTOP); 854ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } else { 855ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko struct sigaction sv_sigchld; 856ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, NULL, &sv_sigchld); 857ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 858ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make sure it is not SIG_IGN, otherwise wait 859ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will not block. 860ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 861ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko signal(SIGCHLD, SIG_DFL); 862ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 863ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Wait for grandchild to attach to us. 864ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * It kills child after that, and wait() unblocks. 865ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 866ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(3); 867ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko wait(NULL); 868ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(0); 869ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko sigaction(SIGCHLD, &sv_sigchld, NULL); 870ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 87102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 87202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, argv); 873cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 87402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 875ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 8762e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We are the tracer */ 87775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 8782e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (!daemonized_tracer) { 87931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) { 88031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* child did PTRACE_TRACEME, nothing to do in parent */ 88131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } else { 88231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) { 88331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Wait until child stopped itself */ 88431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status; 88531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (waitpid(pid, &status, WSTOPPED) < 0) { 88631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 88731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 88831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("waitpid"); 88931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 89031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 89175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 89231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Unexpected wait status %x", status); 89331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 89431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 89531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Else: vforked case, we have no way to sync. 89631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * Just attach to it as soon as possible. 89731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This means that we may miss a few first syscalls... 89831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 89931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 90031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(pid)) { 90175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 90231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Can't attach to %d", pid); 90331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 90431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) 90531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGCONT); 90631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 9072e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 908f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!strace_vforked) 90975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop; 910f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko else 91175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP; 9122e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko } 9132e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko else { 9142e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 9152e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko strace_tracer_pid = getpid(); 9162e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* The tracee is our parent: */ 9172e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko pid = getppid(); 918f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko alloctcb(pid); 919f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko /* attaching will be done later, by startup_attach */ 920ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 92102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 92202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 923b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 924b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 925b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 926b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 927b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 92804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void 9293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 930b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 9312fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 9322fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 9332fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 9342fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 935b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 9365d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = fork(); 9375d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid < 0) 93804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 9395d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid == 0) { 94004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin pid = getpid(); 94131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 94204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 94304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 9444c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGSTOP); 94504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (fork() < 0) 94604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 94704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin _exit(0); 948b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 949b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 950b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 951b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 952b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 95304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = 0; 954b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 95504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid <= 0) { 956b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 957b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 9584c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko if (errno == ECHILD) 959b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 96004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 96104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 96204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 96304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 96404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFEXITED(status)) { 96504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WEXITSTATUS(status)) { 96604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 96704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 96804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 96904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 97004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 97104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 97204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 97304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 97404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 97504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 97604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 97704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 97804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 97904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (!WIFSTOPPED(status)) { 98004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 98104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 9824c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGKILL); 98304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 98404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 985b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 986b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 9872fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 98804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 98904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 99004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 99104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_CONT doesn't work"); 99204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 99304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 994b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 99504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin switch (WSTOPSIG(status)) { 99604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGSTOP: 99704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 99804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 99904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 100004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 100104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGTRAP: 100204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 100304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin long msg = 0; 10042fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 100504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 100604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin NULL, (long) &msg) == 0) 100704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin expected_grandchild = msg; 1008b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 100904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 101004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 101104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 101204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 101304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1014b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 1015b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 101604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) { 1017f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1018a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 101904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin fprintf(stderr, "ptrace_setoptions = %#x\n", 102004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin ptrace_setoptions); 102104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin return; 102204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 102304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACECLONE failed, " 102404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 1025b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 10263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10273454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 10283454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 10293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 10303454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 10313454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 10323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 10333454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 10343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * _start: .globl _start 10353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int3 10363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $42, %ebx 10373454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $1, %eax 10383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int $0x80 10393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 10403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 10413454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkostatic void 10423454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 10433454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 104404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 104504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin PTRACE_O_TRACEEXEC; 10463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 10473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 10483454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 10503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 105175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 10523454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 10543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 10553454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 105675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 105704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 105804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 10593454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 10603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 10613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10623454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10633454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 10643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 10653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 10673454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 10683454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 10693454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 10703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 107104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 107204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 107304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 107475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 107575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 107675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 107775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 107804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 107904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 108004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 108104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 108204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 108304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 10843454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10853454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 10863454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 108704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 108804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 10893454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10903454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 10913454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 10923454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 10933454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 10943454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 10953454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 10963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 109704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 109804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 109904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 11003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11013454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 11023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 11033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 110504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 110675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 11073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11083454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11093454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 11103454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 111175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 1112f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1113a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1114f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 1115f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 11163454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko return; 11173454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 111904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 112004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 11213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 112231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 112331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# ifdef USE_SEIZE 112431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic void 112531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotest_ptrace_seize(void) 112631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 112731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int pid; 112831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 112931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pid = fork(); 113031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid < 0) 113131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("fork"); 113231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 113331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid == 0) { 113431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pause(); 113531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko _exit(0); 113631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 113731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 113831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 113931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * attaching tracee continues to run unless a trap condition occurs. 114031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * PTRACE_SEIZE doesn't affect signal or group stop state. 114131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 114231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 114331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1144a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko } else if (debug_flag) { 114531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 114631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 114731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 114831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 114931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 115031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (1) { 115131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status, tracee_pid; 115231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 115331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko errno = 0; 115431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tracee_pid = waitpid(pid, &status, 0); 115531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (tracee_pid <= 0) { 115631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 115731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 115831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("%s: unexpected wait result %d", 115931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, tracee_pid); 116031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 116131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (WIFSIGNALED(status)) { 116231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return; 116331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 116431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko error_msg_and_die("%s: unexpected wait status %x", 116531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, status); 116631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 116731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 116831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# else /* !USE_SEIZE */ 116931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define test_ptrace_seize() ((void)0) 117031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# endif 117131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 1172ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkostatic void 1173f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkoget_os_release(void) 1174f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko{ 1175f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct utsname u; 1176f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (uname(&u) < 0) 1177f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko perror_msg_and_die("uname"); 1178f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko os_release = strdup(u.release); 1179f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (!os_release) 1180f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko die_out_of_memory(); 1181f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko} 1182f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1183ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko/* 1184ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Initialization part of main() was eating much stack (~0.5k), 1185ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * which was unused after init. 1186ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * We can reuse it if we move init code into a separate function. 1187ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * 1188ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Don't want main() to inline us and defeat the reason 1189ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * we have a separate function. 1190ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko */ 1191ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkostatic void __attribute__ ((noinline)) 1192ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoinit(int argc, char *argv[]) 119376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 119476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 1195e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko int c; 119606350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 119776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 119876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 119908b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 120008b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 120175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 120275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 1203f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko get_os_release(); 1204f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1205ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 1206ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 12074f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 12081d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcbtab) 12091d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 12104f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 12111d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcp) 12121d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 12134f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 12144f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 1215ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 121676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 1217138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 1218138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 121976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 122276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 122376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 122461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko "+bcCdfFhiqrtTvVxyz" 1225ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 1226b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 122776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 122861e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko case 'b': 122961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko detach_on_execve = 1; 123061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko break; 123176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 1232e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 1233cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1234e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1235e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 1236e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 1237e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 1238e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 1239cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1240e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1241e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 124276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 124376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 1244a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko debug_flag = 1; 124576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1246ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 1247ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 1248ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 124941c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 125006350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 125106350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 125276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 125876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 1259a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko iflag = 1; 126076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 1262a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko qflag = 1; 126376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 126476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 1265a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko rflag = 1; 1266a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko /* fall through to tflag++ */ 126776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 126876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 126976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 127076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 1271a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko Tflag = 1; 127276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 127376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 127476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 127576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 12768a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 12778a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 12788a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 128076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 128176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 128276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 12839c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 128476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 128576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 128617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 128717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 128817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 1291102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (acolumn < 0) 1292102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko error_msg_and_die("Bad column width '%s'", optarg); 129376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 129676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 129976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 130076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 1304e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko process_opt_p_list(optarg); 130576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 13068a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 13078a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tracing_paths = 1; 13088a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (pathtrace_select(optarg)) { 1309cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Failed to select path '%s'", optarg); 13108a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards } 13118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 131276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 1314dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (max_strlen < 0) { 1315b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1316dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 131776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 132076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 132176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 132276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1324de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 13251d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (putenv(optarg) < 0) 13261d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1327de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 1328b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko case 'I': 1329b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = atoi(optarg); 1330b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1331b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1332b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1333b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko break; 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 133876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1339837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko argv += optind; 1340837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* argc -= optind; - no need, argc is not used below */ 134176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1342102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces = malloc(acolumn + 1); 1343102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (!acolumn_spaces) 13441d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1345102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko memset(acolumn_spaces, ' ', acolumn); 1346102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces[acolumn] = '\0'; 1347102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko 1348837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* Must have PROG [ARGS], or -p PID. Not both. */ 1349fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (!argv[0] == !nprocs) 1350ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1351ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1352fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 && daemonized_tracer) { 1353cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-D and -p are mutually exclusive options"); 1354d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1355d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 135606350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 135706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 135806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 1359cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (followfork > 1 && cflag) { 1360cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1361cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1362cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 136376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 136476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 136576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 136676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 136776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1368cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 13705d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pent = getpwnam(username); 13715d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pent == NULL) { 1372cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 137376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 137676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 137876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 137976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 138076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 138176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 138204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (followfork) 138304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin test_ptrace_setoptions_followfork(); 13843454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko test_ptrace_setoptions_for_all(); 138531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko test_ptrace_seize(); 13868044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 138776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 138876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 138937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 139037b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 139137b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 139237b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 139337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 139437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 13957dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (followfork > 1) 13967dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 13977dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko outf = strace_popen(outfname + 1); 139854b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 13993d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko else if (followfork <= 1) 14003d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko outf = strace_fopen(outfname); 1401328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko } else { 1402328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko /* -ff without -o FILE is the same as single -f */ 1403328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko if (followfork > 1) 1404328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko followfork = 1; 140576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 140676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1407cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1408a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko char *buf = malloc(BUFSIZ); 1409a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko if (!buf) 1410a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko die_out_of_memory(); 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 1412cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 1413837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (outfname && argv[0]) { 1414b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1415b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_NEVER; 141676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1417369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1418b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1419b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_WHILE_WAIT; 1420b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1421b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* argv[0] -pPID -oFILE Default interactive setting 1422b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 0 INTR_WHILE_WAIT 1423b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 0 INTR_WHILE_WAIT 1424b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 1 INTR_NEVER 1425b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 1 INTR_WHILE_WAIT 142654cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 142754cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 142854cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* STARTUP_CHILD must be called before the signal handlers get 142954cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath installed below as they are inherited into the spawned process. 143054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Also we do not need to be protected by them as during interruption 143154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath in the STARTUP_CHILD mode we kill the spawned process anyway. */ 143261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (argv[0]) { 143361e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko skip_startup_execve = 1; 1434837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko startup_child(argv); 143561e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 143676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 143776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 143876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 144176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 1442b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1443b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1444b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr != INTR_ANYWHERE) { 1445b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_BLOCK_TSTP_TOO) 1446b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1447b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* 1448b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In interactive mode (if no -o OUTFILE, or -p PID is used), 1449b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * fatal signals are blocked while syscall stop is processed, 1450b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * and acted on in between, when waiting for new syscall stops. 1451b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In non-interactive mode, signals are ignored. 1452b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko */ 1453b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_WHILE_WAIT) { 1454b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGHUP); 1455b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGINT); 1456b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGQUIT); 1457b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGPIPE); 1458b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGTERM); 1459b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sa.sa_handler = interrupt; 1460b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1461b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* SIG_IGN, or set handler for these */ 1462b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGHUP, &sa, NULL); 1463b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGINT, &sa, NULL); 1464b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGQUIT, &sa, NULL); 1465b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGPIPE, &sa, NULL); 1466b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTERM, &sa, NULL); 146776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1468553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath /* Make sure SIGCHLD has the default action so that waitpid 1469553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath definitely works without losing track of children. The user 1470553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath should not have given us a bogus state to inherit, but he might 1471553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath have. Arguably we should detect SIG_IGN here and pass it on 1472553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath to children, but probably noone really needs that. */ 1473553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sa.sa_handler = SIG_DFL; 1474553a609807074e95eed5a0bffba334b7fb3d3751Roland McGrath sigaction(SIGCHLD, &sa, NULL); 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1476fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 || daemonized_tracer) 147702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 147802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 1479fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko /* Do we want pids printed in our -o OUTFILE? 1480fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -ff: no (every pid has its own file); or 1481fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -f: yes (there can be more pids in the future); or 1482fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -p PID1,PID2: yes (there are already more than one pid) 1483fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko */ 1484fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1)); 148576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 148676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 14872b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic void 1488418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoexpand_tcbtab(void) 14897b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 14907b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath /* Allocate some more TCBs and expand the table. 14917b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath We don't want to relocate the TCBs because our 14927b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath callers have pointers and it would be a pain. 14937b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath So tcbtab is a table of pointers. Since we never 14947b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath free the TCBs, we allocate a single chunk of many. */ 149518da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko int i = tcbtabsize; 149618da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 149718da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 14981d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!newtab || !newtcbs) 14991d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 15007b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtabsize *= 2; 15017b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtab = newtab; 150218da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko while (i < tcbtabsize) 150318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko tcbtab[i++] = newtcbs++; 15047b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath} 15057b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 150676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 150710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinalloc_tcb(int pid, int command_options_parsed) 150876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 150976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 151076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1512418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (nprocs == tcbtabsize) 1513418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko expand_tcbtab(); 1514418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1515ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1516ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 151776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 151818da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 151976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 1520381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko tcp->flags = TCB_INUSE; 152176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 1522a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#if SUPPORTED_PERSONALITIES > 1 1523a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin tcp->currpers = current_personality; 1524a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#endif 152576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 1526a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 15271d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 152810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (command_options_parsed) 152910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newoutf(tcp); 153076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 153176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 153318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("bug in alloc_tcb"); 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1536eebb04d4ae8bf4b08a041f5ea442ca24c90692c2Denys Vlasenkostatic struct tcb * 153754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 153876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 153976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 154054e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 154154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 154254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1544ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 154554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 154654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 154876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 154954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 155076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 155276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 155376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15541201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodroptcb(struct tcb *tcp) 155576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 155819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko 155976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 1560a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 15611d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1562eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 15633e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (tcp->outf) { 15643e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (outfname && followfork >= 2) { 15653e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (tcp->curcol != 0) 15663e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 15673e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fclose(tcp->outf); 15683e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (outf == tcp->outf) 15693e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko outf = NULL; 15703e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } else { 15713e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (printing_tcp == tcp && tcp->curcol != 0) 15723e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 15733e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fflush(tcp->outf); 15743e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } 15753e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } 15763e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko 15777de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (printing_tcp == tcp) 15787de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = NULL; 15797de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 158019cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko memset(tcp, 0, sizeof(*tcp)); 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15830a463880341945df08b6dc79134dc78cc38dc283Roland McGrath/* detach traced process; continue with sig 158475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * Never call DETACH twice on the same process as both unattached and 158575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * attached-unstopped processes give the same ESRCH. For unattached process we 158675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * would SIGSTOP it and wait for its SIGSTOP notification forever. 158775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko */ 158876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 15894c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkodetach(struct tcb *tcp) 159076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 159175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int error; 159275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int status, sigstop_expected; 159376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 1595840d85b3e50cea9f28aedd23af94742c2a60265aAndreas Schwab clearbpt(tcp); 159676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 159776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 159876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 15997bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 16007bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 160176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 16027bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 16037bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 16047bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 16057bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 160675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 16073e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko error = 0; 160875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = 0; 160975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (tcp->flags & TCB_ATTACHED) { 161075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* 161175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * We attached but possibly didn't see the expected SIGSTOP. 161275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * We must catch exactly one as otherwise the detached process 161375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * would be left stopped (process state T). 161475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko */ 161575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 161675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 161775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (error == 0) { 161875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* On a clear day, you can see forever. */ 161975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 162075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (errno != ESRCH) { 162175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* Shouldn't happen. */ 162275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: ptrace(PTRACE_DETACH, ...)"); 162375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 162475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (my_tkill(tcp->pid, 0) < 0) { 162575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (errno != ESRCH) 162675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: checking sanity"); 162775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 162875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) { 162975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (errno != ESRCH) 163075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: stopping child"); 163175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 163275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else 163375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = 1; 16347bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 163575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 163675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (sigstop_expected) { 163776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 16387508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 163937ab4b79de57c1657e41f96a96fa699a08194a80Denys Vlasenko if (waitpid(tcp->pid, &status, __WALL) < 0) { 16407508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 16417508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16427508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 164376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 16447508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16457508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16467508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 16477508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 16487508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 16497508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 16507508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16517508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16527508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16537508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 16547508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 165537ab4b79de57c1657e41f96a96fa699a08194a80Denys Vlasenko if (waitpid(tcp->pid, &status, __WCLONE) < 0) { 16567508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 16577508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16587508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16597508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16607508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 16617508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16627508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16647508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 166576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 166676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 16704c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, 0); 167176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 167276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1673732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, 167475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko WSTOPSIG(status) == syscall_trap_sig ? 0 1675732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko : WSTOPSIG(status)); 1676732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (error < 0) 167776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 167876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1679ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } 168076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!qflag && (tcp->flags & TCB_ATTACHED)) 168276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 168376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 1685a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath 168676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 168776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 16901201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 16943521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko int fatal_sig; 16953521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko 16963521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko /* 'interrupted' is a volatile object, fetch it only once */ 16973521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = interrupted; 16983521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko if (!fatal_sig) 16993521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = SIGTERM; 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1701ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1702ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1705a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 170776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 17087de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (tcp->flags & TCB_STRACE_CHILD) { 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 1710a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko kill(tcp->pid, fatal_sig); 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17127de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko detach(tcp); 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 171676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 17191201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 1721a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko interrupted = sig; 172276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 172376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRERROR 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17266d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#if !HAVE_DECL_SYS_ERRLIST 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern int sys_nerr; 172876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanextern char *sys_errlist[]; 17296d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrath#endif /* HAVE_DECL_SYS_ERRLIST */ 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 17321201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrerror(int err_no) 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17341945ccc3fbd5b56008c4a6b0cdd4611616201675Denys Vlasenko static char buf[sizeof("Unknown error %d") + sizeof(int)*3]; 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 173635aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 173735aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko sprintf(buf, "Unknown error %d", err_no); 173876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174035aba6a8dd87a8d1fd69110d80f98224d1f5b18dDenys Vlasenko return sys_errlist[err_no]; 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STERRROR */ 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifndef HAVE_STRSIGNAL 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17478f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS_SIGLIST && !defined HAVE_DECL_SYS_SIGLIST 17486d2b34971b33d379c89c36c5ad1b0c6d5d12c453Roland McGrathextern char *sys_siglist[]; 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 17508f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#if defined HAVE_SYS__SIGLIST && !defined HAVE_DECL__SYS_SIGLIST 17518f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrathextern char *_sys_siglist[]; 17528f474e087ebb77b57eb87f4fdc557d53c64ca933Roland McGrath#endif 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanconst char * 17551201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostrsignal(int sig) 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 17571945ccc3fbd5b56008c4a6b0cdd4611616201675Denys Vlasenko static char buf[sizeof("Unknown signal %d") + sizeof(int)*3]; 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (sig < 1 || sig >= NSIG) { 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sprintf(buf, "Unknown signal %d", sig); 176176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return buf; 176276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 176376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE__SYS_SIGLIST 176476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return _sys_siglist[sig]; 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#else 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return sys_siglist[sig]; 176776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 176976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#endif /* HAVE_STRSIGNAL */ 177176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 17731201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 177476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 177576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 177626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko struct rusage *rup = cflag ? &ru : NULL; 177726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 1778eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath static int wait4_options = __WALL; 177926d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1781eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath while (nprocs != 0) { 1782f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int pid; 1783f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int wait_errno; 1784f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int status, sig; 178531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int stopped; 1786f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *tcp; 1787f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko unsigned event; 1788f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1789222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 1790eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 1791eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 1792eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 179326d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 179426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 17955bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 17962f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 17972f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 179826d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 17992f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 18005bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 18012f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 180226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, __WCLONE, rup); 180326d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 1804cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg("wait4(__WCLONE) failed"); 18052f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 18062f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 180726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# else 180826d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, 0, rup); 180926d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif /* __WALL */ 181076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 1811eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 1812eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 181376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 181426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 1815eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath switch (wait_errno) { 1816eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case EINTR: 181776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1818eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case ECHILD: 181976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 182076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 182176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 182276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 182376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 182476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1825eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 1826eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath default: 1827eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = wait_errno; 18284c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("wait"); 1829eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 183076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 183210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 183310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (WIFEXITED(status) || WIFSIGNALED(status)) 18347dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 183510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 183610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 1837f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1838f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko event = ((unsigned)status >> 16); 1839a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) { 18401d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 184167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16]; 18421d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 18431d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 18441d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 18451d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 18461d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 18471d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 18481d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 18491d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 18501d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 18511d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 18521d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 18531d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 18541d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 18551d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 18565bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 18571d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 18581d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 18595bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 186067559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko evbuf[0] = '\0'; 186167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event != 0) { 186267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko static const char *const event_names[] = { 186367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 186467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 186567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 186667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 186767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 186867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 186967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko }; 187067559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko const char *e; 187167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event < ARRAY_SIZE(event_names)) 187267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko e = event_names[event]; 187367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko else { 187467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko sprintf(buf, "?? (%u)", event); 187567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko e = buf; 187667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko } 187767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko sprintf(evbuf, ",PTRACE_EVENT_%s", e); 187867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko } 187967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf); 18801d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 188176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1882f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Look up 'pid' in our table. */ 18835d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pid2tcb(pid); 1884f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1885f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Under Linux, execve changes pid to thread leader's pid, 1886f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and we see this changed pid on EVENT_EXEC and later, 1887f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * execve sysexit. Leader "disappears" without exit 1888f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * notification. Let user know that, drop leader's tcb, 1889f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and fix up pid in execve thread's tcb. 1890f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * Effectively, execve thread's tcb replaces leader's tcb. 1891f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 1892f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 1893f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * on exit syscall) in multithreaded programs exactly 1894f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * in order to handle this case. 1895f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 1896f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 1897f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * On 2.6 and earlier, it can return garbage. 1898f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko */ 1899f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event == PTRACE_EVENT_EXEC && os_release[0] >= '3') { 1900f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko long old_pid = 0; 1901f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 1902f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid > 0 1903f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid != pid 1904f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko ) { 1905f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *execve_thread = pid2tcb(old_pid); 1906f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 1907f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko outf = tcp->outf; 1908f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko curcol = tcp->curcol; 1909f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (execve_thread) { 19107de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (execve_thread->curcol != 0) { 19117de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* 19127de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * One case we are here is -ff: 19137de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * try "strace -oLOG -ff test/threaded_execve" 19147de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 19157de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid); 19167de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko execve_thread->curcol = 0; 19177de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 1918f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* swap output FILEs (needed for -ff) */ 1919f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->outf = execve_thread->outf; 19207de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = execve_thread->curcol; 1921f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko execve_thread->outf = outf; 19227de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko execve_thread->curcol = curcol; 1923f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1924f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko droptcb(tcp); 1925f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1926f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp = execve_thread; 1927f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 1928f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->pid = pid; 1929f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->flags |= TCB_REPRINT; 19307de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (!cflag) { 19317de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printleader(tcp); 19327de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 19337de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 19347de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 1935f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1936f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1937f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1938f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 193961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (event == PTRACE_EVENT_EXEC && detach_on_execve) { 194061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (!skip_startup_execve) 194161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko detach(tcp); 194261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko /* This was initial execve for "strace PROG". Skip. */ 194361e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko skip_startup_execve = 0; 194461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 194561e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko 19465d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 194741c48227a86a176da333f713d5047240885f25ccRoland McGrath if (followfork) { 1948e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 1949e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 1950e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 1951e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 1952e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 1953e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 1954e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 1955e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 1956e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 1957418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloctcb(pid); 195831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 1959e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 1960833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko fprintf(stderr, "Process %d attached\n", 1961e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 19628b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1963e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 1964e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 1965e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 1966e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 1967e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 196897c503fa2e9cd02126feae659f133631c8eb36f1Denys Vlasenko ptrace(PTRACE_CONT, pid, (char *) 0, 0); 1969cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Unknown pid: %u", pid); 1970e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 197176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19727de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 19737de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* Set current output file */ 1974eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath outf = tcp->outf; 1975ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 19767de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 197713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1981eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 198276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 1983a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 1984a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 1985e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 198676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 198813d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 1989000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s %s+++\n", 19902efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 199113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 199213d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 1993000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s +++\n", 199413d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 19952efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 19967de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 200176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 2002a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2003a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 200419cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 200519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 2006000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 20077de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 200819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 201476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 201676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2018f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this the very first time we see this tracee stopped? */ 2019f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (tcp->flags & TCB_STARTUP) { 2020a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2021f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 202302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 202502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 20262ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * parent through fork(). 202776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 20286cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (clearbpt(tcp) < 0) { 20296cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko /* Pretty fatal */ 203076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 203176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 203544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace_setoptions) { 2036a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 203744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 203844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 203944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (errno != ESRCH) { 204044f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko /* Should never happen, really */ 204144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 20423454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 20433454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 20443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2045f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2046f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 204731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko sig = WSTOPSIG(status); 204831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 2049f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event != 0) { 205031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Ptrace event */ 205131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 205231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 20536703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko /* 20546703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop or group-stop. 20556703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 20566703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko */ 205731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (sig == SIGSTOP 205831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTSTP 205931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTIN 206031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTOU 206131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko ) { 206231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = 1; 206331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto show_stopsig; 206431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 206531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 206631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 2067f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko goto restart_tracee_with_sig_0; 2068f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2069f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2070f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this post-attach SIGSTOP? 2071f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Interestingly, the process may stop 2072f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * with STOPSIG equal to some other signal 2073f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * than SIGSTOP if we happend to attach 2074f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * just before the process takes a signal. 2075f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 2076f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2077a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2078f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2079f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 20806cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee_with_sig_0; 208176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 208276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20836cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (sig != syscall_trap_sig) { 208431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko siginfo_t si; 208531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 208631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Nonzero (true) if tracee is stopped by signal 208731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (as opposed to "tracee received signal"). 208831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 208931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 20906703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#ifdef USE_SEIZE 209131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko show_stopsig: 20926703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#endif 2093e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 20946cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko && (qual_flags[sig] & QUAL_SIGNAL)) { 2095c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 20966b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long pc = 0; 20976b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long psr = 0; 20987b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2099932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IPSR, &psr); 2100932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IIP, &pc); 21017b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 21026b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PSR_RI 41 21037b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 21046b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR " @ %lx" 21052ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG , pc 21066b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin#else 21072ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_STR "" 21082ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG /* nothing */ 21097b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 211076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 211131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) { 211260fe8c139c6f2febefe595781812ddf0864a6ab8Denys Vlasenko tprints("--- "); 21136b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin printsiginfo(&si, verbose(tcp)); 2114000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf(" (%s)" PC_FORMAT_STR " ---\n", 21156cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig) 21166b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 21176b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin } else 2118000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("--- %s by %s" PC_FORMAT_STR " ---\n", 21196cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko strsignal(sig), 21206cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko signame(sig) 21216b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 21227de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 212376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 212431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 212531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) 212631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's signal-delivery-stop. Inject the signal */ 212731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto restart_tracee; 212831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 212931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's group-stop */ 213031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 213131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (use_seize) { 213231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* 213331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This ends ptrace-stop, but does *not* end group-stop. 213431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This makes stopping signals work properly on straced process 213531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (that is, process really stops. It used to continue to run). 213631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 213731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 213831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cleanup(); 213931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return -1; 214031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 21417de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = curcol; 214231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 214331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 214431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* We don't have PTRACE_LISTEN support... */ 214531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 21466cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee; 214776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21482ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 21492ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* We handled quick cases, we are permitted to interrupt now. */ 215002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 215102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return 0; 21522ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 21532ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* This should be syscall entry or exit. 21542ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * (Or it still can be that pesky post-execve SIGTRAP!) 21552ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * Handle it. 21562ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko */ 2157eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2158eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* ptrace() failed in trace_syscall() with ESRCH. 2159eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2160eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Observed case: exit_group() terminating 2161f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * all processes in thread group. 21627de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * We assume that ptrace error was caused by process death. 2163f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * We used to detach(tcp) here, but since we no longer 2164f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * implement "detach before death" policy/hack, 2165f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * we can let this process to report its death to us 2166f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * normally, via WIFEXITED or WIFSIGNALED wait status. 2167f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko */ 21687de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = curcol; 216976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 217076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21716cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0: 21726cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko sig = 0; 21736cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee: 2174ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2175ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 21766cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 217776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 217876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 217976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 218176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 218276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 2183ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2184ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoint 2185ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkomain(int argc, char *argv[]) 2186ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko{ 2187ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko init(argc, argv); 2188ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2189ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Run main tracing loop */ 2190ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko if (trace() < 0) 2191ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko return 1; 2192ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2193ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko cleanup(); 2194ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko fflush(NULL); 2195ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko if (exit_code > 0xff) { 2196ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Avoid potential core file clobbering. */ 2197ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko struct rlimit rlim = {0, 0}; 2198ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko setrlimit(RLIMIT_CORE, &rlim); 2199ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2200ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Child was killed by a signal, mimic that. */ 2201ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code &= 0xff; 2202ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko signal(exit_code, SIG_DFL); 2203ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko raise(exit_code); 2204ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Paranoia - what if this signal is not fatal? 2205ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko Exit with 128 + signo then. */ 2206ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code += 128; 2207ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko } 2208ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2209ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko return exit_code; 2210ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko} 2211