Skip to content

Commit fa8c286

Browse files
committed
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.
1 parent 3872143 commit fa8c286

File tree

8 files changed

+202
-21
lines changed

8 files changed

+202
-21
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ Noteworthy changes in release ?.?? (????-??-??)
22
===============================================
33

44
* Improvements
5+
* Implemented simultaneous use of -p option and tracing of a command.
6+
(addresses Debian bug #549942).
57
* Enhanced decoding of personality, sched_getaffinity,
68
and sched_setaffinity syscalls.
79
* Enhanced decoding of getxpid, getxuid, and getxgid syscalls on alpha.

strace.1

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,13 @@ will respond by detaching itself from the traced process(es)
530530
leaving it (them) to continue running.
531531
Multiple
532532
.B \-p
533-
options can be used to attach to many processes.
534-
-p "`pidof PROG`" syntax is supported.
533+
options can be used to attach to many processes in addition to
534+
.I command
535+
(which is optional if at least one
536+
.B \-p
537+
option is given).
538+
.B \-p
539+
"`pidof PROG`" syntax is supported.
535540
.TP
536541
.BI "\-P " path
537542
Trace only system calls accessing

strace.c

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,7 @@ process_opt_p_list(char *opt)
973973
static void
974974
startup_attach(void)
975975
{
976+
pid_t parent_pid = strace_tracer_pid;
976977
unsigned int tcbi;
977978
struct tcb *tcp;
978979

@@ -1015,7 +1016,13 @@ startup_attach(void)
10151016
if (tcp->flags & TCB_ATTACHED)
10161017
continue; /* no, we already attached it */
10171018

1018-
if (followfork && !daemonized_tracer) {
1019+
if (tcp->pid == parent_pid || tcp->pid == strace_tracer_pid) {
1020+
errno = EPERM;
1021+
perror_msg("attach: %d", tcp->pid);
1022+
droptcb(tcp);
1023+
continue;
1024+
}
1025+
if (followfork && tcp->pid != strace_child) {
10191026
char procdir[sizeof("/proc/%d/task") + sizeof(int) * 3];
10201027
DIR *dir;
10211028

@@ -1092,18 +1099,19 @@ startup_attach(void)
10921099
if (debug_flag)
10931100
error_msg("attach to pid %d (main) succeeded", tcp->pid);
10941101

1095-
if (daemonized_tracer) {
1096-
/*
1097-
* Make parent go away.
1098-
* Also makes grandparent's wait() unblock.
1099-
*/
1100-
kill(getppid(), SIGKILL);
1101-
}
1102-
11031102
if (!qflag)
11041103
error_msg("Process %u attached", tcp->pid);
11051104
} /* for each tcbtab[] */
11061105

1106+
if (daemonized_tracer) {
1107+
/*
1108+
* Make parent go away.
1109+
* Also makes grandparent's wait() unblock.
1110+
*/
1111+
kill(parent_pid, SIGKILL);
1112+
strace_child = 0;
1113+
}
1114+
11071115
ret:
11081116
if (interactive)
11091117
sigprocmask(SIG_SETMASK, &empty_set, NULL);
@@ -1317,11 +1325,10 @@ startup_child(char **argv)
13171325
newoutf(tcp);
13181326
}
13191327
else {
1320-
/* With -D, we are *child* here, IOW: different pid. Fetch it: */
1328+
/* With -D, we are *child* here, the tracee is our parent. */
1329+
strace_child = strace_tracer_pid;
13211330
strace_tracer_pid = getpid();
1322-
/* The tracee is our parent: */
1323-
pid = getppid();
1324-
alloctcb(pid);
1331+
alloctcb(strace_child);
13251332
/* attaching will be done later, by startup_attach */
13261333
/* note: we don't do newoutf(tcp) here either! */
13271334

@@ -1619,13 +1626,12 @@ init(int argc, char *argv[])
16191626
memset(acolumn_spaces, ' ', acolumn);
16201627
acolumn_spaces[acolumn] = '\0';
16211628

1622-
/* Must have PROG [ARGS], or -p PID. Not both. */
1623-
if (!argv[0] == !nprocs) {
1629+
if (!argv[0] && !nprocs) {
16241630
error_msg_and_help("must have PROG [ARGS] or -p PID");
16251631
}
16261632

1627-
if (nprocs != 0 && daemonized_tracer) {
1628-
error_msg_and_help("-D and -p are mutually exclusive");
1633+
if (!argv[0] && daemonized_tracer) {
1634+
error_msg_and_help("PROG [ARGS] must be specified with -D");
16291635
}
16301636

16311637
if (!followfork)
@@ -1722,9 +1728,9 @@ init(int argc, char *argv[])
17221728
opt_intr = INTR_WHILE_WAIT;
17231729

17241730
/* argv[0] -pPID -oFILE Default interactive setting
1725-
* yes 0 0 INTR_WHILE_WAIT
1731+
* yes * 0 INTR_WHILE_WAIT
17261732
* no 1 0 INTR_WHILE_WAIT
1727-
* yes 0 1 INTR_NEVER
1733+
* yes * 1 INTR_NEVER
17281734
* no 1 1 INTR_WHILE_WAIT
17291735
*/
17301736

tests/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
_newselect
99
adjtimex
1010
aio
11+
attach-p-cmd-cmd
12+
attach-p-cmd-p
1113
bpf
1214
caps
1315
clock_nanosleep

tests/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ check_PROGRAMS = \
5656
_newselect \
5757
adjtimex \
5858
aio \
59+
attach-p-cmd-cmd \
60+
attach-p-cmd-p \
5961
bpf \
6062
caps \
6163
clock_nanosleep \
@@ -299,6 +301,7 @@ TESTS = \
299301
xettimeofday.test \
300302
\
301303
count.test \
304+
attach-p-cmd.test \
302305
detach-sleeping.test \
303306
detach-stopped.test \
304307
detach-running.test \

tests/attach-p-cmd-cmd.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* This file is part of attach-p-cmd strace test.
3+
*
4+
* Copyright (c) 2016 Dmitry V. Levin <[email protected]>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. The name of the author may not be used to endorse or promote products
16+
* derived from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include "tests.h"
31+
#include <assert.h>
32+
#include <stdio.h>
33+
#include <unistd.h>
34+
35+
int
36+
main(void)
37+
{
38+
static const char text[] = "attach-p-cmd.test cmd";
39+
assert(chdir(text) == -1);
40+
pid_t pid = getpid();
41+
printf("%-5d chdir(\"%s\") = -1 ENOENT (%m)\n"
42+
"%-5d +++ exited with 0 +++\n", pid, text, pid);
43+
return 0;
44+
}

tests/attach-p-cmd-p.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* This file is part of attach-p-cmd strace test.
3+
*
4+
* Copyright (c) 2016 Dmitry V. Levin <[email protected]>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without
8+
* modification, are permitted provided that the following conditions
9+
* are met:
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
* 3. The name of the author may not be used to endorse or promote products
16+
* derived from this software without specific prior written permission.
17+
*
18+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21+
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28+
*/
29+
30+
#include "tests.h"
31+
#include <assert.h>
32+
#include <signal.h>
33+
#include <stdlib.h>
34+
#include <time.h>
35+
#include <sys/time.h>
36+
#include <unistd.h>
37+
38+
static void
39+
handler(int signo)
40+
{
41+
_exit(!chdir("attach-p-cmd.test -p"));
42+
}
43+
44+
int
45+
main(int ac, char **av)
46+
{
47+
if (ac < 2)
48+
error_msg_and_fail("missing operand");
49+
50+
if (ac > 2)
51+
error_msg_and_fail("extra operand");
52+
53+
const sigset_t set = {};
54+
const struct sigaction act = { .sa_handler = handler };
55+
const struct itimerval itv = { .it_value.tv_sec = atoi(av[1]) };
56+
57+
assert(sigaction(SIGALRM, &act, NULL) == 0);
58+
assert(sigprocmask(SIG_SETMASK, &set, NULL) == 0);
59+
if (setitimer(ITIMER_REAL, &itv, NULL))
60+
perror_msg_and_skip("setitimer");
61+
62+
for (;;);
63+
64+
return 0;
65+
}

tests/attach-p-cmd.test

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/sh
2+
#
3+
# Check that simultaneous use of -p option and tracing of a command works.
4+
#
5+
# Copyright (c) 2016 Dmitry V. Levin <[email protected]>
6+
# All rights reserved.
7+
#
8+
# Redistribution and use in source and binary forms, with or without
9+
# modification, are permitted provided that the following conditions
10+
# are met:
11+
# 1. Redistributions of source code must retain the above copyright
12+
# notice, this list of conditions and the following disclaimer.
13+
# 2. Redistributions in binary form must reproduce the above copyright
14+
# notice, this list of conditions and the following disclaimer in the
15+
# documentation and/or other materials provided with the distribution.
16+
# 3. The name of the author may not be used to endorse or promote products
17+
# derived from this software without specific prior written permission.
18+
#
19+
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20+
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21+
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22+
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23+
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24+
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26+
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28+
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29+
30+
. "${srcdir=.}/init.sh"
31+
32+
run_prog_skip_if_failed \
33+
kill -0 $$
34+
run_prog ./attach-p-cmd-cmd > /dev/null
35+
run_prog ./attach-p-cmd-p 1 > /dev/null
36+
37+
OUT="$LOG.out"
38+
./set_ptracer_any ./attach-p-cmd-p 1 > "$OUT" &
39+
tracee_pid=$!
40+
41+
while ! [ -s "$OUT" ]; do
42+
kill -0 $tracee_pid 2> /dev/null ||
43+
fail_ 'set_ptracer_any sleep failed'
44+
done
45+
46+
run_strace -a30 -echdir -p $tracee_pid ./attach-p-cmd-cmd > "$OUT"
47+
{
48+
printf '%-5d --- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---\n' $tracee_pid
49+
printf '%-5d chdir("attach-p-cmd.test -p") = -1 ENOENT (No such file or directory)\n' $tracee_pid
50+
printf '%-5d +++ exited with 0 +++\n' $tracee_pid
51+
} >> "$OUT"
52+
53+
match_diff "$LOG" "$OUT"
54+
rm -f "$OUT"

0 commit comments

Comments
 (0)