Currently only test fork related options. Fork a child that uses PTRACE_TRACEME at startup and then does a fork so strace can test how the PTRACE_SETOPTIONS support works before it handles any real tracee. Since PTRACE_O_TRACECLONE/*FORK were introduced to kernel at the same time, so this test seems enough for these 3 options.
* defs.h [LINUX]: Define PTRACE_O_TRACECLONE et al macros here; Variable declaration. * strace.c [LINUX](test_ptrace_setoptions): New function for testing whether kernel supports PTRACE_O_CLONE/*FORK, the result is stored in the new variable for later use. (main): Call that function. Signed-off-by: Wang Chao <[email protected]> --- defs.h | 16 +++++++++++++ strace.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 0 deletions(-) diff --git a/defs.h b/defs.h index 0b3ba43..daed8c6 100644 --- a/defs.h +++ b/defs.h @@ -308,6 +308,21 @@ extern int mp_ioctl (int f, int c, void *a, int s); #define PR_FAULTED S_CORE #endif +#ifdef LINUX +# ifndef PTRACE_SETOPTIONS +# define PTRACE_SETOPTIONS 0x4200 +# endif +# ifndef PTRACE_O_TRACEFORK +# define PTRACE_O_TRACEFORK 0x00000002 +# endif +# ifndef PTRACE_O_TRACEVFORK +# define PTRACE_O_TRACEVFORK 0x00000004 +# endif +# ifndef PTRACE_O_TRACECLONE +# define PTRACE_O_TRACECLONE 0x00000008 +# endif +#endif /* LINUX */ + /* Trace Control Block */ struct tcb { short flags; /* See below for TCB_ values */ @@ -470,6 +485,7 @@ typedef enum { extern struct tcb **tcbtab; extern int *qual_flags; extern int debug, followfork; +extern unsigned int ptrace_setoptions; extern int dtime, xflag, qflag; extern cflag_t cflag; extern int acolumn; diff --git a/strace.c b/strace.c index 497b8d1..e694f17 100644 --- a/strace.c +++ b/strace.c @@ -83,6 +83,7 @@ extern char *optarg; int debug = 0, followfork = 0; +unsigned int ptrace_setoptions = 0; int dtime = 0, xflag = 0, qflag = 0; cflag_t cflag = CFLAG_NONE; static int iflag = 0, interactive = 0, pflag_seen = 0, rflag = 0, tflag = 0; @@ -686,6 +687,70 @@ startup_child (char **argv) #endif /* USE_PROCFS */ } +#ifdef LINUX +/* Test whether kernel support PTRACE_O_TRACECLONE et al options. + * First fork a new child, call ptrace with PTRACE_SETOPTIONS on it, + * and then see which options are supported on this kernel. + */ +int test_ptrace_setoptions() +{ + int pid; + unsigned int test_options = PTRACE_O_TRACEFORK; + + if ((pid = fork()) < 0) + return -1; + else if (pid == 0) { + if (ptrace(PTRACE_TRACEME, 0, (char *)1, 0) < 0) { + exit(1); + } + kill(getpid(), SIGSTOP); + if ((pid = fork()) < 0) { + exit(1); + } + exit(0); + } + else { + int status, tracee_pid, wait_errno; + int no_child = 0; + while(1) { + tracee_pid = wait4(-1, &status, 0, NULL); + wait_errno = errno; + if (tracee_pid == -1) { + switch (wait_errno) { + case EINTR: + continue; + case ECHILD: + no_child = 1; + break; + default: + errno = wait_errno; + perror("test_ptrace_setoptions"); + return -1; + } + } + if (no_child) + break; + if (tracee_pid != pid) + ptrace(PTRACE_CONT, tracee_pid, 0, 0); + if (WIFSTOPPED(status)) { + if (status >> 16 == PTRACE_EVENT_FORK) + ptrace_setoptions |= (PTRACE_O_TRACEVFORK | + PTRACE_O_TRACECLONE | + PTRACE_O_TRACEFORK); + if (WSTOPSIG(status) == SIGSTOP) + if (ptrace(PTRACE_SETOPTIONS, pid, + NULL, test_options) < 0) { + ptrace(PTRACE_CONT, pid, 0, 0); + continue; + } + ptrace(PTRACE_SYSCALL, pid, 0, 0); + } + } + } + return 0; +} +#endif + int main(int argc, char *argv[]) { @@ -914,6 +979,15 @@ main(int argc, char *argv[]) interactive = 0; qflag = 1; } + +#ifdef LINUX + if (test_ptrace_setoptions() < 0) { + fprintf(stderr, "Test for options supported by PTRACE_SETOPTIONS\ + failed, give up using this feature\n"); + ptrace_setoptions = 0; + } +#endif + /* Valid states here: optind < argc pflag_seen outfname interactive 1 0 0 1 -- 1.6.5.2 ------------------------------------------------------------------------------ Start uncovering the many advantages of virtual appliances and start using them to simplify application deployment and accelerate your shift to cloud computing. http://p.sf.net/sfu/novell-sfdev2dev _______________________________________________ Strace-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/strace-devel
