* 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.
===============================================
* 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.
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
static void
startup_attach(void)
{
+ pid_t parent_pid = strace_tracer_pid;
unsigned int tcbi;
struct tcb *tcp;
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;
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);
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! */
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)
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
*/
_newselect
adjtimex
aio
+attach-p-cmd-cmd
+attach-p-cmd-p
bpf
caps
clock_nanosleep
_newselect \
adjtimex \
aio \
+ attach-p-cmd-cmd \
+ attach-p-cmd-p \
bpf \
caps \
clock_nanosleep \
xettimeofday.test \
\
count.test \
+ attach-p-cmd.test \
detach-sleeping.test \
detach-stopped.test \
detach-running.test \
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+#!/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"