* tests/strace-D.test: Check -DD and -DDD.
* tests/strace-DD.test: New test.
* tests/strace-DDD.test: Likewise.
* tests/strace-DD.expected: New file.
* tests/strace-DDD.expected: Likewise.
* tests/tracer_ppid_pgid_sid.c: Likewise.
* tests/Makefile.am (check_PROGRAMS): Add tracer_ppid_pgid_sid.
(MISC_TESTS): Add strace-DD.test and strace-DDD.test.
(EXTRA_DIST): Add strace-DD.expected and strace-DDD.expected.
timerfd_xettime
times
times-fail
+tracer_ppid_pgid_sid
truncate
truncate64
ugetrlimit
status-unfinished-threads \
syslog-success \
threads-execve \
+ tracer_ppid_pgid_sid \
unblock_reset_raise \
unix-pair-send-recv \
unix-pair-sendto-recvfrom \
status-unfinished-threads.test \
strace-C.test \
strace-D.test \
+ strace-DD.test \
+ strace-DDD.test \
strace-E.test \
strace-S.test \
strace-T.test \
status-detached.expected \
strace-C.expected \
strace-D.expected \
+ strace-DD.expected \
+ strace-DDD.expected \
strace-E.expected \
strace-T.expected \
strace-ff.expected \
-#!/bin/sh
+#!/bin/sh -efu
#
# Check -D option.
#
dump_log_and_fail_with "$*: unexpected output"
# !-D: PPid > 0, TracerPid > 0, PPid == TracerPid
-run_strace -a14 -q -enone "$@" > "$OUT"
+run_strace -q -enone "$@" > "$OUT"
[ "$(get_parent_pid < "$OUT")" -gt 0 ] &&
[ "$(get_tracer_pid < "$OUT")" -gt 0 ] &&
[ "$(get_parent_pid < "$OUT")" = "$(get_tracer_pid < "$OUT")" ] || {
}
match_diff
-# -D: PPid > 0, TracerPid > 0, PPid != TracerPid
-run_strace -a14 -D -q -enone "$@" > "$OUT"
-[ "$(get_parent_pid < "$OUT")" -gt 0 ] &&
-[ "$(get_tracer_pid < "$OUT")" -gt 0 ] &&
-[ "$(get_parent_pid < "$OUT")" != "$(get_tracer_pid < "$OUT")" ] || {
- cat < "$OUT" > "$LOG"
- dump_log_and_fail_with "$STRACE $args: unexpected output"
+test_parent_tracer_pid()
+{
+ local d
+ d="$1"; shift
+
+ # -D/-DD/-DDD: PPid > 0, TracerPid > 0, PPid != TracerPid
+ run_strace $d -q -enone "$@" > "$OUT"
+ [ "$(get_parent_pid < "$OUT")" -gt 0 ] &&
+ [ "$(get_tracer_pid < "$OUT")" -gt 0 ] &&
+ [ "$(get_parent_pid < "$OUT")" != "$(get_tracer_pid < "$OUT")" ] || {
+ cat < "$OUT" > "$LOG"
+ dump_log_and_fail_with "$STRACE $args: unexpected output"
+ }
+ match_diff
}
-match_diff
-exit 0
+test_parent_tracer_pid -D "$@"
+test_parent_tracer_pid -DD "$@"
+test_parent_tracer_pid -DDD "$@"
--- /dev/null
+nanosleep({tv_sec=2, tv_nsec=0}, NULL) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- /dev/null
+#!/bin/sh -efu
+#
+# Check -DD option.
+#
+# Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+[ "$STRACE" = "$STRACE_EXE" ] ||
+ skip_ 'Not applicable: $STRACE != $STRACE_EXE'
+
+check_prog timeout
+
+test_D()
+{
+ local exp args
+ exp="$1"; shift
+
+ set -- -e signal=none -e trace=nanosleep "$@" ../sleep 2
+ args="$*"
+ set -- timeout -s XCPU 1 $STRACE -o "$LOG" "$@"
+ > "$LOG"
+ "$@" && rc=0 || rc=$?
+ [ "$rc" = 124 ] ||
+ dump_log_and_fail_with \
+ "$* failed with unexpected exit code $rc"
+ $SLEEP_A_BIT
+ match_diff "$LOG" "$exp"
+}
+
+printf %s 'nanosleep({tv_sec=2, tv_nsec=0}, ' > "$EXP"
+test_D "$EXP" -D
+test_D "$srcdir/$NAME.expected" -DD
+test_D "$srcdir/$NAME.expected" -DDD
--- /dev/null
++++ exited with 0 +++
--- /dev/null
+#!/bin/sh -efu
+#
+# Check -DDD option.
+#
+# Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+check_prog sed
+
+status_file=/proc/self/status
+[ -f "$status_file" ] ||
+ framework_skip_ "$status_file is not available"
+
+stat_file=/proc/self/stat
+[ -f "$stat_file" ] ||
+ framework_skip_ "$stat_file is not available"
+
+set -- -enone -esignal=none ../tracer_ppid_pgid_sid
+run_strace "$@" > "$OUT"
+read -r ppid pgid sid < "$OUT" &&
+[ "$ppid" -gt 1 ] &&
+[ "$pgid" -gt 0 ] &&
+[ "$sid" -gt 0 ] || {
+ cat < "$OUT" > "$LOG"
+ dump_log_and_fail_with "$STRACE $args: unexpected output"
+}
+match_diff
+
+pgid0="$pgid"
+sid0="$sid"
+
+run_strace -D "$@" > "$OUT"
+read -r ppid pgid sid < "$OUT" &&
+[ "$ppid" -eq 1 ] &&
+[ "$pgid" = "$pgid0" ] &&
+[ "$sid" = "$sid0" ] || {
+ cat < "$OUT" > "$LOG"
+ dump_log_and_fail_with "$STRACE $args: unexpected output"
+}
+match_diff
+
+run_strace -DD "$@" > "$OUT"
+read -r ppid pgid sid < "$OUT" &&
+[ "$ppid" -eq 1 ] &&
+[ "$pgid" -gt 1 ] &&
+[ "$pgid" != "$pgid0" ] &&
+[ "$pgid" != "$sid" ] &&
+[ "$sid" = "$sid0" ] || {
+ cat < "$OUT" > "$LOG"
+ dump_log_and_fail_with "$STRACE $args: unexpected output"
+}
+match_diff
+
+run_strace -DDD "$@" > "$OUT"
+read -r ppid pgid sid < "$OUT" &&
+[ "$ppid" -eq 1 ] &&
+[ "$pgid" -gt 1 ] &&
+[ "$pgid" != "$pgid0" ] &&
+[ "$sid" = "$pgid" ] &&
+[ "$sid" != "$sid0" ] || {
+ cat < "$OUT" > "$LOG"
+ dump_log_and_fail_with "$STRACE $args: unexpected output"
+}
+match_diff
--- /dev/null
+/*
+ * Helper program for strace-DDD.test
+ *
+ * Copyright (c) 2019 Dmitry V. Levin <ldv@altlinux.org>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int
+fetch_tracer_pid(const char *str)
+{
+ for (; isspace(*str); ++str)
+ ;
+ return atoi(str);
+}
+
+static int
+get_tracer_pid(void)
+{
+ static const char status[] = "/proc/self/status";
+ FILE *fp = fopen(status, "r");
+ if (!fp)
+ perror_msg_and_fail("fopen: %s", status);
+
+ static const char prefix[] = "TracerPid:";
+ const size_t prefix_len = sizeof(prefix) - 1;
+ const char *str = NULL;
+ char *line = NULL;
+ size_t n = 0;
+
+ while (getline(&line, &n, fp) > 0) {
+ if (strncmp(line, prefix, prefix_len) == 0) {
+ str = line + prefix_len;
+ break;
+ }
+ }
+ if (!str && !line)
+ perror_msg_and_fail("getline");
+
+ int pid = str ? fetch_tracer_pid(str) : 0;
+ free(line);
+ fclose(fp);
+
+ return pid;
+}
+
+static void
+get_ppid_pgid_sid(int pid, int *ppid, int *pgid, int *sid)
+{
+ char *stat;
+ if (asprintf(&stat, "/proc/%d/stat", pid) < 0)
+ perror_msg_and_fail("asprintf");
+
+ FILE *fp = fopen(stat, "r");
+ if (!fp)
+ perror_msg_and_fail("fopen: %s", stat);
+ char buf[4096];
+ if (!fgets(buf, sizeof(buf), fp))
+ perror_msg_and_fail("fgets: %s", stat);
+
+ fclose(fp);
+
+ const char *p = strrchr(buf, ')');
+ if (!p)
+ error_msg_and_fail("%s: parenthesis not found", stat);
+ ++p;
+
+ if (sscanf(p, " %*c %d %d %d", ppid, pgid, sid) != 3)
+ error_msg_and_fail("%s: sscanf failed", stat);
+}
+
+int
+main(void)
+{
+ int tracer_pid = get_tracer_pid();
+ if (tracer_pid < 0)
+ error_msg_and_fail("tracer_pid = %d", tracer_pid);
+
+ int ppid = 0, pgid = 0, sid = 0;
+ get_ppid_pgid_sid(tracer_pid, &ppid, &pgid, &sid);
+ printf("%d %d %d\n", ppid, pgid, sid);
+
+ return 0;
+}