From 626e8d694dd3dfaad1a2ab2219e4a703dc8045a3 Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Mon, 7 Oct 2019 11:33:37 +0000 Subject: [PATCH] tests: check -DD and -DDD options * 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. --- tests/.gitignore | 1 + tests/Makefile.am | 5 ++ tests/strace-D.test | 30 +++++++----- tests/strace-DD.expected | 1 + tests/strace-DD.test | 37 +++++++++++++++ tests/strace-DDD.expected | 1 + tests/strace-DDD.test | 68 ++++++++++++++++++++++++++ tests/tracer_ppid_pgid_sid.c | 92 ++++++++++++++++++++++++++++++++++++ 8 files changed, 224 insertions(+), 11 deletions(-) create mode 100644 tests/strace-DD.expected create mode 100755 tests/strace-DD.test create mode 100644 tests/strace-DDD.expected create mode 100755 tests/strace-DDD.test create mode 100644 tests/tracer_ppid_pgid_sid.c diff --git a/tests/.gitignore b/tests/.gitignore index 1cfe11ca..7c1c8e58 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -635,6 +635,7 @@ timer_xettime timerfd_xettime times times-fail +tracer_ppid_pgid_sid truncate truncate64 ugetrlimit diff --git a/tests/Makefile.am b/tests/Makefile.am index 57f7ad3a..3b377093 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -176,6 +176,7 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \ status-unfinished-threads \ syslog-success \ threads-execve \ + tracer_ppid_pgid_sid \ unblock_reset_raise \ unix-pair-send-recv \ unix-pair-sendto-recvfrom \ @@ -364,6 +365,8 @@ MISC_TESTS = \ 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 \ @@ -457,6 +460,8 @@ EXTRA_DIST = \ status-detached.expected \ strace-C.expected \ strace-D.expected \ + strace-DD.expected \ + strace-DDD.expected \ strace-E.expected \ strace-T.expected \ strace-ff.expected \ diff --git a/tests/strace-D.test b/tests/strace-D.test index 031d765e..6fc117af 100755 --- a/tests/strace-D.test +++ b/tests/strace-D.test @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/sh -efu # # Check -D option. # @@ -35,7 +35,7 @@ set -- sed -n -E '/^(P|Tracer)Pid:/p' "$status_file" 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")" ] || { @@ -44,14 +44,22 @@ run_strace -a14 -q -enone "$@" > "$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 "$@" diff --git a/tests/strace-DD.expected b/tests/strace-DD.expected new file mode 100644 index 00000000..56d90dd1 --- /dev/null +++ b/tests/strace-DD.expected @@ -0,0 +1 @@ +nanosleep({tv_sec=2, tv_nsec=0}, NULL) = ? ERESTART_RESTARTBLOCK (Interrupted by signal) diff --git a/tests/strace-DD.test b/tests/strace-DD.test new file mode 100755 index 00000000..f0b19789 --- /dev/null +++ b/tests/strace-DD.test @@ -0,0 +1,37 @@ +#!/bin/sh -efu +# +# Check -DD option. +# +# Copyright (c) 2019 Dmitry V. Levin +# 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 diff --git a/tests/strace-DDD.expected b/tests/strace-DDD.expected new file mode 100644 index 00000000..78c9d2dc --- /dev/null +++ b/tests/strace-DDD.expected @@ -0,0 +1 @@ ++++ exited with 0 +++ diff --git a/tests/strace-DDD.test b/tests/strace-DDD.test new file mode 100755 index 00000000..577de496 --- /dev/null +++ b/tests/strace-DDD.test @@ -0,0 +1,68 @@ +#!/bin/sh -efu +# +# Check -DDD option. +# +# Copyright (c) 2019 Dmitry V. Levin +# 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 diff --git a/tests/tracer_ppid_pgid_sid.c b/tests/tracer_ppid_pgid_sid.c new file mode 100644 index 00000000..ed4a75e0 --- /dev/null +++ b/tests/tracer_ppid_pgid_sid.c @@ -0,0 +1,92 @@ +/* + * Helper program for strace-DDD.test + * + * Copyright (c) 2019 Dmitry V. Levin + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "tests.h" +#include +#include +#include +#include +#include + +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; +} -- 2.50.1