Implement simultaneous use of -p option and tracing of a command
* strace.c (init): Allow -p option along with a command. (startup_child): In -D mode, record the parent of the tracer process as strace_child. (startup_attach): Save trace_tracer_pid before -D mode fork. When tracing a command in -f mode, do not check for the command's threads as it has no threads at this moment. Never attach to the tracer process. In -D mode, never attach to the parent of the tracer process, terminate that process only once at the end of startup_attach, and reset strace_child. * strace.1: Document that -p option can be used along with tracing of a command. * NEWS: Mention it. * tests/attach-p-cmd-cmd.c: New file. * tests/attach-p-cmd-p.c: Likewise. * tests/attach-p-cmd.test: New test. * tests/.gitignore: Add attach-p-cmd-cmd and attach-p-cmd-p. * tests/Makefile.am (check_PROGRAMS): Likewise. (TESTS): Add attach-p-cmd.test. This fixes Debian bug #549942.
This commit is contained in:
parent
38721432de
commit
fa8c286d50
2
NEWS
2
NEWS
@ -2,6 +2,8 @@ Noteworthy changes in release ?.?? (????-??-??)
|
|||||||
===============================================
|
===============================================
|
||||||
|
|
||||||
* Improvements
|
* Improvements
|
||||||
|
* Implemented simultaneous use of -p option and tracing of a command.
|
||||||
|
(addresses Debian bug #549942).
|
||||||
* Enhanced decoding of personality, sched_getaffinity,
|
* Enhanced decoding of personality, sched_getaffinity,
|
||||||
and sched_setaffinity syscalls.
|
and sched_setaffinity syscalls.
|
||||||
* Enhanced decoding of getxpid, getxuid, and getxgid syscalls on alpha.
|
* Enhanced decoding of getxpid, getxuid, and getxgid syscalls on alpha.
|
||||||
|
9
strace.1
9
strace.1
@ -530,8 +530,13 @@ will respond by detaching itself from the traced process(es)
|
|||||||
leaving it (them) to continue running.
|
leaving it (them) to continue running.
|
||||||
Multiple
|
Multiple
|
||||||
.B \-p
|
.B \-p
|
||||||
options can be used to attach to many processes.
|
options can be used to attach to many processes in addition to
|
||||||
-p "`pidof PROG`" syntax is supported.
|
.I command
|
||||||
|
(which is optional if at least one
|
||||||
|
.B \-p
|
||||||
|
option is given).
|
||||||
|
.B \-p
|
||||||
|
"`pidof PROG`" syntax is supported.
|
||||||
.TP
|
.TP
|
||||||
.BI "\-P " path
|
.BI "\-P " path
|
||||||
Trace only system calls accessing
|
Trace only system calls accessing
|
||||||
|
44
strace.c
44
strace.c
@ -973,6 +973,7 @@ process_opt_p_list(char *opt)
|
|||||||
static void
|
static void
|
||||||
startup_attach(void)
|
startup_attach(void)
|
||||||
{
|
{
|
||||||
|
pid_t parent_pid = strace_tracer_pid;
|
||||||
unsigned int tcbi;
|
unsigned int tcbi;
|
||||||
struct tcb *tcp;
|
struct tcb *tcp;
|
||||||
|
|
||||||
@ -1015,7 +1016,13 @@ startup_attach(void)
|
|||||||
if (tcp->flags & TCB_ATTACHED)
|
if (tcp->flags & TCB_ATTACHED)
|
||||||
continue; /* no, we already attached it */
|
continue; /* no, we already attached it */
|
||||||
|
|
||||||
if (followfork && !daemonized_tracer) {
|
if (tcp->pid == parent_pid || tcp->pid == strace_tracer_pid) {
|
||||||
|
errno = EPERM;
|
||||||
|
perror_msg("attach: %d", tcp->pid);
|
||||||
|
droptcb(tcp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (followfork && tcp->pid != strace_child) {
|
||||||
char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
|
char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
|
|
||||||
@ -1092,18 +1099,19 @@ startup_attach(void)
|
|||||||
if (debug_flag)
|
if (debug_flag)
|
||||||
error_msg("attach to pid %d (main) succeeded", tcp->pid);
|
error_msg("attach to pid %d (main) succeeded", tcp->pid);
|
||||||
|
|
||||||
if (daemonized_tracer) {
|
|
||||||
/*
|
|
||||||
* Make parent go away.
|
|
||||||
* Also makes grandparent's wait() unblock.
|
|
||||||
*/
|
|
||||||
kill(getppid(), SIGKILL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!qflag)
|
if (!qflag)
|
||||||
error_msg("Process %u attached", tcp->pid);
|
error_msg("Process %u attached", tcp->pid);
|
||||||
} /* for each tcbtab[] */
|
} /* for each tcbtab[] */
|
||||||
|
|
||||||
|
if (daemonized_tracer) {
|
||||||
|
/*
|
||||||
|
* Make parent go away.
|
||||||
|
* Also makes grandparent's wait() unblock.
|
||||||
|
*/
|
||||||
|
kill(parent_pid, SIGKILL);
|
||||||
|
strace_child = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
if (interactive)
|
if (interactive)
|
||||||
sigprocmask(SIG_SETMASK, &empty_set, NULL);
|
sigprocmask(SIG_SETMASK, &empty_set, NULL);
|
||||||
@ -1317,11 +1325,10 @@ startup_child(char **argv)
|
|||||||
newoutf(tcp);
|
newoutf(tcp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* With -D, we are *child* here, IOW: different pid. Fetch it: */
|
/* With -D, we are *child* here, the tracee is our parent. */
|
||||||
|
strace_child = strace_tracer_pid;
|
||||||
strace_tracer_pid = getpid();
|
strace_tracer_pid = getpid();
|
||||||
/* The tracee is our parent: */
|
alloctcb(strace_child);
|
||||||
pid = getppid();
|
|
||||||
alloctcb(pid);
|
|
||||||
/* attaching will be done later, by startup_attach */
|
/* attaching will be done later, by startup_attach */
|
||||||
/* note: we don't do newoutf(tcp) here either! */
|
/* note: we don't do newoutf(tcp) here either! */
|
||||||
|
|
||||||
@ -1619,13 +1626,12 @@ init(int argc, char *argv[])
|
|||||||
memset(acolumn_spaces, ' ', acolumn);
|
memset(acolumn_spaces, ' ', acolumn);
|
||||||
acolumn_spaces[acolumn] = '\0';
|
acolumn_spaces[acolumn] = '\0';
|
||||||
|
|
||||||
/* Must have PROG [ARGS], or -p PID. Not both. */
|
if (!argv[0] && !nprocs) {
|
||||||
if (!argv[0] == !nprocs) {
|
|
||||||
error_msg_and_help("must have PROG [ARGS] or -p PID");
|
error_msg_and_help("must have PROG [ARGS] or -p PID");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nprocs != 0 && daemonized_tracer) {
|
if (!argv[0] && daemonized_tracer) {
|
||||||
error_msg_and_help("-D and -p are mutually exclusive");
|
error_msg_and_help("PROG [ARGS] must be specified with -D");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!followfork)
|
if (!followfork)
|
||||||
@ -1722,9 +1728,9 @@ init(int argc, char *argv[])
|
|||||||
opt_intr = INTR_WHILE_WAIT;
|
opt_intr = INTR_WHILE_WAIT;
|
||||||
|
|
||||||
/* argv[0] -pPID -oFILE Default interactive setting
|
/* argv[0] -pPID -oFILE Default interactive setting
|
||||||
* yes 0 0 INTR_WHILE_WAIT
|
* yes * 0 INTR_WHILE_WAIT
|
||||||
* no 1 0 INTR_WHILE_WAIT
|
* no 1 0 INTR_WHILE_WAIT
|
||||||
* yes 0 1 INTR_NEVER
|
* yes * 1 INTR_NEVER
|
||||||
* no 1 1 INTR_WHILE_WAIT
|
* no 1 1 INTR_WHILE_WAIT
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
@ -8,6 +8,8 @@
|
|||||||
_newselect
|
_newselect
|
||||||
adjtimex
|
adjtimex
|
||||||
aio
|
aio
|
||||||
|
attach-p-cmd-cmd
|
||||||
|
attach-p-cmd-p
|
||||||
bpf
|
bpf
|
||||||
caps
|
caps
|
||||||
clock_nanosleep
|
clock_nanosleep
|
||||||
|
@ -56,6 +56,8 @@ check_PROGRAMS = \
|
|||||||
_newselect \
|
_newselect \
|
||||||
adjtimex \
|
adjtimex \
|
||||||
aio \
|
aio \
|
||||||
|
attach-p-cmd-cmd \
|
||||||
|
attach-p-cmd-p \
|
||||||
bpf \
|
bpf \
|
||||||
caps \
|
caps \
|
||||||
clock_nanosleep \
|
clock_nanosleep \
|
||||||
@ -299,6 +301,7 @@ TESTS = \
|
|||||||
xettimeofday.test \
|
xettimeofday.test \
|
||||||
\
|
\
|
||||||
count.test \
|
count.test \
|
||||||
|
attach-p-cmd.test \
|
||||||
detach-sleeping.test \
|
detach-sleeping.test \
|
||||||
detach-stopped.test \
|
detach-stopped.test \
|
||||||
detach-running.test \
|
detach-running.test \
|
||||||
|
44
tests/attach-p-cmd-cmd.c
Normal file
44
tests/attach-p-cmd-cmd.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of attach-p-cmd strace test.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tests.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
static const char text[] = "attach-p-cmd.test cmd";
|
||||||
|
assert(chdir(text) == -1);
|
||||||
|
pid_t pid = getpid();
|
||||||
|
printf("%-5d chdir(\"%s\") = -1 ENOENT (%m)\n"
|
||||||
|
"%-5d +++ exited with 0 +++\n", pid, text, pid);
|
||||||
|
return 0;
|
||||||
|
}
|
65
tests/attach-p-cmd-p.c
Normal file
65
tests/attach-p-cmd-p.c
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of attach-p-cmd strace test.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tests.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
handler(int signo)
|
||||||
|
{
|
||||||
|
_exit(!chdir("attach-p-cmd.test -p"));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int ac, char **av)
|
||||||
|
{
|
||||||
|
if (ac < 2)
|
||||||
|
error_msg_and_fail("missing operand");
|
||||||
|
|
||||||
|
if (ac > 2)
|
||||||
|
error_msg_and_fail("extra operand");
|
||||||
|
|
||||||
|
const sigset_t set = {};
|
||||||
|
const struct sigaction act = { .sa_handler = handler };
|
||||||
|
const struct itimerval itv = { .it_value.tv_sec = atoi(av[1]) };
|
||||||
|
|
||||||
|
assert(sigaction(SIGALRM, &act, NULL) == 0);
|
||||||
|
assert(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
|
||||||
|
if (setitimer(ITIMER_REAL, &itv, NULL))
|
||||||
|
perror_msg_and_skip("setitimer");
|
||||||
|
|
||||||
|
for (;;);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
54
tests/attach-p-cmd.test
Executable file
54
tests/attach-p-cmd.test
Executable file
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Check that simultaneous use of -p option and tracing of a command works.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. The name of the author may not be used to endorse or promote products
|
||||||
|
# derived from this software without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
. "${srcdir=.}/init.sh"
|
||||||
|
|
||||||
|
run_prog_skip_if_failed \
|
||||||
|
kill -0 $$
|
||||||
|
run_prog ./attach-p-cmd-cmd > /dev/null
|
||||||
|
run_prog ./attach-p-cmd-p 1 > /dev/null
|
||||||
|
|
||||||
|
OUT="$LOG.out"
|
||||||
|
./set_ptracer_any ./attach-p-cmd-p 1 > "$OUT" &
|
||||||
|
tracee_pid=$!
|
||||||
|
|
||||||
|
while ! [ -s "$OUT" ]; do
|
||||||
|
kill -0 $tracee_pid 2> /dev/null ||
|
||||||
|
fail_ 'set_ptracer_any sleep failed'
|
||||||
|
done
|
||||||
|
|
||||||
|
run_strace -a30 -echdir -p $tracee_pid ./attach-p-cmd-cmd > "$OUT"
|
||||||
|
{
|
||||||
|
printf '%-5d --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---\n' $tracee_pid
|
||||||
|
printf '%-5d chdir("attach-p-cmd.test -p") = -1 ENOENT (No such file or directory)\n' $tracee_pid
|
||||||
|
printf '%-5d +++ exited with 0 +++\n' $tracee_pid
|
||||||
|
} >> "$OUT"
|
||||||
|
|
||||||
|
match_diff "$LOG" "$OUT"
|
||||||
|
rm -f "$OUT"
|
Loading…
Reference in New Issue
Block a user