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 3176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include "defs.h" 323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko#include <stdarg.h> 3376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/param.h> 3476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <fcntl.h> 3576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/resource.h> 3676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/wait.h> 3776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <sys/stat.h> 3876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <pwd.h> 3976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#include <grp.h> 4070b08530b80a6ee6591c38cf397fe0eeba1b4d7aRoland McGrath#include <dirent.h> 41f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko#include <sys/utsname.h> 42882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#ifdef HAVE_PRCTL 43882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin# include <sys/prctl.h> 44882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#endif 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 53327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND 54327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi/* if this is true do the stack trace for every system call */ 55327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementibool stack_trace_enabled = false; 56327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif 57a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko 58a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#if defined __NR_tkill 59a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) syscall(__NR_tkill, (tid), (sig)) 60a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#else 61a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko /* kill() may choose arbitrarily the target task of the process group 62a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko while we later wait on a that specific TID. PID process waits become 63a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko TID task specific waits for a process under ptrace(2). */ 64978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# warning "tkill(2) not available, risk of strace hangs!" 65a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko# define my_tkill(tid, sig) kill((tid), (sig)) 66a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko#endif 67a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko 685c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko/* Glue for systems without a MMU that cannot provide fork() */ 695c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if !defined(HAVE_FORK) 705c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# undef NOMMU_SYSTEM 715c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# define NOMMU_SYSTEM 1 725c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#endif 735c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if NOMMU_SYSTEM 745c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko# define fork() vfork() 755c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#endif 765c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko 77a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkocflag_t cflag = CFLAG_NONE; 78a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int followfork = 0; 79f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenkounsigned int ptrace_setoptions = 0; 80a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int xflag = 0; 818d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkobool need_fork_exec_workarounds = 0; 82a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool debug_flag = 0; 83a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool Tflag = 0; 84a34deadbb3419909d691de514a298f6b748f2d95Anton Blanchardbool iflag = 0; 85e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hillsbool count_wallclock = 0; 8601997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrangeunsigned int qflag = 0; 873454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* Which WSTOPSIG(status) value marks syscall traps? */ 8875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic unsigned int syscall_trap_sig = SIGTRAP; 89a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic unsigned int tflag = 0; 90a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool rflag = 0; 91a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkostatic bool print_pid_pfx = 0; 92b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 93b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* -I n */ 94b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkoenum { 95b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NOT_SET = 0, 96b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_ANYWHERE = 1, /* don't block/ignore any signals */ 97b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_WHILE_WAIT = 2, /* block fatal signals while decoding syscall. default */ 98b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_NEVER = 3, /* block fatal signals. default if '-o FILE PROG' */ 99b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko INTR_BLOCK_TSTP_TOO = 4, /* block fatal signals and SIGTSTP (^Z) */ 100b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko NUM_INTR_OPTS 101b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko}; 102b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenkostatic int opt_intr; 103b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko/* We play with signal mask only if this mode is active: */ 104b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko#define interactive (opt_intr == INTR_WHILE_WAIT) 105b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 106ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko/* 107ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * daemonized_tracer supports -D option. 108ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * With this option, strace forks twice. 109ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Unlike normal case, with -D *grandparent* process exec's, 110ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * becoming a traced process. Child exits (this prevents traced process 111ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * from having children it doesn't expect to have), and grandchild 112ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * attaches to grandparent similarly to strace -p PID. 113ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * This allows for more transparent interaction in cases 114ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * when process and its parent are communicating via signals, 115ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * wait() etc. Without -D, strace process gets lodged in between, 116ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * disrupting parent<->child link. 117ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 118ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenkostatic bool daemonized_tracer = 0; 11976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1205c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE 12131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int post_attach_sigstop = TCB_IGNORE_ONE_SIGSTOP; 12231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize (post_attach_sigstop == 0) 12331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 12431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define post_attach_sigstop TCB_IGNORE_ONE_SIGSTOP 12531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define use_seize 0 12631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 12731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 12817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig/* Sometimes we want to print only succeeding syscalls. */ 129a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool not_failing_only = 0; 13017f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig 1318a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards/* Show path associated with fd arguments */ 132a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkobool show_fd_path = 0; 1338a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards 13461e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenkostatic bool detach_on_execve = 0; 1352a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko/* Are we "strace PROG" and need to skip detach on first execve? */ 1362a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenkostatic bool skip_one_b_execve = 0; 1372a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko/* Are we "strace PROG" and need to hide everything until execve? */ 1382a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenkobool hide_log_until_execve = 0; 13961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko 140a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int exit_code = 0; 141a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levinstatic int strace_child = 0; 14275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic int strace_tracer_pid = 0; 143eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 144b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *username = NULL; 145ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic uid_t run_uid; 146ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic gid_t run_gid; 14776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 148a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenkounsigned int max_strlen = DEFAULT_STRLEN; 149ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinstatic int acolumn = DEFAULT_ACOLUMN; 150102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenkostatic char *acolumn_spaces; 1516764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko 152b9fe011cdfb0a3014e68a6e82007b6c2703a340bDmitry V. Levinstatic char *outfname = NULL; 1536764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko/* If -ff, points to stderr. Else, it's our common output log */ 1546764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenkostatic FILE *shared_log; 1556764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko 156000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenkostruct tcb *printing_tcp = NULL; 1576764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenkostatic struct tcb *current_tcp; 1586764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko 159ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic struct tcb **tcbtab; 1602b60c35b33cf22a88405c60db1e620880d05a7d4Denys Vlasenkostatic unsigned int nprocs, tcbtabsize; 161ead73bd3493c517fde508aecf6bc097aeae1752cDenys Vlasenkostatic const char *progname; 16276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 163eec8d5d6b028665a73169fda96e4e873cb8351f0Denys Vlasenkounsigned os_release; /* generated from uname()'s u.release */ 164f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1654a9ba989e65c12c50286a8423196236e6bac529dDenys Vlasenkostatic void detach(struct tcb *tcp); 166e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void cleanup(void); 167e5355de95c495dcfc616509f88c4fb5f9996b8e6Andreas Schwabstatic void interrupt(int sig); 16876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic sigset_t empty_set, blocked_set; 16976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 17076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman#ifdef HAVE_SIG_ATOMIC_T 17176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile sig_atomic_t interrupted; 172a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#else 17376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic volatile int interrupted; 174a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko#endif 17576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1762c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#ifndef HAVE_STRERROR 1772c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1782c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#if !HAVE_DECL_SYS_ERRLIST 1792c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern int sys_nerr; 1802c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoextern char *sys_errlist[]; 181a6d91ded3f2d5401e09a9c2fa442aabfbfe593a8Denys Vlasenko#endif 1822c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1832c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkoconst char * 1842c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenkostrerror(int err_no) 1852c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko{ 1862c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko static char buf[sizeof("Unknown error %d") + sizeof(int)*3]; 1872c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1882c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko if (err_no < 1 || err_no >= sys_nerr) { 1892c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko sprintf(buf, "Unknown error %d", err_no); 1902c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko return buf; 1912c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko } 1922c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko return sys_errlist[err_no]; 1932c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko} 1942c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 1952c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko#endif /* HAVE_STERRROR */ 1962c4fb905fef268a7e359ce3acaec4ee7ef087996Denys Vlasenko 19776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 198cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenkousage(FILE *ofp, int exitval) 19976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 20076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(ofp, "\ 201c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenkousage: strace [-CdffhiqrtttTvVxxy] [-I n] [-e expr]...\n\ 202c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko [-a column] [-o file] [-s strsize] [-P path]...\n\ 203c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\ 204c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko or: strace -c[df] [-I n] [-e expr]... [-O overhead] [-S sortby]\n\ 205c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko -p pid... / [-D] [-E var=val]... [-u username] PROG [ARGS]\n\ 20676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-c -- count time, calls, and errors for each syscall and report summary\n\ 207c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-C -- like -c but also print regular output\n\ 208e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills-w -- summarise syscall latency (default is system time)\n\ 2093e084ac349c3b177a75916254a4a5a02f29969e2Denys Vlasenko-d -- enable debug output to stderr\n\ 210b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko-D -- run tracer process as a detached grandchild, not as parent\n\ 21176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-f -- follow forks, -ff -- with output into separate files\n\ 21276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-i -- print instruction pointer at time of syscall\n\ 21376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-q -- suppress messages about attaching, detaching, etc.\n\ 21476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-r -- print relative timestamp, -t -- absolute timestamp, -tt -- with usecs\n\ 215cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-T -- print time spent in each syscall\n\ 216cdab1becb03eeae442719027fc26a17da464e5deDenys Vlasenko-v -- verbose mode: print unabbreviated argv, stat, termios, etc. args\n\ 21776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-x -- print non-ascii strings in hex, -xx -- print all strings in hex\n\ 2188a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-y -- print paths associated with file descriptor arguments\n\ 219c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-h -- print help message, -V -- print version\n\ 22076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-a column -- alignment COLUMN for printing syscall results (default %d)\n\ 22122efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko-b execve -- detach on this syscall\n\ 22276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-e expr -- a qualifying expression: option=[!]all or option=[!]val1[,val2]...\n\ 22338e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko options: trace, abbrev, verbose, raw, signal, read, write\n\ 224c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko-I interruptible --\n\ 225c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko 1: no signals are blocked\n\ 226c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko 2: fatal signals are blocked while decoding syscall (default)\n\ 227c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko 3: fatal signals are always blocked (default if '-o FILE PROG')\n\ 228c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko 4: fatal signals and SIGTSTP (^Z) are always blocked\n\ 229c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko (useful to make 'strace -o FILE PROG' not stop on ^Z)\n\ 23076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-o file -- send trace output to FILE instead of stderr\n\ 23176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-O overhead -- set overhead for tracing syscalls to OVERHEAD usecs\n\ 23276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-p pid -- trace process with process id PID, may be repeated\n\ 23376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-s strsize -- limit length of print strings to STRSIZE chars (default %d)\n\ 23476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-S sortby -- sort syscall counts by: time, calls, name, nothing (default %s)\n\ 23576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman-u username -- run command as username handling setuid and/or setgid\n\ 236de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var=val -- put var=val in the environment for command\n\ 237de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath-E var -- remove var from the environment for command\n\ 2388a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards-P path -- trace accesses to path\n\ 23961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko" 240327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND 2412734a7010fb24dbcad3c55565d08c5c9b81f8624Dmitry V. Levin"-k obtain stack trace between each syscall (experimental)\n\ 242327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi" 243327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif 24438e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko/* ancient, no one should use it 24538e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko-F -- attempt to follow vforks (deprecated, use -f)\n\ 24638e79bbb25bca8b79ae2866b93c4ddf26dea2b13Denys Vlasenko */ 24761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko/* this is broken, so don't document it 24817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig-z -- print only succeeding syscalls\n\ 24961e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko */ 250de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); 25176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(exitval); 25276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 25376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 25475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) __attribute__ ((noreturn)); 25575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void die(void) 25675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 25775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (strace_tracer_pid == getpid()) { 25875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cflag = 0; 25975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko cleanup(); 26075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 26175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko exit(1); 26275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 26375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 26475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkostatic void verror_msg(int err_no, const char *fmt, va_list p) 2653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 26682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko char *msg; 26782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 26844d053218ba658c901c3ab7dd905ab31ba417286Dmitry V. Levin fflush(NULL); 26982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko 27082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We want to print entire message with single fprintf to ensure 27182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * message integrity if stderr is shared with other programs. 27282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * Thus we use vasprintf + single fprintf. 27382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko */ 27482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko msg = NULL; 275cfad543087d98c5313fd7f006c0de69a1d87dc8eDenys Vlasenko if (vasprintf(&msg, fmt, p) >= 0) { 27682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 27782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s: %s\n", progname, msg, strerror(err_no)); 27882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 27982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: %s\n", progname, msg); 28082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko free(msg); 28182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } else { 28282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* malloc in vasprintf failed, try it without malloc */ 28382bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, "%s: ", progname); 28482bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko vfprintf(stderr, fmt, p); 28582bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko if (err_no) 28682bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko fprintf(stderr, ": %s\n", strerror(err_no)); 28782bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko else 28882bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko putc('\n', stderr); 28982bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko } 29082bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* We don't switch stderr to buffered, thus fprintf(stderr) 29182bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko * always flushes its output and this is not necessary: */ 29282bb78c149a1b527f4ae7a764be29a9c85067b29Denys Vlasenko /* fflush(stderr); */ 29375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 29475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 29575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg(const char *fmt, ...) 29675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 29775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 29875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 29975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 3003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko va_end(p); 30175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 3023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 30375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid error_msg_and_die(const char *fmt, ...) 30475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 30575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 30675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 30775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(0, fmt, p); 30875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 30975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 31075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 31175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg(const char *fmt, ...) 31275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 31375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 31475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 31575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 31675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_end(p); 31775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko} 31875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 31975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenkovoid perror_msg_and_die(const char *fmt, ...) 32075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko{ 32175422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_list p; 32275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko va_start(p, fmt); 32375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko verror_msg(errno, fmt, p); 32475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko die(); 3253454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 3263454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 3271d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenkovoid die_out_of_memory(void) 3281d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko{ 3291d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko static bool recursed = 0; 3301d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (recursed) 3311d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko exit(1); 3321d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko recursed = 1; 3331d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko error_msg_and_die("Out of memory"); 3341d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko} 3351d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko 336ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinstatic void 337ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levinerror_opt_arg(int opt, const char *arg) 338ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin{ 339ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_msg_and_die("Invalid -%c argument: '%s'", opt, arg); 340ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin} 341ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin 3425c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE 34331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic int 34431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkoptrace_attach_or_seize(int pid) 34531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 34631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int r; 34731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) 348c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko return ptrace(PTRACE_ATTACH, pid, 0L, 0L); 349c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko r = ptrace(PTRACE_SEIZE, pid, 0L, (unsigned long)ptrace_setoptions); 35031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (r) 35131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 352c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko r = ptrace(PTRACE_INTERRUPT, pid, 0L, 0L); 35331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return r; 35431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 35531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#else 35631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko# define ptrace_attach_or_seize(pid) ptrace(PTRACE_ATTACH, (pid), 0, 0) 35731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 35831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 359852f98a3824f6b8359df744af5772306410341abDenys Vlasenko/* 360852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Used when we want to unblock stopped traced process. 361852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Should be only used with PTRACE_CONT, PTRACE_DETACH and PTRACE_SYSCALL. 362852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Returns 0 on success or if error was ESRCH 363852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * (presumably process was killed while we talk to it). 364852f98a3824f6b8359df744af5772306410341abDenys Vlasenko * Otherwise prints error message and returns -1. 365852f98a3824f6b8359df744af5772306410341abDenys Vlasenko */ 366852f98a3824f6b8359df744af5772306410341abDenys Vlasenkostatic int 367852f98a3824f6b8359df744af5772306410341abDenys Vlasenkoptrace_restart(int op, struct tcb *tcp, int sig) 368852f98a3824f6b8359df744af5772306410341abDenys Vlasenko{ 369852f98a3824f6b8359df744af5772306410341abDenys Vlasenko int err; 370852f98a3824f6b8359df744af5772306410341abDenys Vlasenko const char *msg; 371852f98a3824f6b8359df744af5772306410341abDenys Vlasenko 372852f98a3824f6b8359df744af5772306410341abDenys Vlasenko errno = 0; 373852f98a3824f6b8359df744af5772306410341abDenys Vlasenko ptrace(op, tcp->pid, (void *) 0, (long) sig); 374852f98a3824f6b8359df744af5772306410341abDenys Vlasenko err = errno; 375235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko if (!err) 376852f98a3824f6b8359df744af5772306410341abDenys Vlasenko return 0; 377852f98a3824f6b8359df744af5772306410341abDenys Vlasenko 378852f98a3824f6b8359df744af5772306410341abDenys Vlasenko msg = "SYSCALL"; 379852f98a3824f6b8359df744af5772306410341abDenys Vlasenko if (op == PTRACE_CONT) 380852f98a3824f6b8359df744af5772306410341abDenys Vlasenko msg = "CONT"; 381852f98a3824f6b8359df744af5772306410341abDenys Vlasenko if (op == PTRACE_DETACH) 382852f98a3824f6b8359df744af5772306410341abDenys Vlasenko msg = "DETACH"; 383852f98a3824f6b8359df744af5772306410341abDenys Vlasenko#ifdef PTRACE_LISTEN 384852f98a3824f6b8359df744af5772306410341abDenys Vlasenko if (op == PTRACE_LISTEN) 385852f98a3824f6b8359df744af5772306410341abDenys Vlasenko msg = "LISTEN"; 386852f98a3824f6b8359df744af5772306410341abDenys Vlasenko#endif 387235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko /* 388235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * Why curcol != 0? Otherwise sometimes we get this: 389235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * 390235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * 10252 kill(10253, SIGKILL) = 0 391235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * <ptrace(SYSCALL,10252):No such process>10253 ...next decode... 392235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * 393235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * 10252 died after we retrieved syscall exit data, 394235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * but before we tried to restart it. Log looks ugly. 395235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko */ 3966764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp && current_tcp->curcol != 0) { 397235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko tprintf(" <ptrace(%s):%s>\n", msg, strerror(err)); 398235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko line_ended(); 399235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko } 400235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko if (err == ESRCH) 401235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko return 0; 402235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko errno = err; 403852f98a3824f6b8359df744af5772306410341abDenys Vlasenko perror_msg("ptrace(PTRACE_%s,pid:%d,sig:%d)", msg, tcp->pid, sig); 404852f98a3824f6b8359df744af5772306410341abDenys Vlasenko return -1; 405852f98a3824f6b8359df744af5772306410341abDenys Vlasenko} 406852f98a3824f6b8359df744af5772306410341abDenys Vlasenko 4071f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenkostatic void 40810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinset_cloexec_flag(int fd) 40910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 4101f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko int flags, newflags; 4111f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko 4121f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko flags = fcntl(fd, F_GETFD); 4131f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko if (flags < 0) { 4141f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko /* Can happen only if fd is bad. 4151f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * Should never happen: if it does, we have a bug 4161f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * in the caller. Therefore we just abort 4171f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko * instead of propagating the error. 4181f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko */ 4191f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko perror_msg_and_die("fcntl(%d, F_GETFD)", fd); 42010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 42110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 42210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin newflags = flags | FD_CLOEXEC; 42310de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (flags == newflags) 4241f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko return; 42510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 4261f532ab27db945c33818ba5298fdd78c52d229eaDenys Vlasenko fcntl(fd, F_SETFD, newflags); /* never fails */ 42710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 42810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 42975fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenkostatic void kill_save_errno(pid_t pid, int sig) 43075fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko{ 43175fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko int saved_errno = errno; 43275fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 43375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko (void) kill(pid, sig); 43475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko errno = saved_errno; 43575fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko} 43675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 437800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko/* 438800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * When strace is setuid executable, we have to swap uids 439800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * before and after filesystem and process management operations. 440800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */ 441800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void 442800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkoswap_uid(void) 443800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{ 444800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko int euid = geteuid(), uid = getuid(); 445800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 446800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (euid != uid && setreuid(euid, uid) < 0) { 447800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("setreuid"); 448800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 449800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko} 450800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 4510506f0f430c15677c7724f9c4500093e0e7e15d3Dmitry V. Levin#ifdef _LARGEFILE64_SOURCE 452d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# ifdef HAVE_FOPEN64 453d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# define fopen_for_output fopen64 454d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# else 455d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# define fopen_for_output fopen 456d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# endif 457c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_stat struct stat64 458c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define stat_file stat64 459c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_dirent struct dirent64 460c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define read_dir readdir64 461c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_rlimit struct rlimit64 462c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define set_rlimit setrlimit64 463800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#else 464800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko# define fopen_for_output fopen 465c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_stat struct stat 466c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define stat_file stat 467c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_dirent struct dirent 468c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define read_dir readdir 469c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define struct_rlimit struct rlimit 470c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin# define set_rlimit setrlimit 471800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif 472800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 473800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic FILE * 474800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostrace_fopen(const char *path) 475800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{ 476800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko FILE *fp; 477800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 478800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko swap_uid(); 479800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fp = fopen_for_output(path, "w"); 480800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (!fp) 481800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("Can't fopen '%s'", path); 482800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko swap_uid(); 483800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko set_cloexec_flag(fileno(fp)); 484800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko return fp; 485800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko} 486800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 487800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic int popen_pid = 0; 488800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 489800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#ifndef _PATH_BSHELL 490800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko# define _PATH_BSHELL "/bin/sh" 491800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif 492800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 493800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko/* 494800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * We cannot use standard popen(3) here because we have to distinguish 495800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * popen child process from other processes we trace, and standard popen(3) 496800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * does not export its child's pid. 497800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */ 498800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic FILE * 499800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostrace_popen(const char *command) 500800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{ 501800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko FILE *fp; 502519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko int pid; 503800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko int fds[2]; 504800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 505800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko swap_uid(); 506800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (pipe(fds) < 0) 507800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("pipe"); 508800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 509800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko set_cloexec_flag(fds[1]); /* never fails */ 510800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 511519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko pid = vfork(); 512519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko if (pid < 0) 513800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("vfork"); 514800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 515519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko if (pid == 0) { 516800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko /* child */ 517800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko close(fds[1]); 518800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (fds[0] != 0) { 519800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (dup2(fds[0], 0)) 520800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("dup2"); 521800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko close(fds[0]); 522800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 523800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko execl(_PATH_BSHELL, "sh", "-c", command, NULL); 524800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko perror_msg_and_die("Can't execute '%s'", _PATH_BSHELL); 525800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 526800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 527800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko /* parent */ 528519af5ad34fa19fb48e2bc6539135fe0852210c3Denys Vlasenko popen_pid = pid; 529800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko close(fds[0]); 530800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko swap_uid(); 531800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fp = fdopen(fds[1], "w"); 532800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (!fp) 533800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko die_out_of_memory(); 534800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko return fp; 535800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko} 536800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 5372e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 5382e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprintf(const char *fmt, ...) 5392e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 5402e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_list args; 5412e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 5422e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_start(args, fmt); 5436764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp) { 5446e4f3c1fa41851cb72230432db4be8e0c2993c7dDenys Vlasenko int n = strace_vfprintf(current_tcp->outf, fmt, args); 5452e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n < 0) { 5466764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp->outf != stderr) 5479a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin perror_msg("%s", outfname); 5482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } else 5496764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp->curcol += n; 5502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 5512e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko va_end(args); 5522e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 5532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 554d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#ifndef HAVE_FPUTS_UNLOCKED 555d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin# define fputs_unlocked fputs 556d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin#endif 557d354130b3ac060051b55cda46c45ab5f5574548dDmitry V. Levin 5582e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 5592e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotprints(const char *str) 5602e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 5616764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp) { 562142aee0a593ea9b42aa98347d998176b8a4e2489Denys Vlasenko int n = fputs_unlocked(str, current_tcp->outf); 5632e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (n >= 0) { 5646764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp->curcol += strlen(str); 5652e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko return; 5662e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 5676764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp->outf != stderr) 5689a71bcdab254e4cd93b8f1e93c659644eb70ea9bDmitry V. Levin perror_msg("%s", outfname); 5692e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 5702e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 5712e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 5722e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 5737de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkoline_ended(void) 5747de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko{ 5756764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp) { 5766764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp->curcol = 0; 5776764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko fflush(current_tcp->outf); 5786764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko } 5796764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (printing_tcp) { 5806764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko printing_tcp->curcol = 0; 5816764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko printing_tcp = NULL; 5826764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko } 5837de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko} 5847de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 5857de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenkovoid 5862e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkoprintleader(struct tcb *tcp) 5872e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 5887de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* If -ff, "previous tcb we printed" is always the same as current, 5897de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * because we have per-tcb output files. 5907de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 5917de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (followfork >= 2) 5927de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp = tcp; 5937de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 5942e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (printing_tcp) { 5956764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp = printing_tcp; 5967de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko if (printing_tcp->curcol != 0 && (followfork < 2 || printing_tcp == tcp)) { 5977de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* 5987de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 1: we have a shared log (i.e. not -ff), and last line 5997de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * wasn't finished (same or different tcb, doesn't matter). 6007de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * case 2: split log, we are the same tcb, but our last line 6017de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * didn't finish ("SIGKILL nuked us after syscall entry" etc). 6027de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko */ 6032e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprints(" <unfinished ...>\n"); 6047de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko printing_tcp->curcol = 0; 6052e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6062e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6072e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6082e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko printing_tcp = tcp; 6096764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp = tcp; 6106764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp->curcol = 0; 6112e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6122e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (print_pid_pfx) 6132e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%-5d ", tcp->pid); 6142e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (nprocs > 1 && !outfname) 6152e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("[pid %5u] ", tcp->pid); 6162e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6172e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag) { 6182e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko char str[sizeof("HH:MM:SS")]; 6192e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko struct timeval tv, dtv; 6202e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko static struct timeval otv; 6212e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6222e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko gettimeofday(&tv, NULL); 6232e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (rflag) { 6242e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (otv.tv_sec == 0) 6252e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 6262e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tv_sub(&dtv, &tv, &otv); 6272e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%6ld.%06ld ", 6282e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) dtv.tv_sec, (long) dtv.tv_usec); 6292e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko otv = tv; 6302e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6312e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else if (tflag > 2) { 6322e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%ld.%06ld ", 6332e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko (long) tv.tv_sec, (long) tv.tv_usec); 6342e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6352e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else { 6362e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko time_t local = tv.tv_sec; 6372e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko strftime(str, sizeof(str), "%T", localtime(&local)); 6382e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (tflag > 1) 6392e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s.%06ld ", str, (long) tv.tv_usec); 6402e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko else 6412e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko tprintf("%s ", str); 6422e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6432e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko } 6442e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko if (iflag) 6455a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko print_pc(tcp); 6462e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 6472e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6482e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkovoid 6492e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenkotabto(void) 6502e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko{ 6516764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp->curcol < acolumn) 6526764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko tprints(acolumn_spaces + current_tcp->curcol); 6532e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko} 6542e856a1c9215d292a7c41695928e8552788bc43cDenys Vlasenko 6553db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko/* Should be only called directly *after successful attach* to a tracee. 6563db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko * Otherwise, "strace -oFILE -ff -p<nonexistant_pid>" 6573db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko * may create bogus empty FILE.<nonexistant_pid>, and then die. 6583db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko */ 65910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levinstatic void 660800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkonewoutf(struct tcb *tcp) 66110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 6626764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko tcp->outf = shared_log; /* if not -ff mode, the same file is for all */ 6633db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko if (followfork >= 2) { 664800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko char name[520 + sizeof(int) * 3]; 665800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko sprintf(name, "%.512s.%u", outfname, tcp->pid); 666800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcp->outf = strace_fopen(name); 66710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 66810de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 66910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 670800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void 671800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkoexpand_tcbtab(void) 672800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{ 673800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko /* Allocate some more TCBs and expand the table. 674800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko We don't want to relocate the TCBs because our 675800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko callers have pointers and it would be a pain. 676800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko So tcbtab is a table of pointers. Since we never 677800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko free the TCBs, we allocate a single chunk of many. */ 678800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko int i = tcbtabsize; 679800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko struct tcb *newtcbs = calloc(tcbtabsize, sizeof(newtcbs[0])); 680800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko struct tcb **newtab = realloc(tcbtab, tcbtabsize * 2 * sizeof(tcbtab[0])); 681800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (!newtab || !newtcbs) 682800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko die_out_of_memory(); 683800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcbtabsize *= 2; 684800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcbtab = newtab; 685800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko while (i < tcbtabsize) 686800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcbtab[i++] = newtcbs++; 687800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko} 6884bfa6266eb6c67fce50907b427dff6bbd9e93794Roland McGrath 689800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic struct tcb * 6903db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenkoalloctcb(int pid) 69110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 692800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko int i; 693800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko struct tcb *tcp; 69410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 695800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (nprocs == tcbtabsize) 696800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko expand_tcbtab(); 697800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 698800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko for (i = 0; i < tcbtabsize; i++) { 699800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcp = tcbtab[i]; 700fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko if (!tcp->pid) { 701800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 702800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcp->pid = pid; 703800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#if SUPPORTED_PERSONALITIES > 1 704800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko tcp->currpers = current_personality; 705800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif 706327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi 707327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND 708327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi if (stack_trace_enabled) 7096141392856a170c9297783e6bfbd9fd970f76fdfMasatake YAMATO unwind_tcb_init(tcp); 710327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif 711327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi 712800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko nprocs++; 713800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (debug_flag) 714800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fprintf(stderr, "new tcb for pid %d, active tcbs:%d\n", tcp->pid, nprocs); 715800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko return tcp; 716800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 717800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 7183db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko error_msg_and_die("bug in alloctcb"); 71910de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 72010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 721800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkostatic void 722800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkodroptcb(struct tcb *tcp) 723800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko{ 724800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (tcp->pid == 0) 725800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko return; 72610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 7272b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO#ifdef USE_LIBUNWIND 7282b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO if (stack_trace_enabled) { 7292b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO unwind_tcb_fin(tcp); 7302b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO } 7312b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO#endif 7322b09df9731f97685b4c06e34ce4ff5f1686eb4c1Masatake YAMATO 733800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko nprocs--; 734800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (debug_flag) 735800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fprintf(stderr, "dropped tcb for pid %d, %d remain\n", tcp->pid, nprocs); 73610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 737800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (tcp->outf) { 7388511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (followfork >= 2) { 739800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (tcp->curcol != 0) 740800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 741800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fclose(tcp->outf); 742800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } else { 743800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (printing_tcp == tcp && tcp->curcol != 0) 744800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fprintf(tcp->outf, " <detached ...>\n"); 745800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fflush(tcp->outf); 746800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 747800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 748800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 7496764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko if (current_tcp == tcp) 7506764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp = NULL; 751800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (printing_tcp == tcp) 752800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko printing_tcp = NULL; 753800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 754800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko memset(tcp, 0, sizeof(*tcp)); 755800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko} 756800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko 757f1669e7975cb8d67448d52d9ae7dde3301d27273Denys Vlasenko/* Detach traced process. 758800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * Never call DETACH twice on the same process as both unattached and 759800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * attached-unstopped processes give the same ESRCH. For unattached process we 760800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * would SIGSTOP it and wait for its SIGSTOP notification forever. 76110de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin */ 7624a9ba989e65c12c50286a8423196236e6bac529dDenys Vlasenkostatic void 763800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenkodetach(struct tcb *tcp) 76410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin{ 765800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko int error; 766e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko int status; 76710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 768800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (tcp->flags & TCB_BPTSET) 769800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko clearbpt(tcp); 77010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 771800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko /* 772800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * Linux wrongly insists the child be stopped 773800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * before detaching. Arghh. We go through hoops 774800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko * to make a clean break of things. 775800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */ 776800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#if defined(SPARC) 777978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# undef PTRACE_DETACH 778978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# define PTRACE_DETACH PTRACE_SUNDETACH 779800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko#endif 78010de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 781e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (!(tcp->flags & TCB_ATTACHED)) 782e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto drop; 783e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko 784e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* We attached but possibly didn't see the expected SIGSTOP. 785e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * We must catch exactly one as otherwise the detached process 786e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * would be left stopped (process state T). 787e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 788e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (tcp->flags & TCB_IGNORE_ONE_SIGSTOP) 789e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto wait_loop; 790e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko 791e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko error = ptrace(PTRACE_DETACH, tcp->pid, 0, 0); 792e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (!error) { 793e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* On a clear day, you can see forever. */ 794e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto drop; 795e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 796e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (errno != ESRCH) { 797e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Shouldn't happen. */ 798e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko perror_msg("detach: ptrace(PTRACE_DETACH,%u)", tcp->pid); 799e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto drop; 800e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 801e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* ESRCH: process is either not stopped or doesn't exist. */ 802e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (my_tkill(tcp->pid, 0) < 0) { 803e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (errno != ESRCH) 804e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Shouldn't happen. */ 805e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko perror_msg("detach: tkill(%u,0)", tcp->pid); 806e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* else: process doesn't exist. */ 807e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto drop; 808e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 809e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Process is not stopped, need to stop it. */ 810e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (use_seize) { 811800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko /* 812e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * With SEIZE, tracee can be in group-stop already. 813e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * In this state sending it another SIGSTOP does nothing. 814e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Need to use INTERRUPT. 815e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Testcase: trying to ^C a "strace -p <stopped_process>". 816800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko */ 817e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko error = ptrace(PTRACE_INTERRUPT, tcp->pid, 0, 0); 818e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (!error) 819a2de9dacec47b7902b19f37edcc564faff346816Denys Vlasenko goto wait_loop; 820e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (errno != ESRCH) 821e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko perror_msg("detach: ptrace(PTRACE_INTERRUPT,%u)", tcp->pid); 822800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko } 823e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko else { 824e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko error = my_tkill(tcp->pid, SIGSTOP); 825e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (!error) 826e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto wait_loop; 827e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (errno != ESRCH) 828e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko perror_msg("detach: tkill(%u,SIGSTOP)", tcp->pid); 829e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 830e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Either process doesn't exist, or some weird error. */ 831e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko goto drop; 83210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 833a2de9dacec47b7902b19f37edcc564faff346816Denys Vlasenko wait_loop: 834e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* We end up here in three cases: 835e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * 1. We sent PTRACE_INTERRUPT (use_seize case) 836e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * 2. We sent SIGSTOP (!use_seize) 837e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * 3. Attach SIGSTOP was already pending (TCB_IGNORE_ONE_SIGSTOP set) 838e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 839e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko for (;;) { 840e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko int sig; 841e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (waitpid(tcp->pid, &status, __WALL) < 0) { 842e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (errno == EINTR) 843e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko continue; 844e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* 845e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * if (errno == ECHILD) break; 846e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * ^^^ WRONG! We expect this PID to exist, 847e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * and want to emit a message otherwise: 848e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 849e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko perror_msg("detach: waitpid(%u)", tcp->pid); 850e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko break; 851e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 852e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (!WIFSTOPPED(status)) { 853e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* 854e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Tracee exited or was killed by signal. 855e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * We shouldn't normally reach this place: 856e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * we don't want to consume exit status. 857e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Consider "strace -p PID" being ^C-ed: 858e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * we want merely to detach from PID. 859e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * 860e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * However, we _can_ end up here if tracee 861e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * was SIGKILLed. 862e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 863e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko break; 864e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 865e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko sig = WSTOPSIG(status); 866e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (debug_flag) 867e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko fprintf(stderr, "detach wait: event:%d sig:%d\n", 868e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko (unsigned)status >> 16, sig); 869e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (use_seize) { 870e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko unsigned event = (unsigned)status >> 16; 871e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (event == PTRACE_EVENT_STOP /*&& sig == SIGTRAP*/) { 87269e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko /* 873e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * sig == SIGTRAP: PTRACE_INTERRUPT stop. 874e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * sig == other: process was already stopped 875e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * with this stopping sig (see tests/detach-stopped). 876e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Looks like re-injecting this sig is not necessary 877e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * in DETACH for the tracee to remain stopped. 87869e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko */ 879e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko sig = 0; 88069e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko } 881e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* 882e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * PTRACE_INTERRUPT is not guaranteed to produce 883e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * the above event if other ptrace-stop is pending. 884e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * See tests/detach-sleeping testcase: 885e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * strace got SIGINT while tracee is sleeping. 886e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * We sent PTRACE_INTERRUPT. 887e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * We see syscall exit, not PTRACE_INTERRUPT stop. 888e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * We won't get PTRACE_INTERRUPT stop 889e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * if we would CONT now. Need to DETACH. 890e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 89169e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko if (sig == syscall_trap_sig) 89269e27ef24402059d1d103c83e511b62bc60310d2Denys Vlasenko sig = 0; 893e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* else: not sure in which case we can be here. 894e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Signal stop? Inject it while detaching. 895e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 896e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, sig); 897e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko break; 898e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 899e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Note: this check has to be after use_seize check */ 900e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* (else, in use_seize case SIGSTOP will be mistreated) */ 901e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (sig == SIGSTOP) { 902e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Detach, suppressing SIGSTOP */ 903e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko ptrace_restart(PTRACE_DETACH, tcp, 0); 904e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko break; 905e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko } 906e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (sig == syscall_trap_sig) 907e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko sig = 0; 908e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Can't detach just yet, may need to wait for SIGSTOP */ 909e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko error = ptrace_restart(PTRACE_CONT, tcp, sig); 910e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko if (error < 0) { 911e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko /* Should not happen. 912e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * Note: ptrace_restart returns 0 on ESRCH, so it's not it. 913e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko * ptrace_restart already emitted error message. 914e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko */ 915e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko break; 91610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 91710de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 9187dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko 919e2567d54dd57438d8ebe0167748cde7b661103e8Denys Vlasenko drop: 920800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko if (!qflag && (tcp->flags & TCB_ATTACHED)) 921800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko fprintf(stderr, "Process %u detached\n", tcp->pid); 92210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 923800ec8ffde1296b3f2cfdd838fb08f2ff2bbe946Denys Vlasenko droptcb(tcp); 92410de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin} 92510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin 926558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkostatic void 927558e5127fb68a7ab5c5ba6d8e976efd77e396cc2Denys Vlasenkoprocess_opt_p_list(char *opt) 928e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko{ 929e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko while (*opt) { 930e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko /* 931e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * We accept -p PID,PID; -p "`pidof PROG`"; -p "`pgrep PROG`". 932e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko * pidof uses space as delim, pgrep uses newline. :( 933e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko */ 934e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko int pid; 935e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char *delim = opt + strcspn(opt, ", \n\t"); 936e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko char c = *delim; 937e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 938e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = '\0'; 939ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin pid = string_to_uint(opt); 940e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid <= 0) { 941ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_msg_and_die("Invalid process id: '%s'", opt); 942e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 943e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (pid == strace_tracer_pid) { 944ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_msg_and_die("I'm sorry, I can't let you do that, Dave."); 945e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 946e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko *delim = c; 9473db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko alloctcb(pid); 948e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko if (c == '\0') 949e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko break; 950e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko opt = delim + 1; 951e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko } 952e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko} 953e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko 95402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 95502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstartup_attach(void) 95602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 95702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int tcbi; 95802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 95902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 96002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 96102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Block user interruptions as we would leave the traced 96202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * process stopped (process state T) if we would terminate in 9632e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko * between PTRACE_ATTACH and wait4() on SIGSTOP. 964b63256e69bf3f1a74aadb0e14556490bc8f4ef95Denys Vlasenko * We rely on cleanup() from this point on. 96502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 96602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 96702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 96802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 969ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 970ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pid_t pid = fork(); 971ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 972014ca3a53cb24d8e12e87f43a880efc52940a8beDenys Vlasenko perror_msg_and_die("fork"); 973ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 974ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid) { /* parent */ 975ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 97675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Wait for grandchild to attach to straced process 97775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * (grandparent). Grandchild SIGKILLs us after it attached. 97875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko * Grandparent's wait() is unblocked by our death, 979ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * it proceeds to exec the straced program. 980ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 981ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko pause(); 982ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko _exit(0); /* paranoia */ 983ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 98475422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* grandchild */ 98575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* We will be the tracer process. Remember our new pid: */ 98675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 987ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 988ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 98902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (tcbi = 0; tcbi < tcbtabsize; tcbi++) { 99002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp = tcbtab[tcbi]; 99144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko 992fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko if (!tcp->pid) 99375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; 99475fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko 995d116a7338645af45090aecc331701e999148d284Denys Vlasenko /* Is this a process we should attach to, but not yet attached? */ 99675fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (tcp->flags & TCB_ATTACHED) 99775fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko continue; /* no, we already attached it */ 998d116a7338645af45090aecc331701e999148d284Denys Vlasenko 999ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (followfork && !daemonized_tracer) { 10007a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3]; 100102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath DIR *dir; 100202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 100302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sprintf(procdir, "/proc/%d/task", tcp->pid); 100402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath dir = opendir(procdir); 100502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (dir != NULL) { 100602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath unsigned int ntid = 0, nerr = 0; 1007c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin struct_dirent *de; 1008381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 1009c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin while ((de = read_dir(dir)) != NULL) { 1010381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko struct tcb *cur_tcp; 1011381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko int tid; 1012381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko 10137a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (de->d_fileno == 0) 101402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 1015ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin /* we trust /proc filesystem */ 101602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tid = atoi(de->d_name); 101702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tid <= 0) 101802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 101902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++ntid; 102031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tid) < 0) { 102102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath ++nerr; 1022a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1023f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d failed\n", tid); 1024381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko continue; 1025f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } 1026a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1027381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko fprintf(stderr, "attach to pid %d succeeded\n", tid); 1028381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = tcp; 1029381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (tid != tcp->pid) 1030381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko cur_tcp = alloctcb(tid); 103131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko cur_tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 10323db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko newoutf(cur_tcp); 103302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 103402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath closedir(dir); 1035381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interactive) { 1036381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_SETMASK, &empty_set, NULL); 1037381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko if (interrupted) 1038381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko goto ret; 1039381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko sigprocmask(SIG_BLOCK, &blocked_set, NULL); 1040381dbc22929428579f50d9b0b39193feba93dcfdDenys Vlasenko } 10417a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko ntid -= nerr; 10427a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko if (ntid == 0) { 1043905e8e0e2f0a1f51ab92424dcb005885ea8b2459Denys Vlasenko perror_msg("attach: ptrace(PTRACE_ATTACH, ...)"); 104402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 104502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 104602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 104702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) { 10487a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko fprintf(stderr, ntid > 1 10493db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko? "Process %u attached with %u threads\n" 10503db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko: "Process %u attached\n", 105144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko tcp->pid, ntid); 105202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 105375fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko if (!(tcp->flags & TCB_ATTACHED)) { 1054f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* -p PID, we failed to attach to PID itself 1055f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * but did attach to some of its sibling threads. 1056f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Drop PID's tcp. 1057f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 1058f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko droptcb(tcp); 1059f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 106002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 10617a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (opendir worked) */ 10627a8bf065802f836901ae886317efcb4ed77cae7bDenys Vlasenko } /* if (-f) */ 106331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(tcp->pid) < 0) { 1064905e8e0e2f0a1f51ab92424dcb005885ea8b2459Denys Vlasenko perror_msg("attach: ptrace(PTRACE_ATTACH, ...)"); 106502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath droptcb(tcp); 106602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 106702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 106875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 10693db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko newoutf(tcp); 1070a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1071f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko fprintf(stderr, "attach to pid %d (main) succeeded\n", tcp->pid); 1072ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 1073ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (daemonized_tracer) { 1074ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko /* 1075ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Make parent go away. 1076ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko * Also makes grandparent's wait() unblock. 1077ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko */ 1078ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko kill(getppid(), SIGKILL); 1079ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 1080ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 108102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!qflag) 108202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath fprintf(stderr, 10839c3861d3177f3bfb12b24890fd118bcb77066abbDenys Vlasenko "Process %u attached\n", 108402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath tcp->pid); 1085f95397afb8aadf017b2d3d42056c5929dbf16775Denys Vlasenko } /* for each tcbtab[] */ 108602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 108744f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko ret: 108802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interactive) 108902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 109002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 109102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 1092f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko/* Stack-o-phobic exec helper, in the hope to work around 1093f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * NOMMU + "daemonized tracer" difficulty. 1094f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 1095f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostruct exec_params { 1096f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko int fd_to_close; 1097f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko uid_t run_euid; 1098f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko gid_t run_egid; 1099f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko char **argv; 1100f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko char *pathname; 1101f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko}; 1102f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostatic struct exec_params params_for_tracee; 1103f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkostatic void __attribute__ ((noinline, noreturn)) 1104f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenkoexec_or_die(void) 1105f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko{ 1106f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko struct exec_params *params = ¶ms_for_tracee; 1107f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1108f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (params->fd_to_close >= 0) 1109f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko close(params->fd_to_close); 1110f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (!daemonized_tracer && !use_seize) { 1111f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) { 1112f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("ptrace(PTRACE_TRACEME, ...)"); 1113f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1114f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1115f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1116f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (username != NULL) { 1117f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* 1118f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * It is important to set groups before we 1119f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * lose privileges on setuid. 1120f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 1121f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (initgroups(username, run_gid) < 0) { 1122f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("initgroups"); 1123f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1124f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (setregid(run_gid, params->run_egid) < 0) { 1125f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("setregid"); 1126f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1127f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (setreuid(run_uid, params->run_euid) < 0) { 1128f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("setreuid"); 1129f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1130f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1131f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko else if (geteuid() != 0) 1132f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (setreuid(run_uid, run_uid) < 0) { 1133f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("setreuid"); 1134f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1135f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1136f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (!daemonized_tracer) { 1137f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* 1138f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * Induce a ptrace stop. Tracer (our parent) 1139f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * will resume us with PTRACE_SYSCALL and display 1140f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * the immediately following execve syscall. 1141f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * Can't do this on NOMMU systems, we are after 1142f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * vfork: parent is blocked, stopping would deadlock. 1143f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 1144f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if (!NOMMU_SYSTEM) 1145f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko kill(getpid(), SIGSTOP); 1146f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } else { 1147f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko alarm(3); 1148f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* we depend on SIGCHLD set to SIG_DFL by init code */ 1149f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* if it happens to be SIG_IGN'ed, wait won't block */ 1150f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko wait(NULL); 1151f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko alarm(0); 1152f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko } 1153f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1154f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko execv(params->pathname, params->argv); 1155f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko perror_msg_and_die("exec"); 1156f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko} 1157f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 115802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrathstatic void 11591201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkostartup_child(char **argv) 116002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath{ 1161c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin struct_stat statbuf; 116202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath const char *filename; 116302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath char pathname[MAXPATHLEN]; 1164f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko int pid; 116502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath struct tcb *tcp; 116602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 116702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath filename = argv[0]; 116802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strchr(filename, '/')) { 116902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (strlen(filename) > sizeof pathname - 1) { 117002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath errno = ENAMETOOLONG; 1171cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("exec"); 117202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 117302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 117402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 117502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#ifdef USE_DEBUGGING_EXEC 117602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* 117702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * Debuggers customarily check the current directory 117802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * first regardless of the path but doing that gives 117902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * security geeks a panic attack. 118002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath */ 1181c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin else if (stat_file(filename, &statbuf) == 0) 118202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname, filename); 118302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath#endif /* USE_DEBUGGING_EXEC */ 118402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 118530145dda9d7ff70df1d5ad750a183572c73e8963Dmitry V. Levin const char *path; 118602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath int m, n, len; 118702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 118802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath for (path = getenv("PATH"); path && *path; path += m) { 11894f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko const char *colon = strchr(path, ':'); 11904f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko if (colon) { 11914f3df078b26899afe0f25d8651b06a5a5b5143e2Denys Vlasenko n = colon - path; 119202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n + 1; 119302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 119402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else 119502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath m = n = strlen(path); 119602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (n == 0) { 119702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (!getcwd(pathname, MAXPATHLEN)) 119802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 119902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = strlen(pathname); 120002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 120102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else if (n > sizeof pathname - 1) 120202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath continue; 120302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath else { 120402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strncpy(pathname, path, n); 120502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath len = n; 120602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 120702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (len && pathname[len - 1] != '/') 120802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath pathname[len++] = '/'; 120902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath strcpy(pathname + len, filename); 1210c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin if (stat_file(pathname, &statbuf) == 0 && 121102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath /* Accept only regular files 121202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath with some execute bits set. 121302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath XXX not perfect, might still fail */ 121402203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath S_ISREG(statbuf.st_mode) && 121502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath (statbuf.st_mode & 0111)) 121602203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath break; 121702203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 121802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 1219c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin if (stat_file(pathname, &statbuf) < 0) { 1220cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("Can't stat '%s'", filename); 122102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 1222f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1223f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko params_for_tracee.fd_to_close = (shared_log != stderr) ? fileno(shared_log) : -1; 1224f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko params_for_tracee.run_euid = (statbuf.st_mode & S_ISUID) ? statbuf.st_uid : run_uid; 1225f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko params_for_tracee.run_egid = (statbuf.st_mode & S_ISGID) ? statbuf.st_gid : run_gid; 1226f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko params_for_tracee.argv = argv; 1227f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* 1228f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * On NOMMU, can be safely freed only after execve in tracee. 1229f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * It's hard to know when that happens, so we just leak it. 1230f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 123105f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko params_for_tracee.pathname = NOMMU_SYSTEM ? strdup(pathname) : pathname; 1232f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko 1233882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#if defined HAVE_PRCTL && defined PR_SET_PTRACER && defined PR_SET_PTRACER_ANY 1234882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin if (daemonized_tracer) 1235882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY); 1236882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin#endif 1237882478a0724c04287ac232c212312c8e094cce43Dmitry V. Levin 1238e8681c926c02dad48aca66f3aba1e33122002c36Denys Vlasenko pid = fork(); 1239ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko if (pid < 0) { 1240cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko perror_msg_and_die("fork"); 1241ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 1242f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko if ((pid != 0 && daemonized_tracer) 1243f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko || (pid == 0 && !daemonized_tracer) 1244ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko ) { 1245f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* We are to become the tracee. Two cases: 1246f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * -D: we are parent 1247f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * not -D: we are child 1248f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 1249f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko exec_or_die(); 125002203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath } 1251ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko 12522e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* We are the tracer */ 125375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 12542e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko if (!daemonized_tracer) { 1255e8681c926c02dad48aca66f3aba1e33122002c36Denys Vlasenko strace_child = pid; 125631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!use_seize) { 125731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* child did PTRACE_TRACEME, nothing to do in parent */ 125831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } else { 12595c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko if (!NOMMU_SYSTEM) { 126031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Wait until child stopped itself */ 126131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status; 126231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (waitpid(pid, &status, WSTOPPED) < 0) { 126331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 126431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 126531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("waitpid"); 126631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 126731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) { 126875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 126931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Unexpected wait status %x", status); 127031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 127131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 12725c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko /* Else: NOMMU case, we have no way to sync. 127331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * Just attach to it as soon as possible. 127431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This means that we may miss a few first syscalls... 127531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 127631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 127731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_attach_or_seize(pid)) { 127875fe85c2ee83a31afe0c8f1468da28deb1c2bc28Denys Vlasenko kill_save_errno(pid, SIGKILL); 127931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("Can't attach to %d", pid); 128031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 12815c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko if (!NOMMU_SYSTEM) 128231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGCONT); 128331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 12842e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko tcp = alloctcb(pid); 12855c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko if (!NOMMU_SYSTEM) 1286fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 1287f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko else 1288fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP; 12893db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko newoutf(tcp); 12902e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko } 12912e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko else { 129205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko /* With -D, we are *child* here, IOW: different pid. Fetch it: */ 12932e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko strace_tracer_pid = getpid(); 12942e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko /* The tracee is our parent: */ 12952e968c0bb7b89aa43df726eb651f0b51572b4194Denys Vlasenko pid = getppid(); 1296f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko alloctcb(pid); 1297f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko /* attaching will be done later, by startup_attach */ 12983db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko /* note: we don't do newoutf(tcp) here either! */ 12995c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko 1300f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* NOMMU BUG! -D mode is active, we (child) return, 1301f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * and we will scribble over parent's stack! 1302f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * When parent later unpauses, it segfaults. 1303f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * 1304f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * We work around it 1305f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * (1) by declaring exec_or_die() NORETURN, 1306f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * hopefully compiler will just jump to it 1307f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * instead of call (won't push anything to stack), 1308f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * (2) by trying very hard in exec_or_die() 1309f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * to not use any stack, 1310f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * (3) having a really big (MAXPATHLEN) stack object 1311f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * in this function, which creates a "buffer" between 1312f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * child's and parent's stack pointers. 1313f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * This may save us if (1) and (2) failed 1314f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * and compiler decided to use stack in exec_or_die() anyway 1315f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * (happens on i386 because of stack parameter passing). 131605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko * 131705f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko * A cleaner solution is to use makecontext + setcontext 131805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko * to create a genuine separate stack and execute on it. 1319f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 1320ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko } 132102203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath} 132202203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 1323b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao/* 1324b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * Test whether the kernel support PTRACE_O_TRACECLONE et al options. 1325b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, 1326b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin * and then see which options are supported by the kernel. 1327b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao */ 13288d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkostatic int 13293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_followfork(void) 1330b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao{ 13312fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin int pid, expected_grandchild = 0, found_grandchild = 0; 13322fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACECLONE | 13332fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEFORK | 13342fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin PTRACE_O_TRACEVFORK; 1335b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao 133605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko /* Need fork for test. NOMMU has no forks */ 133705f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko if (NOMMU_SYSTEM) 133805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko goto worked; /* be bold, and pretend that test succeeded */ 133905f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko 13405d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pid = fork(); 13415d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid < 0) 134204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 13435d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pid == 0) { 134404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin pid = getpid(); 134531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 134604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 134704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 13484c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGSTOP); 134904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (fork() < 0) 135004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("fork"); 135104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin _exit(0); 1352b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 1353b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 1354b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin while (1) { 1355b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin int status, tracee_pid; 1356b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin 135704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin errno = 0; 1358b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin tracee_pid = wait(&status); 135904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid <= 0) { 1360b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (errno == EINTR) 1361b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin continue; 13624c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko if (errno == ECHILD) 1363b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao break; 136404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 136504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 136604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 136704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 136804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFEXITED(status)) { 136904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WEXITSTATUS(status)) { 137004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 137104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 137204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 137304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 137404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 137504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 137604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 137704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 137804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 137904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 138004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 138104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 138204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 138304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (!WIFSTOPPED(status)) { 138404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (tracee_pid != pid) 138504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 13864c65c44478f1591d96cda425d78451334fe1d401Denys Vlasenko kill_save_errno(pid, SIGKILL); 138704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 138804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 1389b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 1390b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin if (tracee_pid != pid) { 13912fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin found_grandchild = tracee_pid; 139204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0) { 139304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(tracee_pid, SIGKILL); 139404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 139504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_CONT doesn't work"); 139604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 139704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin continue; 1398b1467440f7c57c4ba9dc17ab9756e45c84d0adbeDmitry V. Levin } 139904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin switch (WSTOPSIG(status)) { 140004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGSTOP: 140104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0, test_options) < 0 140204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 140304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 140404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 140504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin case SIGTRAP: 140604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (status >> 16 == PTRACE_EVENT_FORK) { 140704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin long msg = 0; 14082fabd0eaf05379bf121c208ee7a1c129ce1f2f18Dmitry V. Levin 140904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_GETEVENTMSG, pid, 141004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin NULL, (long) &msg) == 0) 141104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin expected_grandchild = msg; 1412b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 141304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin break; 141404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 141504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) { 141604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 141704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 1418b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 1419b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao } 142004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (expected_grandchild && expected_grandchild == found_grandchild) { 142105f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko worked: 1422f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1423a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 142404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin fprintf(stderr, "ptrace_setoptions = %#x\n", 142504f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin ptrace_setoptions); 14268d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko return 0; 142704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 142804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACECLONE failed, " 142904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 14308d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko return 1; 1431b13c0de058585de7d47778a8923426b89bfffbb5Wang Chao} 14323454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 14333454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko/* 14343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Test whether the kernel support PTRACE_O_TRACESYSGOOD. 14353454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * First fork a new child, call ptrace(PTRACE_SETOPTIONS) on it, 14363454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and then see whether it will stop with (SIGTRAP | 0x80). 14373454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * 14383454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * Use of this option enables correct handling of user-generated SIGTRAPs, 14393454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and SIGTRAPs generated by special instructions such as int3 on x86: 1440329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko 1441329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko# compile with: gcc -nostartfiles -nostdlib -o int3 int3.S 1442329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko_start: .globl _start 1443329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko int3 1444329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko movl $42, %ebx 1445329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko movl $1, %eax 1446329fa3919d0da95ec32949c2092dc40dac6a9d5bDenys Vlasenko int $0x80 14473454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 14488d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenkostatic int 14493454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenkotest_ptrace_setoptions_for_all(void) 14503454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko{ 145104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin const unsigned int test_options = PTRACE_O_TRACESYSGOOD | 145204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin PTRACE_O_TRACEEXEC; 14533454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int pid; 14543454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int it_worked = 0; 14553454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 145605f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko /* Need fork for test. NOMMU has no forks */ 14575c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko if (NOMMU_SYSTEM) 145805f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko goto worked; /* be bold, and pretend that test succeeded */ 14597ff5ed932568a8049c3ca134da374f64c3e255ceMike Frysinger 14603454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = fork(); 14613454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid < 0) 146275422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("fork"); 14633454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 14643454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (pid == 0) { 14653454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko pid = getpid(); 14663454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_TRACEME, 0L, 0L, 0L) < 0) 146775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko /* Note: exits with exitcode 1 */ 146804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: PTRACE_TRACEME doesn't work", 146904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__); 14703454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGSTOP); 14713454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko _exit(0); /* parent should see entry into this syscall */ 14723454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 14733454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 14743454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko while (1) { 14753454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko int status, tracee_pid; 14763454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 14773454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko errno = 0; 14783454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko tracee_pid = wait(&status); 14793454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (tracee_pid <= 0) { 14803454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (errno == EINTR) 14813454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko continue; 148204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 148304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg_and_die("%s: unexpected wait result %d", 148404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, tracee_pid); 148575422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko } 148675422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WIFEXITED(status)) { 148775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko if (WEXITSTATUS(status) == 0) 148875422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko break; 148904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected exit status %u", 149004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WEXITSTATUS(status)); 149104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin } 149204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (WIFSIGNALED(status)) { 149304f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected signal %u", 149404f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, WTERMSIG(status)); 14953454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 14963454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (!WIFSTOPPED(status)) { 14973454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko kill(pid, SIGKILL); 149804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg_and_die("%s: unexpected wait status %x", 149904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin __func__, status); 15003454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15013454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == SIGSTOP) { 15023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko /* 15033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * We don't check "options aren't accepted" error. 15043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * If it happens, we'll never get (SIGTRAP | 0x80), 15053454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * and thus will decide to not use the option. 15063454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko * IOW: the outcome of the test will be correct. 15073454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko */ 150804f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (ptrace(PTRACE_SETOPTIONS, pid, 0L, test_options) < 0 150904f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin && errno != EINVAL && errno != EIO) 151004f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin perror_msg("PTRACE_SETOPTIONS"); 15113454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15123454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (WSTOPSIG(status) == (SIGTRAP | 0x80)) { 15133454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko it_worked = 1; 15143454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15153454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (ptrace(PTRACE_SYSCALL, pid, 0L, 0L) < 0) { 151604f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin kill_save_errno(pid, SIGKILL); 151775422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko perror_msg_and_die("PTRACE_SYSCALL doesn't work"); 15183454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15193454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15203454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 15213454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko if (it_worked) { 152205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko worked: 152375422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko syscall_trap_sig = (SIGTRAP | 0x80); 1524f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions |= test_options; 1525a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 1526f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko fprintf(stderr, "ptrace_setoptions = %#x\n", 1527f44cce48bbbd573cc5ae801f69f857433160b03aDenys Vlasenko ptrace_setoptions); 15288d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko return 0; 15293454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 15303454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko 153104f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin error_msg("Test for PTRACE_O_TRACESYSGOOD failed, " 153204f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin "giving up using this feature."); 15338d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko return 1; 15343454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko} 153531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 15365c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE 153731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkostatic void 153831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenkotest_ptrace_seize(void) 153931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko{ 154031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int pid; 154131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 154205f325199a6cf36c92560d5a08b56652502705c2Denys Vlasenko /* Need fork for test. NOMMU has no forks */ 15435c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko if (NOMMU_SYSTEM) { 15445c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko post_attach_sigstop = 0; /* this sets use_seize to 1 */ 15455c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko return; 15465c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko } 15475c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko 154831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pid = fork(); 154931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid < 0) 155031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("fork"); 155131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 155231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (pid == 0) { 155331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko pause(); 155431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko _exit(0); 155531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 155631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 155731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* PTRACE_SEIZE, unlike ATTACH, doesn't force tracee to trap. After 155831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * attaching tracee continues to run unless a trap condition occurs. 155931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * PTRACE_SEIZE doesn't affect signal or group stop state. 156031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 156126bc0606d96d05d30ba263939a0451889340a64cDenys Vlasenko if (ptrace(PTRACE_SEIZE, pid, 0, 0) == 0) { 156231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko post_attach_sigstop = 0; /* this sets use_seize to 1 */ 1563a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko } else if (debug_flag) { 156431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko fprintf(stderr, "PTRACE_SEIZE doesn't work\n"); 156531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 156631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 156731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko kill(pid, SIGKILL); 156831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 156931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko while (1) { 157031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int status, tracee_pid; 157131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 157231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko errno = 0; 157331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko tracee_pid = waitpid(pid, &status, 0); 157431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (tracee_pid <= 0) { 157531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (errno == EINTR) 157631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 157731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko perror_msg_and_die("%s: unexpected wait result %d", 157831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, tracee_pid); 157931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 158031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (WIFSIGNALED(status)) { 158131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko return; 158231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 158331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko error_msg_and_die("%s: unexpected wait status %x", 158431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko __func__, status); 158531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 158631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko} 1587978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko#else /* !USE_SEIZE */ 1588978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko# define test_ptrace_seize() ((void)0) 1589978fbc901c4fe260caaa5881e54bd9cb54022101Denys Vlasenko#endif 159031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 15916e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenkostatic unsigned 1592f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenkoget_os_release(void) 1593f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko{ 15946e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko unsigned rel; 15956e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko const char *p; 1596f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct utsname u; 1597f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (uname(&u) < 0) 1598f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko perror_msg_and_die("uname"); 15996e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko /* u.release has this form: "3.2.9[-some-garbage]" */ 16006e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko rel = 0; 16016e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p = u.release; 16026e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko for (;;) { 16036e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (!(*p >= '0' && *p <= '9')) 16046e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko error_msg_and_die("Bad OS release string: '%s'", u.release); 16056e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko /* Note: this open-codes KERNEL_VERSION(): */ 16066e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko rel = (rel << 8) | atoi(p); 16076e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (rel >= KERNEL_VERSION(1,0,0)) 16086e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko break; 16096e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko while (*p >= '0' && *p <= '9') 16106e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p++; 16110dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin if (*p != '.') { 16120dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin if (rel >= KERNEL_VERSION(0,1,0)) { 16130dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin /* "X.Y-something" means "X.Y.0" */ 16140dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin rel <<= 8; 16150dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin break; 16160dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin } 16176e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko error_msg_and_die("Bad OS release string: '%s'", u.release); 16180dbc80de895c25769791b7726022a274695eec31Dmitry V. Levin } 16196e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko p++; 16206e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko } 16216e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko return rel; 1622f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko} 1623f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1624ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko/* 1625ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Initialization part of main() was eating much stack (~0.5k), 1626ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * which was unused after init. 1627ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * We can reuse it if we move init code into a separate function. 1628ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * 1629ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * Don't want main() to inline us and defeat the reason 1630ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko * we have a separate function. 1631ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko */ 1632ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkostatic void __attribute__ ((noinline)) 1633ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoinit(int argc, char *argv[]) 163476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 163576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 1636ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin int c, i; 163706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin int optF = 0; 163876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct sigaction sa; 163976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 164008b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin progname = argv[0] ? argv[0] : "strace"; 164108b623eb84266d4a2defc619fa78400c4e4f0dc1Dmitry V. Levin 1642a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko /* Make sure SIGCHLD has the default action so that waitpid 1643a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko definitely works without losing track of children. The user 1644a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko should not have given us a bogus state to inherit, but he might 1645a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko have. Arguably we should detect SIG_IGN here and pass it on 1646a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko to children, but probably noone really needs that. */ 1647a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko signal(SIGCHLD, SIG_DFL); 1648a509054aeee00a89a2250919f74bd849c67ded61Denys Vlasenko 164975422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko strace_tracer_pid = getpid(); 165075422766d51cf96ea081977c9d0b26b2ba1a8adeDenys Vlasenko 16516e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko os_release = get_os_release(); 1652f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 1653ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath /* Allocate the initial tcbtab. */ 1654ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcbtabsize = argc; /* Surely enough for all -p args. */ 16554f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab = calloc(tcbtabsize, sizeof(tcbtab[0])); 16561d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcbtab) 16571d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 16584f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcp = calloc(tcbtabsize, sizeof(*tcp)); 16591d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (!tcp) 16601d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 16614f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko for (c = 0; c < tcbtabsize; c++) 16624f12af24e4c1d4e44b84ba6d5e72e6d8b6490e35Denys Vlasenko tcbtab[c] = tcp++; 1663ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath 16646764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko shared_log = stderr; 1665138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_sortby(DEFAULT_SORTBY); 1666138c6a334fd9949d6147c63ada02cf55472e02c0Roland McGrath set_personality(DEFAULT_PERSONALITY); 166776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("trace=all"); 166876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=all"); 166976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("verbose=all"); 167074ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko#if DEFAULT_QUAL_FLAGS != (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE) 167174ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko# error Bug in DEFAULT_QUAL_FLAGS 167274ec14f968a418691b851cbbfeb0269174c64b08Denys Vlasenko#endif 167376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("signal=all"); 167476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman while ((c = getopt(argc, argv, 1675e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills "+b:cCdfFhiqrtTvVwxyz" 1676327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND 1677327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi "k" 1678327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif 1679ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko "D" 1680b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko "a:e:o:O:p:s:S:u:E:P:I:")) != EOF) { 168176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman switch (c) { 168261e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko case 'b': 168322efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko if (strcmp(optarg, "execve") != 0) 168422efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko error_msg_and_die("Syscall '%s' for -b isn't supported", 168522efaf0028ddec8f9ed2a2a11e9baaa201594a33Denys Vlasenko optarg); 168661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko detach_on_execve = 1; 168761e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko break; 168876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'c': 1689e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_BOTH) { 1690c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko error_msg_and_die("-c and -C are mutually exclusive"); 1691e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1692e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_ONLY_STATS; 1693e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin break; 1694e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin case 'C': 1695e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 1696c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko error_msg_and_die("-c and -C are mutually exclusive"); 1697e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin } 1698e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin cflag = CFLAG_BOTH; 169976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 170076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'd': 1701a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko debug_flag = 1; 170276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1703ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko case 'D': 1704ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko daemonized_tracer = 1; 1705ecfe2f19f963b5c2f176c5e70d42654d7429ce3eDenys Vlasenko break; 170641c48227a86a176da333f713d5047240885f25ccRoland McGrath case 'F': 170706350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin optF = 1; 170806350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin break; 170976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'f': 171076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman followfork++; 171176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 171276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'h': 171376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stdout, 0); 171476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 171576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'i': 1716a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko iflag = 1; 171776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 171876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'q': 171901997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange qflag++; 172076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 172176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'r': 1722a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko rflag = 1; 1723a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko /* fall through to tflag++ */ 172476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 't': 172576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tflag++; 172676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 172776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'T': 1728a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko Tflag = 1; 172976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1730e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills case 'w': 1731e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills count_wallclock = 1; 1732e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills break; 173376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'x': 173476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman xflag++; 173576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 17368a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'y': 17378a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards show_fd_path = 1; 17388a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 173976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'v': 174076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify("abbrev=none"); 174176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 174276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'V': 17439c9a2534e361b683f1e4e08804b7166a01475bf1Roland McGrath printf("%s -- version %s\n", PACKAGE_NAME, VERSION); 174476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman exit(0); 174576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 174617f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig case 'z': 174717f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig not_failing_only = 1; 174817f8fb3484e94976882f65b7a3aaffc6f24cd75dMichal Ludvig break; 174976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'a': 1750ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin acolumn = string_to_uint(optarg); 1751102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (acolumn < 0) 1752ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_opt_arg(c, optarg); 175376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 175476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'e': 175576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qualify(optarg); 175676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 175776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'o': 175876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman outfname = strdup(optarg); 175976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 176076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'O': 1761ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin i = string_to_uint(optarg); 1762ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin if (i < 0) 1763ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_opt_arg(c, optarg); 1764ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin set_overhead(i); 176576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 176676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'p': 1767e8172b79e3dd35a136f4dc4d4de9df5bb4565c01Denys Vlasenko process_opt_p_list(optarg); 176876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 17698a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards case 'P': 17707239dbcf2dff792f408c60fe3e278f707fdf497bDenys Vlasenko pathtrace_select(optarg); 17718a08277d13d0378c2ff3ce851534c3bf7e31defaGrant Edwards break; 177276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 's': 1773ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin i = string_to_uint(optarg); 1774ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin if (i < 0) 1775ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_opt_arg(c, optarg); 1776ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin max_strlen = i; 177776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 177876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'S': 177976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman set_sortby(optarg); 178076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 178176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman case 'u': 178276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman username = strdup(optarg); 178376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 1784327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#ifdef USE_LIBUNWIND 1785327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi case 'k': 1786327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi stack_trace_enabled = true; 1787327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi break; 1788327064b63722a4400058e0e7e9b39d9e34b14b57Luca Clementi#endif 1789de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath case 'E': 17901d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko if (putenv(optarg) < 0) 17911d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1792de6e53308ca58da7d357f8114afc74fff7a18043Roland McGrath break; 1793b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko case 'I': 1794ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin opt_intr = string_to_uint(optarg); 1795ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin if (opt_intr <= 0 || opt_intr >= NUM_INTR_OPTS) 1796ccee169ab6aa4ae7515198dadcef5dd2286ede4bDmitry V. Levin error_opt_arg(c, optarg); 1797b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko break; 179876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman default: 179976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman usage(stderr, 1); 180076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman break; 180176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 180276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1803837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko argv += optind; 1804837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* argc -= optind; - no need, argc is not used below */ 180576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1806102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces = malloc(acolumn + 1); 1807102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko if (!acolumn_spaces) 18081d46ba57a8ab16b353b531f2bbefe2ad7f354ca9Denys Vlasenko die_out_of_memory(); 1809102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko memset(acolumn_spaces, ' ', acolumn); 1810102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko acolumn_spaces[acolumn] = '\0'; 1811102ec4935440ff52a7fa3566154a84cc2473f16aDenys Vlasenko 1812837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko /* Must have PROG [ARGS], or -p PID. Not both. */ 1813fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (!argv[0] == !nprocs) 1814ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath usage(stderr, 1); 1815ce0d15442eec017b1dcbfdd14ac92e73c39c586aRoland McGrath 1816fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 && daemonized_tracer) { 1817c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko error_msg_and_die("-D and -p are mutually exclusive"); 1818d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao } 1819d322a4bbe118642c4c9b170451a601a1e80b72d6Wang Chao 182006350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin if (!followfork) 182106350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin followfork = optF; 182206350dba7505eda4b8220cca8a9b112504fafc4dDmitry V. Levin 18233db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko if (followfork >= 2 && cflag) { 1824c5ccfa450b9818ef9eab94f9d15189e50a796937Denys Vlasenko error_msg_and_die("(-c or -C) and -ff are mutually exclusive"); 1825cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath } 1826cb9def6975f28933ada9d35f05c6fba9ab3fe1fdRoland McGrath 1827e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills if (count_wallclock && !cflag) { 1828e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills error_msg_and_die("-w must be given with (-c or -C)"); 1829e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills } 1830e53bf23f1c33076090b51184b82af4dd98d0c51cMark Hills 18312727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (cflag == CFLAG_ONLY_STATS) { 18322727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (iflag) 18332727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 'i'); 18342727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#ifdef USE_LIBUNWIND 18352727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (stack_trace_enabled) 18362727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 'k'); 18372727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#endif 18382727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (rflag) 18392727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 'r'); 18402727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (tflag) 18412727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 't'); 18422727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (Tflag) 18432727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 'T'); 18442727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (show_fd_path) 18452727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin error_msg("-%c has no effect with -c", 'y'); 18462727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin } 18472727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin 18482727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#ifdef USE_LIBUNWIND 18492727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin if (stack_trace_enabled) 18502727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin unwind_init(); 18512727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin#endif 18522727aae37c56eb2620699388513ef5bbb0af2b7eDmitry V. Levin 185376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* See if they want to run as another user. */ 185476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (username != NULL) { 185576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct passwd *pent; 185676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 185776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (getuid() != 0 || geteuid() != 0) { 1858cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("You must be root to use the -u option"); 185976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 18605d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko pent = getpwnam(username); 18615d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko if (pent == NULL) { 1862cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko error_msg_and_die("Cannot find user '%s'", username); 186376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = pent->pw_uid; 186576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = pent->pw_gid; 186676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 186776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman else { 186876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_uid = getuid(); 186976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman run_gid = getgid(); 187076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 187176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 18728d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko /* 18738d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko * On any reasonably recent Linux kernel (circa about 2.5.46) 18748d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko * need_fork_exec_workarounds should stay 0 after these tests: 18758d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko */ 18768d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko /*need_fork_exec_workarounds = 0; - already is */ 187704f8b4860f12512186481ca21dbd311d9d612326Dmitry V. Levin if (followfork) 18788d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko need_fork_exec_workarounds = test_ptrace_setoptions_followfork(); 18798d4ca0c8cd81329ad730ab52b1e0653c1bbea803Denys Vlasenko need_fork_exec_workarounds |= test_ptrace_setoptions_for_all(); 188031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko test_ptrace_seize(); 18818044bc1463f62ae5f974cc531576bc18dade0337Dmitry V. Levin 188276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* Check if they want to redirect the output. */ 188376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (outfname) { 188437b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* See if they want to pipe the output. */ 188537b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath if (outfname[0] == '|' || outfname[0] == '!') { 188637b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath /* 188737b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * We can't do the <outfname>.PID funny business 188837b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath * when using popen, so prohibit it. 188937b9a66dd4cf063c4a3d1002f4196cd7ef9ae5b7Roland McGrath */ 18903db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko if (followfork >= 2) 18917dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko error_msg_and_die("Piping the output and -ff are mutually exclusive"); 18926764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko shared_log = strace_popen(outfname + 1); 189354b4f79216c819ec93aaf5031acb1772fccef7a9Wichert Akkerman } 18943db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko else if (followfork < 2) 18956764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko shared_log = strace_fopen(outfname); 1896328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko } else { 1897328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko /* -ff without -o FILE is the same as single -f */ 18983db3b26101443dccbea959ba0abcbffb240d04e8Denys Vlasenko if (followfork >= 2) 1899328bf250bde8167cec6f2f5bf35463fb4ffb6f9fDenys Vlasenko followfork = 1; 190076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 190176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1902cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko if (!outfname || outfname[0] == '|' || outfname[0] == '!') { 1903a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko char *buf = malloc(BUFSIZ); 1904a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko if (!buf) 1905a677da5e3f25107d4402c1c917d019f2d0bc9f29Denys Vlasenko die_out_of_memory(); 19066764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko setvbuf(shared_log, buf, _IOLBF, BUFSIZ); 1907cb2ad00652e746b370703b5470932b7612308b9cDenys Vlasenko } 1908837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko if (outfname && argv[0]) { 1909b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1910b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_NEVER; 191176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman qflag = 1; 1912369310502bfca4b202d72be9452c8cdb55bb6d5eRoland McGrath } 1913b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (!opt_intr) 1914b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko opt_intr = INTR_WHILE_WAIT; 1915b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko 1916b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* argv[0] -pPID -oFILE Default interactive setting 1917b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 0 INTR_WHILE_WAIT 1918b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 0 INTR_WHILE_WAIT 1919b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * yes 0 1 INTR_NEVER 1920b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * no 1 1 INTR_WHILE_WAIT 192154cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath */ 192254cc1c8ae2d097502439a95d43e1f0ed6782d38cRoland McGrath 19235c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko sigemptyset(&empty_set); 19245c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko sigemptyset(&blocked_set); 19255c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko 1926f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko /* startup_child() must be called before the signal handlers get 1927f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * installed below as they are inherited into the spawned process. 1928f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * Also we do not need to be protected by them as during interruption 1929f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko * in the startup_child() mode we kill the spawned process anyway. 1930f909c8d0d759d0511ad2c741854602b0494e0390Denys Vlasenko */ 193161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko if (argv[0]) { 19321d2435b20bc81fb52c3edb19a3b6247ce2d43ca6Dmitry V. Levin if (!NOMMU_SYSTEM || daemonized_tracer) 19331d2435b20bc81fb52c3edb19a3b6247ce2d43ca6Dmitry V. Levin hide_log_until_execve = 1; 19342a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko skip_one_b_execve = 1; 1935837399af4ffefec55f9693022dc6d8608da442cfDenys Vlasenko startup_child(argv); 193661e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 193776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 193876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_handler = SIG_IGN; 193976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sigemptyset(&sa.sa_mask); 194076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman sa.sa_flags = 0; 1941b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTOU, &sa, NULL); /* SIG_IGN */ 1942b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTTIN, &sa, NULL); /* SIG_IGN */ 1943b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr != INTR_ANYWHERE) { 1944b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_BLOCK_TSTP_TOO) 1945b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTSTP, &sa, NULL); /* SIG_IGN */ 1946b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* 1947b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In interactive mode (if no -o OUTFILE, or -p PID is used), 1948b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * fatal signals are blocked while syscall stop is processed, 1949b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * and acted on in between, when waiting for new syscall stops. 1950b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko * In non-interactive mode, signals are ignored. 1951b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko */ 1952b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko if (opt_intr == INTR_WHILE_WAIT) { 1953b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGHUP); 1954b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGINT); 1955b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGQUIT); 1956b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGPIPE); 1957b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaddset(&blocked_set, SIGTERM); 1958b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sa.sa_handler = interrupt; 1959b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko } 1960b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko /* SIG_IGN, or set handler for these */ 1961b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGHUP, &sa, NULL); 1962b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGINT, &sa, NULL); 1963b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGQUIT, &sa, NULL); 1964b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGPIPE, &sa, NULL); 1965b51581e8f0b11d8f1cce055cebb287f728a508a3Denys Vlasenko sigaction(SIGTERM, &sa, NULL); 196676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 1967fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko if (nprocs != 0 || daemonized_tracer) 196802203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath startup_attach(); 196902203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath 1970fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko /* Do we want pids printed in our -o OUTFILE? 1971fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -ff: no (every pid has its own file); or 1972fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -f: yes (there can be more pids in the future); or 1973fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko * -p PID1,PID2: yes (there are already more than one pid) 1974fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko */ 1975fd883380671693a4616881a9103491f9e67fc8aeDenys Vlasenko print_pid_pfx = (outfname && followfork < 2 && (followfork == 1 || nprocs > 1)); 197676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 197776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1978eebb04d4ae8bf4b08a041f5ea442ca24c90692c2Denys Vlasenkostatic struct tcb * 197954e931fb858410644f61885b4b36fc20320e1fc6Roland McGrathpid2tcb(int pid) 198076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 198176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 198254e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 198354e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath if (pid <= 0) 198454e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath return NULL; 198576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 1986ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 198754e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath struct tcb *tcp = tcbtab[i]; 1988fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko if (tcp->pid == pid) 198976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return tcp; 199076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 199154e931fb858410644f61885b4b36fc20320e1fc6Roland McGrath 199276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman return NULL; 199376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 199476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 199576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 19961201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkocleanup(void) 199776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 199876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman int i; 199976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct tcb *tcp; 20003521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko int fatal_sig; 20013521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko 20023521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko /* 'interrupted' is a volatile object, fetch it only once */ 20033521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = interrupted; 20043521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko if (!fatal_sig) 20053521884c91d0bbd8e796d72619da40bdad95789cDenys Vlasenko fatal_sig = SIGTERM; 200676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2007ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath for (i = 0; i < tcbtabsize; i++) { 2008ee9d435275fd7abf736992f84b5053ee16ec4fc7Roland McGrath tcp = tcbtab[i]; 2009fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko if (!tcp->pid) 201076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2011a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 201276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, 201376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman "cleanup: looking at pid %u\n", tcp->pid); 2014fadbf6679cb52d4265a771cbb8635a2ff472e869Denys Vlasenko if (tcp->pid == strace_child) { 201576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman kill(tcp->pid, SIGCONT); 2016a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko kill(tcp->pid, fatal_sig); 201776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 20187de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko detach(tcp); 201976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 202076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (cflag) 20216764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko call_summary(shared_log); 202276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 202376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 202476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkermanstatic void 20251201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkointerrupt(int sig) 202676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 2027a3559250d48ccc3ef755183ebb3246cbbb442c0dDenys Vlasenko interrupted = sig; 202876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 202976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2030d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenkostatic void 20311201426dd43f5b4e12dfe520e2a9c5027d33dc11Denys Vlasenkotrace(void) 203276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman{ 203376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman struct rusage ru; 203476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2035d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko /* Used to be "while (nprocs != 0)", but in this testcase: 2036d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * int main() { _exit(!!fork()); } 2037d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * under strace -f, parent sometimes (rarely) manages 2038d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * to exit before we see the first stop of the child, 2039d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * and we are losing track of it: 2040d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * 19923 clone(...) = 19924 2041d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * 19923 exit_group(1) = ? 2042d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * 19923 +++ exited with 1 +++ 2043d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * Waiting for ECHILD works better. 20447c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko * (However, if -o|logger is in use, we can't do that. 20457c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko * Can work around that by double-forking the logger, 20467c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko * but that loses the ability to wait for its completion on exit. 20477c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko * Oh well...) 2048d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko */ 2049d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko while (1) { 2050f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int pid; 2051f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int wait_errno; 2052f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko int status, sig; 205331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko int stopped; 2054f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko struct tcb *tcp; 2055f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko unsigned event; 2056f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 2057222713aa409c5caa47327a084f1083a7d6fee66fDenys Vlasenko if (interrupted) 2058d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 2059725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko 20607c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko if (popen_pid != 0 && nprocs == 0) 20617c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko return; 20627c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko 2063eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2064eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_SETMASK, &empty_set, NULL); 2065725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko pid = wait4(-1, &status, __WALL, (cflag ? &ru : NULL)); 206676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman wait_errno = errno; 2067eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath if (interactive) 2068eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath sigprocmask(SIG_BLOCK, &blocked_set, NULL); 206976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 207026d1b1eaa861ec33d2c671acc9c0ccb867042cb8Denys Vlasenko if (pid < 0) { 2071725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko if (wait_errno == EINTR) 207276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 2073d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko if (nprocs == 0 && wait_errno == ECHILD) 2074d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 2075d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko /* If nprocs > 0, ECHILD is not expected, 2076d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko * treat it as any other error here: 2077d2e1f42d8a28486484f00739e561a58be4808b03Denys Vlasenko */ 2078725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko errno = wait_errno; 2079d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko perror_msg_and_die("wait4(__WALL)"); 208076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2081725dd425a60af0cd0fa7bb764ae3a122269a70fcDenys Vlasenko 208210de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin if (pid == popen_pid) { 2083c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko if (!WIFSTOPPED(status)) 20847dd23384f77e9917bd3173c673f318c5d5b485acDenys Vlasenko popen_pid = 0; 208510de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin continue; 208610de62bb052b541af3d0566f05f3f870cce0e028Dmitry V. Levin } 2087f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 2088f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko event = ((unsigned)status >> 16); 2089a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) { 20901d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko char buf[sizeof("WIFEXITED,exitcode=%u") + sizeof(int)*3 /*paranoia:*/ + 16]; 20911b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko char evbuf[sizeof(",EVENT_VFORK_DONE (%u)") + sizeof(int)*3 /*paranoia:*/ + 16]; 20921d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "???"); 20931d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSIGNALED(status)) 20941d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#ifdef WCOREDUMP 20951d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,%ssig=%s", 20961d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko WCOREDUMP(status) ? "core," : "", 20971d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 20981d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#else 20991d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSIGNALED,sig=%s", 21001d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko signame(WTERMSIG(status))); 21011d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko#endif 21021d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFEXITED(status)) 21031d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFEXITED,exitcode=%u", WEXITSTATUS(status)); 21041d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFSTOPPED(status)) 21051d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko sprintf(buf, "WIFSTOPPED,sig=%s", signame(WSTOPSIG(status))); 21065bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#ifdef WIFCONTINUED 2107c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko /* Should never be seen */ 21081d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko if (WIFCONTINUED(status)) 21091d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko strcpy(buf, "WIFCONTINUED"); 21105bd67c86a93c658d258348e8f14af94fd45cbeb6Denys Vlasenko#endif 211167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko evbuf[0] = '\0'; 211267559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event != 0) { 211367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko static const char *const event_names[] = { 211467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_CLONE] = "CLONE", 211567559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_FORK] = "FORK", 211667559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK] = "VFORK", 211767559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_VFORK_DONE] = "VFORK_DONE", 211867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXEC] = "EXEC", 211967559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko [PTRACE_EVENT_EXIT] = "EXIT", 21204e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko /* [PTRACE_EVENT_STOP (=128)] would make biggish array */ 212167559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko }; 21221b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko const char *e = "??"; 212367559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko if (event < ARRAY_SIZE(event_names)) 212467559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko e = event_names[event]; 21254e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko else if (event == PTRACE_EVENT_STOP) 21264e020c0f4b054a030ce8922906cdc217c4b2faf4Denys Vlasenko e = "STOP"; 21271b2bfbc8257231c18dcdd30b8a84eadffbe9417aDenys Vlasenko sprintf(evbuf, ",EVENT_%s (%u)", e, event); 212867559ad260fd31c823615f650f5e131818acf20fDenys Vlasenko } 212938eab5d6ea5627233b781f1bc68c2b264e8ee774Denys Vlasenko fprintf(stderr, " [wait(0x%06x) = %u] %s%s\n", status, pid, buf, evbuf); 21301d5f12ecb88f0cd7aa889d1d7ebd47449f4691b7Denys Vlasenko } 213176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2132f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Look up 'pid' in our table. */ 21335d64581e106f47c474707001f924ee15ef22830bDenys Vlasenko tcp = pid2tcb(pid); 2134f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 21358511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (!tcp) { 2136c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko if (!WIFSTOPPED(status)) { 2137c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko /* This can happen if we inherited 2138c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko * an unknown child. Example: 2139c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko * (sleep 1 & exec strace sleep 2) 2140c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko */ 2141c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko error_msg("Exit of unknown pid %u seen", pid); 2142c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko continue; 2143c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko } 21448511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (followfork) { 2145c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko /* We assume it's a fork/vfork/clone child */ 21468511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tcp = alloctcb(pid); 21478511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tcp->flags |= TCB_ATTACHED | TCB_STARTUP | post_attach_sigstop; 21488511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko newoutf(tcp); 21498511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (!qflag) 21508511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko fprintf(stderr, "Process %d attached\n", 21518511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko pid); 21528511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko } else { 21538511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* This can happen if a clone call used 2154c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko * CLONE_PTRACE itself. 215571d3d29a9d51add731c07e328a7394db0b3dd212Denys Vlasenko */ 2156c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko ptrace(PTRACE_CONT, pid, (char *) 0, 0); 2157c8511f07aba78178f8528e22a8daa438347eb4faDenys Vlasenko error_msg("Stop of unknown pid %u seen, PTRACE_CONTed it", pid); 215871d3d29a9d51add731c07e328a7394db0b3dd212Denys Vlasenko continue; 21598511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko } 21608511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko } 21618511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko 2162ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko clear_regs(); 2163ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko if (WIFSTOPPED(status)) 2164ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko get_regs(pid); 2165ce7d953ebecc10f71e191b6d18cfeb2399429d5fDenys Vlasenko 2166f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko /* Under Linux, execve changes pid to thread leader's pid, 2167f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and we see this changed pid on EVENT_EXEC and later, 2168f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * execve sysexit. Leader "disappears" without exit 2169f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * notification. Let user know that, drop leader's tcb, 2170f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * and fix up pid in execve thread's tcb. 2171f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * Effectively, execve thread's tcb replaces leader's tcb. 2172f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 2173f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * BTW, leader is 'stuck undead' (doesn't report WIFEXITED 2174f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * on exit syscall) in multithreaded programs exactly 2175f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * in order to handle this case. 2176f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * 2177f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * PTRACE_GETEVENTMSG returns old pid starting from Linux 3.0. 2178f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko * On 2.6 and earlier, it can return garbage. 2179f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko */ 21806e0bfd11ac1aa36713d9a65542ae86dd607ae374Denys Vlasenko if (event == PTRACE_EVENT_EXEC && os_release >= KERNEL_VERSION(3,0,0)) { 21816764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko FILE *fp; 21828511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko struct tcb *execve_thread; 2183f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko long old_pid = 0; 21848511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko 21858511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, (long) &old_pid) < 0) 21868511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko goto dont_switch_tcbs; 21876162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko /* Avoid truncation in pid2tcb() param passing */ 21886162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko if (old_pid > UINT_MAX) 21896162a3f34fc8d15095a3b71dc6e4cbdfe1b14ac1Denys Vlasenko goto dont_switch_tcbs; 21908511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (old_pid <= 0 || old_pid == pid) 21918511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko goto dont_switch_tcbs; 21928511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko execve_thread = pid2tcb(old_pid); 21938511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* It should be !NULL, but I feel paranoid */ 21948511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (!execve_thread) 21958511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko goto dont_switch_tcbs; 21968511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko 21978511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (execve_thread->curcol != 0) { 21988511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* 21998511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko * One case we are here is -ff: 22008511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko * try "strace -oLOG -ff test/threaded_execve" 22018511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko */ 22028511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko fprintf(execve_thread->outf, " <pid changed to %d ...>\n", pid); 22036764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko /*execve_thread->curcol = 0; - no need, see code below */ 22048511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko } 22058511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* Swap output FILEs (needed for -ff) */ 22066764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko fp = execve_thread->outf; 22076764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko execve_thread->outf = tcp->outf; 22086764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko tcp->outf = fp; 22098511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* And their column positions */ 22106764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko execve_thread->curcol = tcp->curcol; 22116764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko tcp->curcol = 0; 22128511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* Drop leader, but close execve'd thread outfile (if -ff) */ 22138511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko droptcb(tcp); 22148511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko /* Switch to the thread, reusing leader's outfile and pid */ 22158511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tcp = execve_thread; 22168511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tcp->pid = pid; 22178511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko if (cflag != CFLAG_ONLY_STATS) { 22188511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko printleader(tcp); 22198511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tprintf("+++ superseded by execve in pid %lu +++\n", old_pid); 22208511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko line_ended(); 22218511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko tcp->flags |= TCB_REPRINT; 2222f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 2223f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko } 22248511f2a1f02a31f66eab86bf95dee1636fb39076Denys Vlasenko dont_switch_tcbs: 2225f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko 22262a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko if (event == PTRACE_EVENT_EXEC) { 22272a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko if (detach_on_execve && !skip_one_b_execve) 22282a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko detach(tcp); /* do "-b execve" thingy */ 22292a3d27552f17a5b378344620bec7d255bac65a8dDenys Vlasenko skip_one_b_execve = 0; 223061e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko } 223161e7aad9fa1a6a5bd5a586e6276767caf12b53f2Denys Vlasenko 22327de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko /* Set current output file */ 22336764f8f2f0b71ecc069d607eb8525735d1684a59Denys Vlasenko current_tcp = tcp; 22347de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko 223513d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko if (cflag) { 223676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tv_sub(&tcp->dtime, &ru.ru_stime, &tcp->stime); 223776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->stime = ru.ru_stime; 223876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2239eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath 224076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFSIGNALED(status)) { 2241a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2242a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = 0x100 | WTERMSIG(status); 2243e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 2244a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenko && (qual_flags[WTERMSIG(status)] & QUAL_SIGNAL) 2245a9fe13c9437707fa132fde4e51a20d88381e7430Denys Vlasenko ) { 224676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman printleader(tcp); 224713d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#ifdef WCOREDUMP 2248000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s %s+++\n", 22492efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath signame(WTERMSIG(status)), 225013d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko WCOREDUMP(status) ? "(core dumped) " : ""); 225113d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko#else 2252000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ killed by %s +++\n", 225313d22f1aa3a1beba79a8febb3770f75e646211a8Denys Vlasenko signame(WTERMSIG(status))); 22542efe879fa8df30bf69c3a4c471dcc5e19ad0b6eaRoland McGrath#endif 22557de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 225676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 225776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 225876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 225976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 226076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (WIFEXITED(status)) { 2261a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin if (pid == strace_child) 2262a68096576afc07e51d33b49c432d658b27a7f13cDmitry V. Levin exit_code = WEXITSTATUS(status); 226301997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange if (cflag != CFLAG_ONLY_STATS && 226401997cf32d4492b9898283ced45e8a4a6fd161b8Daniel P. Berrange qflag < 2) { 226519cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko printleader(tcp); 2266000b601439d249a4afa2ceb6096850a702612d1eDenys Vlasenko tprintf("+++ exited with %d +++\n", WEXITSTATUS(status)); 22677de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko line_ended(); 226819cdada5b499b978ffd9c3367b4ef34ad6f8bf2bDenys Vlasenko } 226976baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 227076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 227176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 227276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman if (!WIFSTOPPED(status)) { 227376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman fprintf(stderr, "PANIC: pid %u not stopped\n", pid); 227476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 227576baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 227676baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 227776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 2278f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this the very first time we see this tracee stopped? */ 2279f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (tcp->flags & TCB_STARTUP) { 2280a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2281f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "pid %d has TCB_STARTUP, initializing it\n", tcp->pid); 228276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman tcp->flags &= ~TCB_STARTUP; 228302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (tcp->flags & TCB_BPTSET) { 228476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman /* 228502203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath * One example is a breakpoint inherited from 22862ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * parent through fork(). 228776baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman */ 22886cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (clearbpt(tcp) < 0) { 22896cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko /* Pretty fatal */ 229076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman droptcb(tcp); 2291d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko exit_code = 1; 2292d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 229376baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 229476baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 2295c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko if (!use_seize && ptrace_setoptions) { 2296a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2297c169d94718e0c3a980dbf352010e615daf2f4332Denys Vlasenko fprintf(stderr, "setting opts 0x%x on pid %d\n", ptrace_setoptions, tcp->pid); 229844f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (ptrace(PTRACE_SETOPTIONS, tcp->pid, NULL, ptrace_setoptions) < 0) { 229944f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko if (errno != ESRCH) { 230044f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko /* Should never happen, really */ 230144f87efc676467ab47972feec49af4f7f34356bfDenys Vlasenko perror_msg_and_die("PTRACE_SETOPTIONS"); 23023454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 23033454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 23043454e4b463e6c22c7ea8c5461ef5a077f4650a54Denys Vlasenko } 2305f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2306f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 230731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko sig = WSTOPSIG(status); 230831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 2309f7db5dd876eb41a3f0d5fd223c831734acc8d8d1Denys Vlasenko if (event != 0) { 231031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Ptrace event */ 23115c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE 231226bc0606d96d05d30ba263939a0451889340a64cDenys Vlasenko if (event == PTRACE_EVENT_STOP) { 23136703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko /* 23146703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop or group-stop. 23156703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko * PTRACE_INTERRUPT-stop has sig == SIGTRAP here. 23166703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko */ 231731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (sig == SIGSTOP 231831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTSTP 231931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTIN 232031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko || sig == SIGTTOU 232131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko ) { 232231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = 1; 232331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto show_stopsig; 232431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 232531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 232631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko#endif 2327f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko goto restart_tracee_with_sig_0; 2328f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko } 2329f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko 2330f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko /* Is this post-attach SIGSTOP? 2331f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * Interestingly, the process may stop 2332f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * with STOPSIG equal to some other signal 2333f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * than SIGSTOP if we happend to attach 2334f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko * just before the process takes a signal. 2335f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko */ 2336f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko if (sig == SIGSTOP && (tcp->flags & TCB_IGNORE_ONE_SIGSTOP)) { 2337a50d2a87a1a8df4471bbd93f2ce9ef0541b1124bDenys Vlasenko if (debug_flag) 2338f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko fprintf(stderr, "ignored SIGSTOP on pid %d\n", tcp->pid); 2339f88837a666a716aecd9974f7ef3fcf006e0afce1Denys Vlasenko tcp->flags &= ~TCB_IGNORE_ONE_SIGSTOP; 23406cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee_with_sig_0; 234176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 234276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman 23436cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (sig != syscall_trap_sig) { 234431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko siginfo_t si; 234531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 234631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* Nonzero (true) if tracee is stopped by signal 234731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (as opposed to "tracee received signal"). 2348a44f9696e45f5bb51c6ec37c0ef95dc2cdfd4c8aDenys Vlasenko * TODO: shouldn't we check for errno == EINVAL too? 2349a44f9696e45f5bb51c6ec37c0ef95dc2cdfd4c8aDenys Vlasenko * We can get ESRCH instead, you know... 235031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 235131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko stopped = (ptrace(PTRACE_GETSIGINFO, pid, 0, (long) &si) < 0); 23525c9d8f4fc5318fc740ec2a16bac5b8a29e7eb52dDenys Vlasenko#if USE_SEIZE 235331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko show_stopsig: 23546703816060c2cf4aaf9c82057ced31c3ba744346Denys Vlasenko#endif 2355e3a7ef5a2a3ac31bfa0d3f9ce65981e51700073eDmitry V. Levin if (cflag != CFLAG_ONLY_STATS 2356e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin && !hide_log_until_execve 2357e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin && (qual_flags[sig] & QUAL_SIGNAL) 2358e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin ) { 2359e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin printleader(tcp); 2360e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin if (!stopped) { 2361e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin tprintf("--- %s ", signame(sig)); 2362e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin printsiginfo(&si, verbose(tcp)); 23635a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko tprints(" ---\n"); 2364e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin } else 23655a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko tprintf("--- stopped by %s ---\n", 23665a2483ba25fd80cb189abcdc14624be72b0c4c0bDenys Vlasenko signame(sig)); 2367e8ff4c6f863c16180dacff74988f0e617f8136d9Dmitry V. Levin line_ended(); 236876baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 236931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 237031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (!stopped) 237131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's signal-delivery-stop. Inject the signal */ 237231fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko goto restart_tracee; 237331fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko 237431fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* It's group-stop */ 237531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (use_seize) { 237631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* 237731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This ends ptrace-stop, but does *not* end group-stop. 237831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * This makes stopping signals work properly on straced process 237931fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko * (that is, process really stops. It used to continue to run). 238031fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko */ 238131fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko if (ptrace_restart(PTRACE_LISTEN, tcp, 0) < 0) { 2382d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko /* Note: ptrace_restart emitted error message */ 2383d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko exit_code = 1; 2384d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 238531fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 238631fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko continue; 238731fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko } 238831fa8a22b17b2f898513b68e04269597147d2478Denys Vlasenko /* We don't have PTRACE_LISTEN support... */ 23896cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko goto restart_tracee; 239076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 23912ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 23922ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* We handled quick cases, we are permitted to interrupt now. */ 239302203311e96a90608c30e6604dc1f7bda0a777f0Roland McGrath if (interrupted) 2394d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 23952ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko 23962ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko /* This should be syscall entry or exit. 23972ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * (Or it still can be that pesky post-execve SIGTRAP!) 23982ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko * Handle it. 23992ecba32d52db699538bcfc3f69259aaff32a0fa9Denys Vlasenko */ 2400235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko if (trace_syscall(tcp) < 0) { 2401235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko /* ptrace() failed in trace_syscall(). 2402eb9e2e8904ce85a6c7390be25bb873c6db88c4d3Roland McGrath * Likely a result of process disappearing mid-flight. 2403235067525cc064a9a466c245fa8a6265ae136306Denys Vlasenko * Observed case: exit_group() or SIGKILL terminating 2404f1e690370359f61f9533134817b52d74460a20fbDenys Vlasenko * all processes in thread group. 24057de265d88a78a27d58c2c728424e5bb8379ef351Denys Vlasenko * We assume that ptrace error was caused by process death. 2406f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * We used to detach(tcp) here, but since we no longer 2407f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * implement "detach before death" policy/hack, 2408f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * we can let this process to report its death to us 2409f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko * normally, via WIFEXITED or WIFSIGNALED wait status. 2410f20250266eb5988805b03b1cc0fa74cdb6398742Denys Vlasenko */ 241176baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman continue; 241276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24136cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee_with_sig_0: 24146cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko sig = 0; 24156cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko restart_tracee: 24166cda73ff9ca94e2be56d04186fceaca223a9c45bDenys Vlasenko if (ptrace_restart(PTRACE_SYSCALL, tcp, sig) < 0) { 2417d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko /* Note: ptrace_restart emitted error message */ 2418d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko exit_code = 1; 2419d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko return; 242076baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman } 24217c41ce287804f5409400c2b87bf11ebc6f6e1091Denys Vlasenko } /* while (1) */ 242276baf7c9f6dd61a15524ad43c1b690c252cf5b7Wichert Akkerman} 2423ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2424ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkoint 2425ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenkomain(int argc, char *argv[]) 2426ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko{ 2427ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko init(argc, argv); 2428ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2429ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Run main tracing loop */ 2430d0ffdf494ac722f3d121c6e807f105000409e6a6Denys Vlasenko trace(); 2431ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2432ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko cleanup(); 2433ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko fflush(NULL); 2434cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin if (shared_log != stderr) 2435cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin fclose(shared_log); 2436cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin if (popen_pid) { 2437cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin while (waitpid(popen_pid, NULL, 0) < 0 && errno == EINTR) 2438cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin ; 2439cf53436f737c0273028503186fc0f837c7191085Dmitry V. Levin } 2440ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko if (exit_code > 0xff) { 2441ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Avoid potential core file clobbering. */ 2442c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin struct_rlimit rlim = {0, 0}; 2443c8938e08ad06ae7bf0f50872ddbb0efbe7bf7560Dmitry V. Levin set_rlimit(RLIMIT_CORE, &rlim); 2444ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2445ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Child was killed by a signal, mimic that. */ 2446ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code &= 0xff; 2447ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko signal(exit_code, SIG_DFL); 2448ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko raise(exit_code); 2449ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko /* Paranoia - what if this signal is not fatal? 2450ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko Exit with 128 + signo then. */ 2451ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko exit_code += 128; 2452ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko } 2453ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko 2454ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko return exit_code; 2455ecc8b97c9bd36ad25c550ec412f43f44b59e2ebdDenys Vlasenko} 2456