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
|
||||
* Implemented simultaneous use of -p option and tracing of a command.
|
||||
(addresses Debian bug #549942).
|
||||
* Enhanced decoding of personality, sched_getaffinity,
|
||||
and sched_setaffinity syscalls.
|
||||
* 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.
|
||||
Multiple
|
||||
.B \-p
|
||||
options can be used to attach to many processes.
|
||||
-p "`pidof PROG`" syntax is supported.
|
||||
options can be used to attach to many processes in addition to
|
||||
.I command
|
||||
(which is optional if at least one
|
||||
.B \-p
|
||||
option is given).
|
||||
.B \-p
|
||||
"`pidof PROG`" syntax is supported.
|
||||
.TP
|
||||
.BI "\-P " path
|
||||
Trace only system calls accessing
|
||||
|
44
strace.c
44
strace.c
@ -973,6 +973,7 @@ process_opt_p_list(char *opt)
|
||||
static void
|
||||
startup_attach(void)
|
||||
{
|
||||
pid_t parent_pid = strace_tracer_pid;
|
||||
unsigned int tcbi;
|
||||
struct tcb *tcp;
|
||||
|
||||
@ -1015,7 +1016,13 @@ startup_attach(void)
|
||||
if (tcp->flags & TCB_ATTACHED)
|
||||
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];
|
||||
DIR *dir;
|
||||
|
||||
@ -1092,18 +1099,19 @@ startup_attach(void)
|
||||
if (debug_flag)
|
||||
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)
|
||||
error_msg("Process %u attached", tcp->pid);
|
||||
} /* for each tcbtab[] */
|
||||
|
||||
if (daemonized_tracer) {
|
||||
/*
|
||||
* Make parent go away.
|
||||
* Also makes grandparent's wait() unblock.
|
||||
*/
|
||||
kill(parent_pid, SIGKILL);
|
||||
strace_child = 0;
|
||||
}
|
||||
|
||||
ret:
|
||||
if (interactive)
|
||||
sigprocmask(SIG_SETMASK, &empty_set, NULL);
|
||||
@ -1317,11 +1325,10 @@ startup_child(char **argv)
|
||||
newoutf(tcp);
|
||||
}
|
||||
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();
|
||||
/* The tracee is our parent: */
|
||||
pid = getppid();
|
||||
alloctcb(pid);
|
||||
alloctcb(strace_child);
|
||||
/* attaching will be done later, by startup_attach */
|
||||
/* note: we don't do newoutf(tcp) here either! */
|
||||
|
||||
@ -1619,13 +1626,12 @@ init(int argc, char *argv[])
|
||||
memset(acolumn_spaces, ' ', acolumn);
|
||||
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");
|
||||
}
|
||||
|
||||
if (nprocs != 0 && daemonized_tracer) {
|
||||
error_msg_and_help("-D and -p are mutually exclusive");
|
||||
if (!argv[0] && daemonized_tracer) {
|
||||
error_msg_and_help("PROG [ARGS] must be specified with -D");
|
||||
}
|
||||
|
||||
if (!followfork)
|
||||
@ -1722,9 +1728,9 @@ init(int argc, char *argv[])
|
||||
opt_intr = INTR_WHILE_WAIT;
|
||||
|
||||
/* argv[0] -pPID -oFILE Default interactive setting
|
||||
* yes 0 0 INTR_WHILE_WAIT
|
||||
* yes * 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
|
||||
*/
|
||||
|
||||
|
2
tests/.gitignore
vendored
2
tests/.gitignore
vendored
@ -8,6 +8,8 @@
|
||||
_newselect
|
||||
adjtimex
|
||||
aio
|
||||
attach-p-cmd-cmd
|
||||
attach-p-cmd-p
|
||||
bpf
|
||||
caps
|
||||
clock_nanosleep
|
||||
|
@ -56,6 +56,8 @@ check_PROGRAMS = \
|
||||
_newselect \
|
||||
adjtimex \
|
||||
aio \
|
||||
attach-p-cmd-cmd \
|
||||
attach-p-cmd-p \
|
||||
bpf \
|
||||
caps \
|
||||
clock_nanosleep \
|
||||
@ -299,6 +301,7 @@ TESTS = \
|
||||
xettimeofday.test \
|
||||
\
|
||||
count.test \
|
||||
attach-p-cmd.test \
|
||||
detach-sleeping.test \
|
||||
detach-stopped.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