strace.c revision a509054aeee00a89a2250919f74bd849c67ded61
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 1476e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenkostatic unsigned os_release; /* generated from uname()'s u.release */ 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 1612c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#ifndef HAVE_STRERROR 1622c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1632c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#if !HAVE_DECL_SYS_ERRLIST 1642c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern int sys_nerr; 1652c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern char *sys_errlist[]; 1662c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#endif /* HAVE_DECL_SYS_ERRLIST */ 1672c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1682c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoconst char * 1692c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkostrerror(int err_no) 1702c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko{ 1712c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko static char buf[sizeof("Unknown error %d") + sizeof(int)*3]; 1722c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1732c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 1742c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko sprintf(buf, "Unknown error %d", err_no); 1752c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko return buf; 1762c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko } 1772c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko return sys_errlist[err_no]; 1782c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko} 1792c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1802c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#endif /* HAVE_STERRROR */ 1812c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 18276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 183cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 18476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 18576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 186b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkousage: strace [-CdDffhiqrtttTvVxxy] [-I n] [-a column] [-e expr]... [-o file]\n\ 187b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko [-p pid]... [-s strsize] [-u username] [-E var=val]...\n\ 188cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko [-P path] [PROG [ARGS]]\n\ 189b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko or: strace -c [-D] [-I n] [-e expr]... [-O overhead] [-S sortby] [-E var=val]...\n\ 190cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko [PROG [ARGS]]\n\ 19176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 192b87d30c785679b37a2ec7242881f0d0b819c738dAndreas Schwab-C -- like -c but also print regular output while processes are running\n\ 1933e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-d -- enable debug output to stderr\n\ 194b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 19576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 1963e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-F -- attempt to follow vforks (deprecated, use -f)\n\ 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 198b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-I interruptible\n\ 199b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1: no signals are blocked\n\ 200b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 2: fatal signals are blocked while decoding syscall (default)\n\ 201b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 202b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 203b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 20476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 20576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 206cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-T -- print time spent in each syscall\n\ 207cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 20876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 2098a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 210cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-h -- print help message\n\ 211cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-V -- print version\n\ 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman options: trace, abbrev, verbose, raw, signal, read, or write\n\ 21576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 21676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 21876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 21976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 221de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 222de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2238a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 22461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko" 22561e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* this is broken, so don't document it 22617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 22761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */ 22861e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* experimental, don't document it yet (option letter may change in the future!) 22961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko-b -- detach on successful execve\n\ 23061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */ 231de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 23675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 23775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 23875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 23975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 24075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 24175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 24275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 24375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 24475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 24575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 24782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko char *msg; 24882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 24944d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 25082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 25182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We want to print entire message with single fprintf to ensure 25282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * message integrity if stderr is shared with other programs. 25382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * Thus we use vasprintf + single fprintf. 25482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko */ 25582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko msg = NULL; 256cfad543087d98c5313fd7f006c0de69a1d87dc8eDenys Vlasenko if (vasprintf(&msg, fmt, p) >= 0) { 25782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 25882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 25982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 26082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s\n", progname, msg); 26182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko free(msg); 26282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } else { 26382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* malloc in vasprintf failed, try it without malloc */ 26482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: ", progname); 26582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vfprintf(stderr, fmt, p); 26682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 26782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, ": %s\n", strerror(err_no)); 26882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 26982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko putc('\n', stderr); 27082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } 27182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We don't switch stderr to buffered, thus fprintf(stderr) 27282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * always flushes its output and this is not necessary: */ 27382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* fflush(stderr); */ 27475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 27575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 27675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 27775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 27875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 27975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 28075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 2813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 28275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 2833454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 28475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 28575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 28675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 28775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 28875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 28975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 29075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 29175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 29275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 29375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 29475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 29575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 29675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 29775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 29875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 29975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 30075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 30175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 30275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 30375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 30475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 30575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 3063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 3073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 3081d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void) 3091d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{ 3101d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko static bool recursed = 0; 3111d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (recursed) 3121d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko exit(1); 3131d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko recursed = 1; 3141d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko error_msg_and_die("Out of memory"); 3151d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko} 3161d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 317c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger/* Glue for systems without a MMU that cannot provide fork() */ 318c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#ifdef HAVE_FORK 319c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 0 320c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#else 321c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define strace_vforked 1 322c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger# define fork() vfork() 323c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger#endif 324c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger 32531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 32631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int 32731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkoptrace_attach_or_seize(int pid) 32831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 32931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int r; 33031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) 33131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return ptrace(PTRACE_ATTACH, pid, 0, 0); 33231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL); 33331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (r) 33431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 33531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko r = ptrace(PTRACE_INTERRUPT, pid, 0, 0); 33631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 33731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 33831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 33931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 34031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 34131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 3421f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 34310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 34410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 3451f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 3461f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 3471f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 3481f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 3491f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 3501f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 3511f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 3521f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 3531f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 3541f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 35510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 35610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 35710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 35810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 3591f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 36010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 3611f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 36210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 36310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 36475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenkostatic void kill_save_errno(pid_t pid, int sig) 36575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko{ 36675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int saved_errno = errno; 36775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 36875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko (void) kill(pid, sig); 36975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko errno = saved_errno; 37075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko} 37175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 3722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 3732e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprintf(const char *fmt, ...) 3742e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 3752e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_list args; 3762e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 3772e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_start(args, fmt); 3782e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf) { 3792e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko int n = vfprintf(outf, fmt, args); 3802e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n < 0) { 3812e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf != stderr) 3822e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko perror(outfname == NULL 3832e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko ? "<writing to pipe>" : outfname); 3842e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } else 3852e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol += n; 3862e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 3872e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_end(args); 3882e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 3892e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 3902e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 3912e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprints(const char *str) 3922e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 3932e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf) { 3942e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko int n = fputs(str, outf); 3952e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n >= 0) { 3962e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol += strlen(str); 3972e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko return; 3982e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 3992e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (outf != stderr) 4002e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko perror(outfname == NULL 4012e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko ? "<writing to pipe>" : outfname); 4022e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4032e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 4042e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4052e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 4067de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkoline_ended(void) 4077de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko{ 4087de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko curcol = 0; 4097de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko fflush(outf); 4107de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (!printing_tcp) 4117de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko return; 4127de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 4137de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = NULL; 4147de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko} 4157de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 4167de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkovoid 4172e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkoprintleader(struct tcb *tcp) 4182e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 4197de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* If -ff, "previous tcb we printed" is always the same as current, 4207de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * because we have per-tcb output files. 4217de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 4227de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (followfork >= 2) 4237de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = tcp; 4247de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 4252e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp) { 4267de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko outf = printing_tcp->outf; 4277de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko curcol = printing_tcp->curcol; 4282e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp->ptrace_errno) { 4292e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp->flags & TCB_INSYSCALL) { 4302e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(" <unavailable>) "); 4312e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tabto(); 4322e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4332e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints("= ? <unavailable>\n"); 4342e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printing_tcp->ptrace_errno = 0; 4357de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 4367de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 4377de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) { 4387de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* 4397de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 1: we have a shared log (i.e. not -ff), and last line 4407de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * wasn't finished (same or different tcb, doesn't matter). 4417de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 2: split log, we are the same tcb, but our last line 4427de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * didn't finish ("SIGKILL nuked us after syscall entry" etc). 4437de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 4442e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(" <unfinished ...>\n"); 4457de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->flags |= TCB_REPRINT; 4467de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 4472e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4492e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printing_tcp = tcp; 4517de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko outf = tcp->outf; 4522e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko curcol = 0; 4532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4542e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (print_pid_pfx) 4552e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%-5d ", tcp->pid); 4562e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (nprocs > 1 && !outfname) 4572e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("[pid %5u] ", tcp->pid); 4582e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4592e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag) { 4602e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko char str[sizeof("HH:MM:SS")]; 4612e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko struct timeval tv, dtv; 4622e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko static struct timeval otv; 4632e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4642e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko gettimeofday(&tv, NULL); 4652e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (rflag) { 4662e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (otv.tv_sec == 0) 4672e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 4682e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tv_sub(&dtv, &tv, &otv); 4692e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%6ld.%06ld ", 4702e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) dtv.tv_sec, (long) dtv.tv_usec); 4712e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 4722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4732e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (tflag > 2) { 4742e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%ld.%06ld ", 4752e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) tv.tv_sec, (long) tv.tv_usec); 4762e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4772e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else { 4782e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko time_t local = tv.tv_sec; 4792e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko strftime(str, sizeof(str), "%T", localtime(&local)); 4802e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag > 1) 4812e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s.%06ld ", str, (long) tv.tv_usec); 4822e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else 4832e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s ", str); 4842e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4852e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 4862e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (iflag) 4872e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printcall(tcp); 4882e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 4892e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 4902e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 4912e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotabto(void) 4922e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 4932e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (curcol < acolumn) 4942e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(acolumn_spaces + curcol); 4952e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 4962e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 49710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 49810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * When strace is setuid executable, we have to swap uids 49910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * before and after filesystem and process management operations. 50010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 50110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 50210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinswap_uid(void) 50310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 50410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin int euid = geteuid(), uid = getuid(); 50510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5067b609d5ba0852e6c56ba311350ebd4412361777bDenys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 507cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("setreuid"); 50810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 50910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 51010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5114bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#if _LFS64_LARGEFILE 5124bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen64 5134bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#else 5144bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath# define fopen_for_output fopen 5154bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath#endif 5164bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 51710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 5183d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostrace_fopen(const char *path) 51910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 52010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin FILE *fp; 52110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 52210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 5233d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko fp = fopen_for_output(path, "w"); 5243d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko if (!fp) 5253d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 52610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 5273d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko set_cloexec_flag(fileno(fp)); 52810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin return fp; 52910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 53010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5317dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenkostatic int popen_pid = 0; 53210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 53310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#ifndef _PATH_BSHELL 53410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin# define _PATH_BSHELL "/bin/sh" 53510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin#endif 53610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 53710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin/* 53810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * We cannot use standard popen(3) here because we have to distinguish 53910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * popen child process from other processes we trace, and standard popen(3) 54010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin * does not export its child's pid. 54110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 54210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic FILE * 54310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstrace_popen(const char *command) 54410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 5457dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko FILE *fp; 5467dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko int fds[2]; 54710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 54810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin swap_uid(); 54910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pipe(fds) < 0) 5507dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("pipe"); 55110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5527dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 55310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5547dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = vfork(); 5557dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == -1) 5567dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("vfork"); 55710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5587dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (popen_pid == 0) { 55910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin /* child */ 56010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin close(fds[1]); 5617dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (fds[0] != 0) { 5627dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (dup2(fds[0], 0)) 5637dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("dup2"); 5647dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 56510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 56610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin execl(_PATH_BSHELL, "sh", "-c", command, NULL); 5677dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 56810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 5697dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 5707dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko /* parent */ 5717dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko close(fds[0]); 5727dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko swap_uid(); 5737dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko fp = fdopen(fds[1], "w"); 5747dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (!fp) 5751d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 5767dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko return fp; 57710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 57810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 5793d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenkostatic void 58010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinnewoutf(struct tcb *tcp) 58110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 5827de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (outfname && followfork >= 2) { 5837a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char name[520 + sizeof(int) * 3]; 5847a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 5853d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko tcp->outf = strace_fopen(name); 58610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 58710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 58810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 589558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkostatic void 590558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkoprocess_opt_p_list(char *opt) 591e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko{ 592e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko while (*opt) { 593e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko /* 594e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". 595e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * pidof uses space as delim, pgrep uses newline. :( 596e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko */ 597e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko int pid; 598e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char *delim = opt + strcspn(opt, ", \n\t"); 599e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char c = *delim; 600e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 601e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = '\0'; 602e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko pid = atoi(opt); /* TODO: stricter parsing of the number? */ 603e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid <= 0) { 604e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko error_msg("Invalid process id: '%s'", opt); 605e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 606e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko return; 607e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 608e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid == strace_tracer_pid) { 609e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko error_msg("I'm sorry, I can't let you do that, Dave."); 610e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 611e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko return; 612e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 613e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 61475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko alloc_tcb(pid, 0); 615e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (c == '\0') 616e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko break; 617e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko opt = delim + 1; 618e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 619e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko} 620e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 62102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 62202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 62302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 62402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 62502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 62602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 62702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 62802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 62902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 6302e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * between PTRACE_ATTACH and wait4() on SIGSTOP. 631b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 63202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 63302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 63402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 63502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 636ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 637ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 638ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 639014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko perror_msg_and_die("fork"); 640ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 641ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 642ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 64375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 64475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 64575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 646ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 647ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 648ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 649ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 650ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 65175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 65275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 65375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 654ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 655ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 65602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 65702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 65844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko 65975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!(tcp->flags & TCB_INUSE)) 66075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; 66175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 662d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Is this a process we should attach to, but not yet attached? */ 66375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (tcp->flags & TCB_ATTACHED) 66475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; /* no, we already attached it */ 665d116a7338645af45090aecc331701e999148d284Denys Vlasenko 666d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Reinitialize the output since it may have changed */ 66702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->outf = outf; 6683d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko newoutf(tcp); 66902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 670ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 6717a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 67202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 67302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 67402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 67502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 67602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 67702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 67802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct dirent *de; 679381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 68002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath while ((de = readdir(dir)) != NULL) { 681381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko struct tcb *cur_tcp; 682381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko int tid; 683381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 6847a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 68502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 68602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 68702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 68802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 68902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 69031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tid) < 0) { 69102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 692a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 693f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 694381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko continue; 695f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 696a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 697381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 698381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = tcp; 699381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (tid != tcp->pid) 700381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = alloctcb(tid); 70131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 70202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 70302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 704381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interactive) { 705381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 706381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interrupted) 707381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko goto ret; 708381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 709381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko } 7107a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 7117a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 71202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 71302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 71402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 71502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 71602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 7177a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 7187a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko? "Process %u attached with %u threads - interrupt to quit\n" 7197a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko: "Process %u attached - interrupt to quit\n", 72044f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko tcp->pid, ntid); 72102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 72275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!(tcp->flags & TCB_ATTACHED)) { 723f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* -p PID, we failed to attach to PID itself 724f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * but did attach to some of its sibling threads. 725f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Drop PID's tcp. 726f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 727f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko droptcb(tcp); 728f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 72902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 7307a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 7317a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 73231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tcp->pid) < 0) { 73302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath perror("attach: ptrace(PTRACE_ATTACH, ...)"); 73402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 73502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 73602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 73775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 738a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 739f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 740ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 741ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 742ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 743ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 744ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 745ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 746ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 747ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 748ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 74902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 75002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 75102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath "Process %u attached - interrupt to quit\n", 75202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 753f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 75402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 75544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret: 75602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 75702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 75802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 75902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 76002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 7611201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 76202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 76302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct stat statbuf; 76402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 76502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 76602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int pid = 0; 76702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 76802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 76902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 77002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 77102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 77202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 773cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 77402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 77502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 77602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 77702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 77802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 77902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 78002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 78102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 78202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 78302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (stat(filename, &statbuf) == 0) 78402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 78502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 78602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 78730145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 78802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 78902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 79002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 7914f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko const char *colon = strchr(path, ':'); 7924f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko if (colon) { 7934f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko n = colon - path; 79402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 79502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 79602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 79702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 79802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 79902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 80002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 80102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 80202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 80302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 80402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 80502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 80602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 80702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 80802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 80902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 81002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 81102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 81202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) == 0 && 81302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 81402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 81502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 81602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 81702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 81802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 81902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 82002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 82102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (stat(pathname, &statbuf) < 0) { 822cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 82302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 824a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin strace_child = pid = fork(); 825ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 826cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 827ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 82875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if ((pid != 0 && daemonized_tracer) /* -D: parent to become a traced process */ 82975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko || (pid == 0 && !daemonized_tracer) /* not -D: child to become a traced process */ 830ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 831ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid = getpid(); 8322e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (outf != stderr) 8332e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko close(fileno(outf)); 83431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!daemonized_tracer && !use_seize) { 83531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 836cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 837ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 83802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 83902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 840ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (username != NULL) { 84102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath uid_t run_euid = run_uid; 84202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath gid_t run_egid = run_gid; 84302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 84402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISUID) 84502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_euid = statbuf.st_uid; 84602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (statbuf.st_mode & S_ISGID) 84702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath run_egid = statbuf.st_gid; 84802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 84902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * It is important to set groups before we 85002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * lose privileges on setuid. 85102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 852ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (initgroups(username, run_gid) < 0) { 853ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("initgroups"); 854ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 855ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setregid(run_gid, run_egid) < 0) { 856ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setregid"); 857ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko } 858ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko if (setreuid(run_uid, run_euid) < 0) { 859ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko perror_msg_and_die("setreuid"); 86002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 86102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 862ab034fbf09460c2fd933ea47c9085d09b8a1ab27Denys Vlasenko else if (geteuid() != 0) 86302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath setreuid(run_uid, run_uid); 86402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 865ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (!daemonized_tracer) { 866ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 8672e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Induce a ptrace stop. Tracer (our parent) 868ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * will resume us with PTRACE_SYSCALL and display 8692e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * the immediately following execve syscall. 8702e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * Can't do this on NOMMU systems, we are after 8712e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * vfork: parent is blocked, stopping would deadlock. 872ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 873c1a5b7e8c42086635d09ce8adc7f8b3dd018c999Mike Frysinger if (!strace_vforked) 8742e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko kill(pid, SIGSTOP); 875ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } else { 876ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(3); 877a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko /* we depend on SIGCHLD set to SIG_DFL by init code */ 878a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko /* if it happens to be SIG_IGN'ed, wait won't block */ 879ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko wait(NULL); 880ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko alarm(0); 881ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 88202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 88302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath execv(pathname, argv); 884cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 88502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 886ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 8872e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We are the tracer */ 88875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 8892e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (!daemonized_tracer) { 89031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) { 89131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* child did PTRACE_TRACEME, nothing to do in parent */ 89231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } else { 89331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) { 89431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Wait until child stopped itself */ 89531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status; 89631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (waitpid(pid, &status, WSTOPPED) < 0) { 89731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 89831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 89931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("waitpid"); 90031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 90131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 90275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 90331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Unexpected wait status %x", status); 90431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 90531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 90631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Else: vforked case, we have no way to sync. 90731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * Just attach to it as soon as possible. 90831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This means that we may miss a few first syscalls... 90931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 91031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 91131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(pid)) { 91275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 91331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Can't attach to %d", pid); 91431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 91531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!strace_vforked) 91631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGCONT); 91731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 9182e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 919f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (!strace_vforked) 92075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP | post_attach_sigstop; 921f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko else 92275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STRACE_CHILD | TCB_STARTUP; 9232e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko } 9242e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko else { 9252e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* With -D, *we* are child here, IOW: different pid. Fetch it: */ 9262e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko strace_tracer_pid = getpid(); 9272e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* The tracee is our parent: */ 9282e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko pid = getppid(); 929f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko alloctcb(pid); 930f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko /* attaching will be done later, by startup_attach */ 931ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 93202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 93302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 934b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 935b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 936b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 937b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 938b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 93904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levinstatic void 9403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 941b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 9422fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 9432fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 9442fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 9452fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 946b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 9475d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = fork(); 9485d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid < 0) 94904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 9505d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid == 0) { 95104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin pid = getpid(); 95231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 95304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 95404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 9554c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGSTOP); 95604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (fork() < 0) 95704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 95804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin _exit(0); 959b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 960b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 961b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 962b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 963b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 96404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = 0; 965b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 96604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid <= 0) { 967b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 968b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 9694c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko if (errno == ECHILD) 970b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 97104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 97204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 97304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 97404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 97504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFEXITED(status)) { 97604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WEXITSTATUS(status)) { 97704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 97804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 97904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 98004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 98104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 98204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 98304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 98404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 98504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 98604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 98704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 98804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 98904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 99004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (!WIFSTOPPED(status)) { 99104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 99204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 9934c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGKILL); 99404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 99504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 996b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 997b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 9982fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 99904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 100004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 100104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 100204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_CONT doesn't work"); 100304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 100404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 1005b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 100604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin switch (WSTOPSIG(status)) { 100704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGSTOP: 100804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 100904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 101004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 101104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 101204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGTRAP: 101304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 101404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin long msg = 0; 10152fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 101604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 101704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin NULL, (long) &msg) == 0) 101804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin expected_grandchild = msg; 1019b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 102004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 102104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 102204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 102304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 102404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1025b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 1026b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 102704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) { 1028f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1029a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 103004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin fprintf(stderr, "ptrace_setoptions = %#x\n", 103104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin ptrace_setoptions); 103204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin return; 103304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 103404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACECLONE failed, " 103504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 1036b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 10373454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 10393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 10403454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 10413454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 10423454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 10433454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 10443454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 10453454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * _start: .globl _start 10463454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int3 10473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $42, %ebx 10483454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * movl $1, %eax 10493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * int $0x80 10503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * (compile with: "gcc -nostartfiles -nostdlib -o int3 int3.S") 10513454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 10523454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkostatic void 10533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 10543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 105504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 105604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin PTRACE_O_TRACEEXEC; 10573454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 10583454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 10593454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 10613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 106275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 10633454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 10653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 10663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 106775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 106804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 106904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 10703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 10713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 10723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 10753454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 10763454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 10773454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 10783454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 10793454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 10803454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 10813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 108204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 108304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 108404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 108575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 108675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 108775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 108875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 108904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 109004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 109104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 109204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 109304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 109404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 10953454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 10963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 10973454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 109804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 109904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 11003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11013454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 11023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 11033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 11043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 11053454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 11063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 11073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 110804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 110904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 111004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 11113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 11133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 11143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11153454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 111604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 111775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 11183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11193454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 11213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 112275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 1123f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1124a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1125f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 1126f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 11273454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko return; 11283454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 11293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 113004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 113104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 11323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 113331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 113431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# ifdef USE_SEIZE 113531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic void 113631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotest_ptrace_seize(void) 113731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 113831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int pid; 113931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 114031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pid = fork(); 114131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid < 0) 114231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("fork"); 114331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 114431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid == 0) { 114531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pause(); 114631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko _exit(0); 114731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 114831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 114931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 115031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * attaching tracee continues to run unless a trap condition occurs. 115131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * PTRACE_SEIZE doesn't affect signal or group stop state. 115231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 115331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_SEIZE, pid, 0, PTRACE_SEIZE_DEVEL) == 0) { 115431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1155a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko } else if (debug_flag) { 115631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 115731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 115831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 115931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 116031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 116131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (1) { 116231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status, tracee_pid; 116331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 116431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko errno = 0; 116531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tracee_pid = waitpid(pid, &status, 0); 116631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (tracee_pid <= 0) { 116731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 116831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 116931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("%s: unexpected wait result %d", 117031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, tracee_pid); 117131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 117231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (WIFSIGNALED(status)) { 117331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return; 117431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 117531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko error_msg_and_die("%s: unexpected wait status %x", 117631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, status); 117731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 117831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 117931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# else /* !USE_SEIZE */ 118031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define test_ptrace_seize() ((void)0) 118131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# endif 118231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 11836e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenkostatic unsigned 1184f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkoget_os_release(void) 1185f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko{ 11866e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko unsigned rel; 11876e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko const char *p; 1188f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct utsname u; 1189f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (uname(&u) < 0) 1190f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko perror_msg_and_die("uname"); 11916e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko /* u.release has this form: "3.2.9[-some-garbage]" */ 11926e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko rel = 0; 11936e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p = u.release; 11946e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko for (;;) { 11956e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (!(*p >= '0' && *p <= '9')) 11966e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko error_msg_and_die("Bad OS release string: '%s'", u.release); 11976e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko /* Note: this open-codes KERNEL_VERSION(): */ 11986e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko rel = (rel << 8) | atoi(p); 11996e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (rel >= KERNEL_VERSION(1,0,0)) 12006e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko break; 12016e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko while (*p >= '0' && *p <= '9') 12026e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p++; 12036e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (*p != '.') 12046e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko error_msg_and_die("Bad OS release string: '%s'", u.release); 12056e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p++; 12066e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko } 12076e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko return rel; 1208f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko} 1209f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1210ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko/* 1211ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Initialization part of main() was eating much stack (~0.5k), 1212ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * which was unused after init. 1213ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * We can reuse it if we move init code into a separate function. 1214ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * 1215ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Don't want main() to inline us and defeat the reason 1216ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * we have a separate function. 1217ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko */ 1218ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkostatic void __attribute__ ((noinline)) 1219ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoinit(int argc, char *argv[]) 122076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 122176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 1222e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko int c; 122306350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 122476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 122576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 122608b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 122708b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 1228a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko /* Make sure SIGCHLD has the default action so that waitpid 1229a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko definitely works without losing track of children. The user 1230a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko should not have given us a bogus state to inherit, but he might 1231a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko have. Arguably we should detect SIG_IGN here and pass it on 1232a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko to children, but probably noone really needs that. */ 1233a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko signal(SIGCHLD, SIG_DFL); 1234a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko 123575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 123675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 12376e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko os_release = get_os_release(); 1238f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1239ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 1240ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 12414f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 12421d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcbtab) 12431d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 12444f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 12451d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcp) 12461d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 12474f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 12484f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 1249ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 125076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outf = stderr; 1251138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 1252138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 125376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 125476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 125576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 125676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 125776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 125861e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko "+bcCdfFhiqrtTvVxyz" 1259ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 1260b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 126176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 126261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko case 'b': 126361e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko detach_on_execve = 1; 126461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko break; 126576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 1266e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 1267cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1268e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1269e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 1270e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 1271e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 1272e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 1273cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-c and -C are mutually exclusive options"); 1274e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1275e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 127676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 127776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 1278a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko debug_flag = 1; 127976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1280ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 1281ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 1282ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 128341c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 128406350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 128506350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 128676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 128776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 128876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 128976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 129076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 129176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 129276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 1293a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko iflag = 1; 129476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 129576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 1296a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko qflag = 1; 129776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 129876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 1299a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko rflag = 1; 1300a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko /* fall through to tflag++ */ 130176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 130276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 130376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 130476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 1305a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko Tflag = 1; 130676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 130776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 130876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 130976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 13108a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 13118a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 13128a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 131376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 131476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 131576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 131676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 13179c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 131876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 131976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 132017f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 132117f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 132217f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 132376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 132476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman acolumn = atoi(optarg); 1325102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (acolumn < 0) 1326102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko error_msg_and_die("Bad column width '%s'", optarg); 132776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 132876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 132976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 133076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 133176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 133276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 133376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 133476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 133576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_overhead(atoi(optarg)); 133676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 133776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 1338e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko process_opt_p_list(optarg); 133976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 13408a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 13418a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards tracing_paths = 1; 13428a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards if (pathtrace_select(optarg)) { 1343cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Failed to select path '%s'", optarg); 13448a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards } 13458a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 134676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 134776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman max_strlen = atoi(optarg); 1348dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath if (max_strlen < 0) { 1349b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1350dccec72a72e7b6451d9739e5d4611f4abf39f48dRoland McGrath } 135176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 135276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 135376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 135476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 135576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 135676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 135776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1358de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 13591d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (putenv(optarg) < 0) 13601d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1361de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 1362b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko case 'I': 1363b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = atoi(optarg); 1364b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) { 1365b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko error_msg_and_die("Invalid -%c argument: '%s'", c, optarg); 1366b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1367b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko break; 136876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 136976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 137076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 137176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 137276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1373837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko argv += optind; 1374837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* argc -= optind; - no need, argc is not used below */ 137576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1376102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces = malloc(acolumn + 1); 1377102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (!acolumn_spaces) 13781d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1379102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko memset(acolumn_spaces, ' ', acolumn); 1380102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces[acolumn] = '\0'; 1381102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko 1382837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* Must have PROG [ARGS], or -p PID. Not both. */ 1383fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (!argv[0] == !nprocs) 1384ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1385ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1386fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 && daemonized_tracer) { 1387cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("-D and -p are mutually exclusive options"); 1388d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1389d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 139006350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 139106350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 139206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 1393cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath if (followfork > 1 && cflag) { 1394cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive options"); 1395cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1396cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 139776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 139876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 139976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 140076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 140176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1402cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 140376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 14045d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pent = getpwnam(username); 14055d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pent == NULL) { 1406cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 140776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 140876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 140976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 141076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 141276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 141376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 141476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 141576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 141604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (followfork) 141704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin test_ptrace_setoptions_followfork(); 14183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko test_ptrace_setoptions_for_all(); 141931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko test_ptrace_seize(); 14208044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 142176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 142276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 142337b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 142437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 142537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 142637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 142737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 142837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 14297dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko if (followfork > 1) 14307dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 14317dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko outf = strace_popen(outfname + 1); 143254b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 14333d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko else if (followfork <= 1) 14343d5ed41252ab8c0bb9f410058c61e95ba91caf90Denys Vlasenko outf = strace_fopen(outfname); 1435328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko } else { 1436328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko /* -ff without -o FILE is the same as single -f */ 1437328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko if (followfork > 1) 1438328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko followfork = 1; 143976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 144076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1441cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1442a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko char *buf = malloc(BUFSIZ); 1443a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko if (!buf) 1444a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko die_out_of_memory(); 144576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman setvbuf(outf, buf, _IOLBF, BUFSIZ); 1446cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 1447837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (outfname && argv[0]) { 1448b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1449b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_NEVER; 145076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1451369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1452b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1453b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_WHILE_WAIT; 1454b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1455b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* argv[0] -pPID -oFILE Default interactive setting 1456b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 0 INTR_WHILE_WAIT 1457b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 0 INTR_WHILE_WAIT 1458b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 1 INTR_NEVER 1459b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 1 INTR_WHILE_WAIT 146054cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 146154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 146254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath /* STARTUP_CHILD must be called before the signal handlers get 146354cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath installed below as they are inherited into the spawned process. 146454cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath Also we do not need to be protected by them as during interruption 146554cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath in the STARTUP_CHILD mode we kill the spawned process anyway. */ 146661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (argv[0]) { 146761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko skip_startup_execve = 1; 1468837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko startup_child(argv); 146961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 147076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 147176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&empty_set); 147276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&blocked_set); 147376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 147476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 147576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 1476b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1477b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1478b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr != INTR_ANYWHERE) { 1479b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_BLOCK_TSTP_TOO) 1480b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1481b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* 1482b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In interactive mode (if no -o OUTFILE, or -p PID is used), 1483b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * fatal signals are blocked while syscall stop is processed, 1484b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * and acted on in between, when waiting for new syscall stops. 1485b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In non-interactive mode, signals are ignored. 1486b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko */ 1487b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_WHILE_WAIT) { 1488b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGHUP); 1489b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGINT); 1490b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGQUIT); 1491b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGPIPE); 1492b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGTERM); 1493b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sa.sa_handler = interrupt; 1494b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1495b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* SIG_IGN, or set handler for these */ 1496b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGHUP, &sa, NULL); 1497b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGINT, &sa, NULL); 1498b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGQUIT, &sa, NULL); 1499b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGPIPE, &sa, NULL); 1500b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTERM, &sa, NULL); 150176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1502fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 || daemonized_tracer) 150302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 150402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 1505fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko /* Do we want pids printed in our -o OUTFILE? 1506fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -ff: no (every pid has its own file); or 1507fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -f: yes (there can be more pids in the future); or 1508fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -p PID1,PID2: yes (there are already more than one pid) 1509fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko */ 1510fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1)); 151176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 151276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 15132b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic void 1514418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenkoexpand_tcbtab(void) 15157b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath{ 15167b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath /* Allocate some more TCBs and expand the table. 15177b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath We don't want to relocate the TCBs because our 15187b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath callers have pointers and it would be a pain. 15197b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath So tcbtab is a table of pointers. Since we never 15207b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath free the TCBs, we allocate a single chunk of many. */ 152118da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko int i = tcbtabsize; 152218da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 152318da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 15241d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!newtab || !newtcbs) 15251d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 15267b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtabsize *= 2; 15277b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath tcbtab = newtab; 152818da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko while (i < tcbtabsize) 152918da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko tcbtab[i++] = newtcbs++; 15307b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath} 15317b54a7ae61d0eda798575f77d898a24dda7a0952Roland McGrath 153276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstruct tcb * 153310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinalloc_tcb(int pid, int command_options_parsed) 153476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 153576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 153676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 153776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1538418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko if (nprocs == tcbtabsize) 1539418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko expand_tcbtab(); 1540418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko 1541ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1542ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 154376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if ((tcp->flags & TCB_INUSE) == 0) { 154418da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 154576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->pid = pid; 1546381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko tcp->flags = TCB_INUSE; 154776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->outf = outf; /* Initialise to current out file */ 1548a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#if SUPPORTED_PERSONALITIES > 1 1549a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin tcp->currpers = current_personality; 1550a5a839a920da9d54c4174ebc82b29d7718839029Dmitry V. Levin#endif 155176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs++; 1552a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 15531d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 155410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (command_options_parsed) 155510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newoutf(tcp); 155676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 155776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 155918da27367534217ac52a425413ae3f8b4b9d8ad2Denys Vlasenko error_msg_and_die("bug in alloc_tcb"); 156076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 156176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1562eebb04d4ae8bf4b08a041f5ea442ca24c90692c2Denys Vlasenkostatic struct tcb * 156354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 156476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 156576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 156654e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 156754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 156854e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 156976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1570ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 157154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 157254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (tcp->pid == pid && (tcp->flags & TCB_INUSE)) 157376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 157476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 157554e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 157676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 157776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 157876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 157976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanvoid 15801201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkodroptcb(struct tcb *tcp) 158176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 158276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->pid == 0) 158376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return; 158419cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko 158576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman nprocs--; 1586a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 15871d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 1588eb8ebdad122a20ecae0ce8e3e60cb71d8e4a7152Wichert Akkerman 15893e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (tcp->outf) { 15903e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (outfname && followfork >= 2) { 15913e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (tcp->curcol != 0) 15923e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 15933e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fclose(tcp->outf); 15943e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (outf == tcp->outf) 15953e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko outf = NULL; 15963e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } else { 15973e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko if (printing_tcp == tcp && tcp->curcol != 0) 15983e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 15993e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko fflush(tcp->outf); 16003e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } 16013e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko } 16023e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko 16037de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (printing_tcp == tcp) 16047de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = NULL; 16057de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 160619cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko memset(tcp, 0, sizeof(*tcp)); 160776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 160876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 16090a463880341945df08b6dc79134dc78cc38dc283Roland McGrath/* detach traced process; continue with sig 161075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * Never call DETACH twice on the same process as both unattached and 161175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * attached-unstopped processes give the same ESRCH. For unattached process we 161275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * would SIGSTOP it and wait for its SIGSTOP notification forever. 161375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko */ 161476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 16154c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenkodetach(struct tcb *tcp) 161676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 161775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int error; 161875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int status, sigstop_expected; 161976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 162076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (tcp->flags & TCB_BPTSET) 1621840d85b3e50cea9f28aedd23af94742c2a60265aAndreas Schwab clearbpt(tcp); 162276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 162376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 162476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * Linux wrongly insists the child be stopped 16257bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * before detaching. Arghh. We go through hoops 16267bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath * to make a clean break of things. 162776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 16287bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#if defined(SPARC) 16297bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#undef PTRACE_DETACH 16307bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#define PTRACE_DETACH PTRACE_SUNDETACH 16317bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath#endif 163275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 16333e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko error = 0; 163475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = 0; 163575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (tcp->flags & TCB_ATTACHED) { 163675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* 163775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * We attached but possibly didn't see the expected SIGSTOP. 163875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * We must catch exactly one as otherwise the detached process 163975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko * would be left stopped (process state T). 164075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko */ 164175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP); 164275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0); 164375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (error == 0) { 164475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* On a clear day, you can see forever. */ 164575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 164675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (errno != ESRCH) { 164775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko /* Shouldn't happen. */ 164875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: ptrace(PTRACE_DETACH, ...)"); 164975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 165075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (my_tkill(tcp->pid, 0) < 0) { 165175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (errno != ESRCH) 165275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: checking sanity"); 165375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 165475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) { 165575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (errno != ESRCH) 165675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko perror("detach: stopping child"); 165775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko } 165875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko else 165975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko sigstop_expected = 1; 16607bf10474b981aa27f6b8c5b5e3f563d21f2eafcaRoland McGrath } 166175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 166275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (sigstop_expected) { 166376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman for (;;) { 16647508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 166537ab4b79de57c1657e41f96a96fa699a08194a80Denys Vlasenko if (waitpid(tcp->pid, &status, __WALL) < 0) { 16667508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno == ECHILD) /* Already gone. */ 16677508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16687508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != EINVAL) { 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman perror("detach: waiting"); 16707508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16717508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16727508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WALL */ 16737508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* No __WALL here. */ 16747508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (waitpid(tcp->pid, &status, 0) < 0) { 16757508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) { 16767508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16777508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16787508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16797508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WCLONE 16807508cb4678141d146d819120f6b5b428c103882eRoland McGrath /* If no processes, try clones. */ 168137ab4b79de57c1657e41f96a96fa699a08194a80Denys Vlasenko if (waitpid(tcp->pid, &status, __WCLONE) < 0) { 16827508cb4678141d146d819120f6b5b428c103882eRoland McGrath if (errno != ECHILD) 16837508cb4678141d146d819120f6b5b428c103882eRoland McGrath perror("detach: waiting"); 16847508cb4678141d146d819120f6b5b428c103882eRoland McGrath break; 16857508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16867508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif /* __WCLONE */ 16877508cb4678141d146d819120f6b5b428c103882eRoland McGrath } 16887508cb4678141d146d819120f6b5b428c103882eRoland McGrath#ifdef __WALL 168976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 16907508cb4678141d146d819120f6b5b428c103882eRoland McGrath#endif 169176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 169276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Au revoir, mon ami. */ 169376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 169476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 169576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WSTOPSIG(status) == SIGSTOP) { 16964c1963836fd96909c2d86315d4972b5b0075edf6Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, 0); 169776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 169876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1699732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, 170075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko WSTOPSIG(status) == syscall_trap_sig ? 0 1701732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko : WSTOPSIG(status)); 1702732d1bf4d4aaff68eff1c41d8900264637a57dfeDenys Vlasenko if (error < 0) 170376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 170476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1705ef2fbf856cf775981b52278c80ce2a74a44019f4Denys Vlasenko } 170676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 170775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!qflag && (tcp->flags & TCB_ATTACHED)) 170876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "Process %u detached\n", tcp->pid); 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 1711a08a97eff32ba016ec5d71d2e6948dd43b98cf34Roland McGrath 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return error; 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 17161201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 171976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 17203521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko int fatal_sig; 17213521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko 17223521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko /* 'interrupted' is a volatile object, fetch it only once */ 17233521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = interrupted; 17243521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko if (!fatal_sig) 17253521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = SIGTERM; 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1727ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 1728ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!(tcp->flags & TCB_INUSE)) 173076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1731a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 173276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 17347de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (tcp->flags & TCB_STRACE_CHILD) { 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 1736a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko kill(tcp->pid, fatal_sig); 173776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 17387de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko detach(tcp); 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman call_summary(outf); 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 17451201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 174676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 1747a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko interrupted = sig; 174876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 175076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic int 17511201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 175276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 175426d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko struct rusage *rup = cflag ? &ru : NULL; 175526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 1756eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath static int wait4_options = __WALL; 175726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1759eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath while (nprocs != 0) { 1760f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int pid; 1761f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int wait_errno; 1762f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int status, sig; 176331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int stopped; 1764f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *tcp; 1765f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko unsigned event; 1766f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1767222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 1768eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 1769eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 1770eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 177126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# ifdef __WALL 177226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 17735bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && (wait4_options & __WALL) && errno == EINVAL) { 17742f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* this kernel does not support __WALL */ 17752f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman wait4_options &= ~__WALL; 177626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, wait4_options, rup); 17772f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 17785bc05558bb9f9acd1f895ea128f3326ef4b03338Roland McGrath if (pid < 0 && !(wait4_options & __WALL) && errno == ECHILD) { 17792f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman /* most likely a "cloned" process */ 178026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, __WCLONE, rup); 178126d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 1782cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg("wait4(__WCLONE) failed"); 17832f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 17842f1d87e74ff68004b99901f964a1cbab89da09dbWichert Akkerman } 178526d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# else 178626d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko pid = wait4(-1, &status, 0, rup); 178726d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko# endif /* __WALL */ 178876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 1789eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 1790eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 179176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 179226d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 1793eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath switch (wait_errno) { 1794eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case EINTR: 179576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 1796eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath case ECHILD: 179776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * We would like to verify this case 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * but sometimes a race in Solbourne's 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * version of SunOS sometimes reports 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman * ECHILD before sending us SIGCHILD. 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 1803eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return 0; 1804eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath default: 1805eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath errno = wait_errno; 18064c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko perror_msg("wait"); 1807eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath return -1; 180876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 181010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 181110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (WIFEXITED(status) || WIFSIGNALED(status)) 18127dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 181310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 181410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 1815f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1816f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko event = ((unsigned)status >> 16); 1817a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) { 18181d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 181967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko char evbuf[sizeof(",PTRACE_EVENT_?? (%u)") + sizeof(int)*3 /*paranoia:*/ + 16]; 18201d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 18211d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 18221d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 18231d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 18241d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 18251d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 18261d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 18271d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 18281d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 18291d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 18301d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 18311d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 18321d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 18331d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 18345bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 18351d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 18361d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 18375bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 183867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko evbuf[0] = '\0'; 183967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event != 0) { 184067559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko static const char *const event_names[] = { 184167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 184267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 184367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 184467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 184567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 184667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 184767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko }; 184867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko const char *e; 184967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event < ARRAY_SIZE(event_names)) 185067559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko e = event_names[event]; 185167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko else { 185267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko sprintf(buf, "?? (%u)", event); 185367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko e = buf; 185467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko } 185567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko sprintf(evbuf, ",PTRACE_EVENT_%s", e); 185667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko } 185767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko fprintf(stderr, " [wait(0x%04x) = %u] %s%s\n", status, pid, buf, evbuf); 18581d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1860f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Look up 'pid' in our table. */ 18615d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pid2tcb(pid); 1862f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1863f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Under Linux, execve changes pid to thread leader's pid, 1864f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and we see this changed pid on EVENT_EXEC and later, 1865f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * execve sysexit. Leader "disappears" without exit 1866f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * notification. Let user know that, drop leader's tcb, 1867f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and fix up pid in execve thread's tcb. 1868f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * Effectively, execve thread's tcb replaces leader's tcb. 1869f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 1870f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 1871f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * on exit syscall) in multithreaded programs exactly 1872f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * in order to handle this case. 1873f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 1874f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 1875f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * On 2.6 and earlier, it can return garbage. 1876f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko */ 18776e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) { 1878f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko long old_pid = 0; 1879f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) >= 0 1880f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid > 0 1881f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko && old_pid != pid 1882f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko ) { 1883f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *execve_thread = pid2tcb(old_pid); 1884f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 1885f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko outf = tcp->outf; 1886f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko curcol = tcp->curcol; 1887f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (execve_thread) { 18887de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (execve_thread->curcol != 0) { 18897de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* 18907de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * One case we are here is -ff: 18917de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * try "strace -oLOG -ff test/threaded_execve" 18927de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 18937de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid); 18947de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko execve_thread->curcol = 0; 18957de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 1896f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* swap output FILEs (needed for -ff) */ 1897f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->outf = execve_thread->outf; 18987de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = execve_thread->curcol; 1899f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko execve_thread->outf = outf; 19007de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko execve_thread->curcol = curcol; 1901f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1902f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko droptcb(tcp); 1903f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1904f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp = execve_thread; 1905f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (tcp) { 1906f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->pid = pid; 1907f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko tcp->flags |= TCB_REPRINT; 19087de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (!cflag) { 19097de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printleader(tcp); 19107de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 19117de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 19127de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko } 1913f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1914f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1915f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 1916f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 191761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (event == PTRACE_EVENT_EXEC && detach_on_execve) { 191861e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (!skip_startup_execve) 191961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko detach(tcp); 192061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko /* This was initial execve for "strace PROG". Skip. */ 192161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko skip_startup_execve = 0; 192261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 192361e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko 19245d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (tcp == NULL) { 192541c48227a86a176da333f713d5047240885f25ccRoland McGrath if (followfork) { 1926e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This is needed to go with the CLONE_PTRACE 1927e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath changes in process.c/util.c: we might see 1928e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath the child's initial trap before we see the 1929e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath parent return from the clone syscall. 1930e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath Leave the child suspended until the parent 1931e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath returns from its system call. Only then 1932e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath will we have the association of parent and 1933e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath child so that we know how to do clearbpt 1934e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath in the child. */ 1935418d66a847bda4867c59e604c0d07c64ed53e320Denys Vlasenko tcp = alloctcb(pid); 193631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 1937e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (!qflag) 1938833fb13cef3f1f05b71361b5002aa3c2faad9615Denys Vlasenko fprintf(stderr, "Process %d attached\n", 1939e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath pid); 19408b1b40cd8b49151374d0ac2a5b1a4b459f9e0ae5Wichert Akkerman } 1941e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath else 1942e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath /* This can happen if a clone call used 1943e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath CLONE_PTRACE itself. */ 1944e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath { 1945e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath if (WIFSTOPPED(status)) 194697c503fa2e9cd02126feae659f133631c8eb36f1Denys Vlasenko ptrace(PTRACE_CONT, pid, (char *) 0, 0); 1947cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Unknown pid: %u", pid); 1948e85bbfe9ab55854cc3a6227d2f9001587fe64996Roland McGrath } 194976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 19507de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 19517de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* Set current output file */ 1952eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath outf = tcp->outf; 1953ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab curcol = tcp->curcol; 19547de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 195513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 195676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 195776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 195876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1959eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 196076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 1961a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 1962a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 1963e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 196476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL)) { 196576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 196613d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 1967000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s %s+++\n", 19682efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 196913d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 197013d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 1971000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s +++\n", 197213d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 19732efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 19747de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 197576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 197876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 197976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 1980a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 1981a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 198219cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko if (!cflag /* && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) */ ) { 198319cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 1984000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 19857de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 198619cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 198776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 198876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 199176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1996f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this the very first time we see this tracee stopped? */ 1997f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (tcp->flags & TCB_STARTUP) { 1998a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1999f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 200076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 200102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 200276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 200302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 20042ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * parent through fork(). 200576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 20066cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (clearbpt(tcp) < 0) { 20076cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko /* Pretty fatal */ 200876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 200976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 201176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 201344f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace_setoptions) { 2014a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 201544f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko fprintf(stderr, "setting opts %x on pid %d\n", ptrace_setoptions, tcp->pid); 201644f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 201744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (errno != ESRCH) { 201844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko /* Should never happen, really */ 201944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 20203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 20213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 20223454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2023f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2024f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 202531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko sig = WSTOPSIG(status); 202631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 2027f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event != 0) { 202831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Ptrace event */ 202931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 203031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (event == PTRACE_EVENT_STOP || event == PTRACE_EVENT_STOP1) { 20316703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko /* 20326703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop or group-stop. 20336703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 20346703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko */ 203531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (sig == SIGSTOP 203631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTSTP 203731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTIN 203831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTOU 203931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko ) { 204031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = 1; 204131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto show_stopsig; 204231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 204331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 204431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 2045f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko goto restart_tracee_with_sig_0; 2046f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2047f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2048f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this post-attach SIGSTOP? 2049f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Interestingly, the process may stop 2050f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * with STOPSIG equal to some other signal 2051f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * than SIGSTOP if we happend to attach 2052f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * just before the process takes a signal. 2053f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 2054f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2055a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2056f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2057f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 20586cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee_with_sig_0; 205976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 206076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 20616cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (sig != syscall_trap_sig) { 206231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko siginfo_t si; 206331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 206431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Nonzero (true) if tracee is stopped by signal 206531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (as opposed to "tracee received signal"). 206631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 206731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 20686703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#ifdef USE_SEIZE 206931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko show_stopsig: 20706703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#endif 2071e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 20726cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko && (qual_flags[sig] & QUAL_SIGNAL)) { 2073c15dfc796150d09bb74bebfbb85bebf142766b6cDmitry V. Levin#if defined(PT_CR_IPSR) && defined(PT_CR_IIP) 20746b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long pc = 0; 20756b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin long psr = 0; 20767b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 2077932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IPSR, &psr); 2078932fc7d4fc1a29e8b8bcea5685db3f6c2e212e36Denys Vlasenko upeek(tcp, PT_CR_IIP, &pc); 20797b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman 20806b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PSR_RI 41 20817b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman pc += (psr >> PSR_RI) & 0x3; 20826b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin# define PC_FORMAT_STR " @ %lx" 20832ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG , pc 20846b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin#else 20852ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_STR "" 20862ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko# define PC_FORMAT_ARG /* nothing */ 20877b3346be42d6a1f539e95d385ee498f8b3c529f8Wichert Akkerman#endif 208876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 208931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) { 20902c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko tprintf("--- %s ", signame(sig)); 20916b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin printsiginfo(&si, verbose(tcp)); 20922c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko tprintf(PC_FORMAT_STR " ---\n" 20936b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 20946b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin } else 20952c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko tprintf("--- stopped by %s" PC_FORMAT_STR " ---\n", 20966cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko signame(sig) 20976b7a261ff81fdbe84769cb59852fa43cabc77e8fDmitry V. Levin PC_FORMAT_ARG); 20987de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 209976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 210031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 210131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) 210231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's signal-delivery-stop. Inject the signal */ 210331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto restart_tracee; 210431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 210531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's group-stop */ 210631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#ifdef USE_SEIZE 210731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (use_seize) { 210831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* 210931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This ends ptrace-stop, but does *not* end group-stop. 211031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This makes stopping signals work properly on straced process 211131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (that is, process really stops. It used to continue to run). 211231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 211331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 211431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cleanup(); 211531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return -1; 211631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 21177de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = curcol; 211831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 211931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 212031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* We don't have PTRACE_LISTEN support... */ 212131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 21226cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee; 212376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21242ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 21252ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* We handled quick cases, we are permitted to interrupt now. */ 212602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 212702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath return 0; 21282ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 21292ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* This should be syscall entry or exit. 21302ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * (Or it still can be that pesky post-execve SIGTRAP!) 21312ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * Handle it. 21322ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko */ 2133eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (trace_syscall(tcp) < 0 && !tcp->ptrace_errno) { 2134eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath /* ptrace() failed in trace_syscall() with ESRCH. 2135eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2136eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Observed case: exit_group() terminating 2137f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * all processes in thread group. 21387de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * We assume that ptrace error was caused by process death. 2139f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * We used to detach(tcp) here, but since we no longer 2140f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * implement "detach before death" policy/hack, 2141f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * we can let this process to report its death to us 2142f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * normally, via WIFEXITED or WIFSIGNALED wait status. 2143f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko */ 21447de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko tcp->curcol = curcol; 214576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 214676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 21476cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0: 21486cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko sig = 0; 21496cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee: 2150ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab /* Remember current print column before continuing. */ 2151ccdff481c086611488c5df70550fcf8fe907e7afAndreas Schwab tcp->curcol = curcol; 21526cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 215376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman cleanup(); 215476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return -1; 215576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 215776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return 0; 215876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 2159ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2160ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoint 2161ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkomain(int argc, char *argv[]) 2162ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko{ 2163ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko init(argc, argv); 2164ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2165ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Run main tracing loop */ 2166ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko if (trace() < 0) 2167ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko return 1; 2168ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2169ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko cleanup(); 2170ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko fflush(NULL); 2171ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko if (exit_code > 0xff) { 2172ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Avoid potential core file clobbering. */ 2173ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko struct rlimit rlim = {0, 0}; 2174ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko setrlimit(RLIMIT_CORE, &rlim); 2175ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2176ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Child was killed by a signal, mimic that. */ 2177ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code &= 0xff; 2178ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko signal(exit_code, SIG_DFL); 2179ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko raise(exit_code); 2180ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Paranoia - what if this signal is not fatal? 2181ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko Exit with 128 + signo then. */ 2182ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code += 128; 2183ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko } 2184ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2185ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko return exit_code; 2186ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko} 2187