[PATCH v8 4/4] tests: check status qualifier

Paul Chaignon paul.chaignon at gmail.com
Thu Jul 11 14:10:02 UTC 2019


This change adds 8 test cases for -e status with unfinished, failed,
none, successful, detached, and the whole set.  The test cases for
failed, successful, and the whole set use chdir(2).  Threaded test cases
for unfinished and none rely on a child thread execve'ing the lead
thread.  There are additional single-threaded tests for status=none and
status=unfinished.  The test case for detached interrupts strace while
attached to a sleeping process.

* tests/status.c: New file.
* tests/status-all.c: Likewise.
* tests/status-failed.c: Likewise.
* tests/status-detached.expected: Likewise.
* tests/status-none.c: Likewise.
* tests/status-none-threads.c: Likewise.
* tests/status-successful.c: Likewise.
* tests/status-unfinished-threads.c: Likewise.
* tests/status-unfinished.c: Likewise.
* tests/status-detached.test: New test.
* tests/status-none-threads.test: Likewise.
* tests/status-unfinished-threads.test: Likewise.
* tests/tests.h (test_status_chdir): New prototype.
* tests/.gitignore: Add status-all, status-failed, status-none,
status-none-threads, status-successful, status-unfinished,
and status-unfinished-threads.
* tests/gen_tests.in: Add status-all, status-failed, status-successful,
status-none, and status-unfinished.
* tests/pure_executables.list: Likewise.
* tests/Makefile.am (libtests_a_SOURCES): Add status.c.
(check_PROGRAMS): Add status-none-threads and status-unfinished-threads.
(status_none_threads_LDADD, status_unfinished_threads_LDADD): New
variables.
(MISC_TESTS): Add status-detached.test, status-none-threads.test, and
status-unfinished-threads.test.
(EXTRA_DIST): Add status-detached.expected.

Co-Authored-by: Burkhard Kohl <burkhard.kohl at intel.com>
Signed-off-by: Paul Chaignon <paul.chaignon at gmail.com>
Co-Authored-by: Dmitry V. Levin <ldv at altlinux.org>
---
 tests/.gitignore                     |  7 ++++
 tests/Makefile.am                    |  9 +++++
 tests/gen_tests.in                   |  5 +++
 tests/pure_executables.list          |  5 +++
 tests/status-all.c                   | 24 ++++++++++++
 tests/status-detached.expected       |  1 +
 tests/status-detached.test           | 18 +++++++++
 tests/status-failed.c                | 24 ++++++++++++
 tests/status-none-threads.c          | 53 +++++++++++++++++++++++++++
 tests/status-none-threads.test       | 44 ++++++++++++++++++++++
 tests/status-none.c                  | 18 +++++++++
 tests/status-successful.c            | 24 ++++++++++++
 tests/status-unfinished-threads.c    | 55 ++++++++++++++++++++++++++++
 tests/status-unfinished-threads.test | 12 ++++++
 tests/status-unfinished.c            | 19 ++++++++++
 tests/status.c                       | 21 +++++++++++
 tests/tests.h                        |  3 ++
 17 files changed, 342 insertions(+)
 create mode 100644 tests/status-all.c
 create mode 100644 tests/status-detached.expected
 create mode 100755 tests/status-detached.test
 create mode 100644 tests/status-failed.c
 create mode 100644 tests/status-none-threads.c
 create mode 100755 tests/status-none-threads.test
 create mode 100644 tests/status-none.c
 create mode 100644 tests/status-successful.c
 create mode 100644 tests/status-unfinished-threads.c
 create mode 100755 tests/status-unfinished-threads.test
 create mode 100644 tests/status-unfinished.c
 create mode 100644 tests/status.c

diff --git a/tests/.gitignore b/tests/.gitignore
index caf26676..7774ceec 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -579,6 +579,13 @@ stat
 stat64
 statfs
 statfs64
+status-all
+status-failed
+status-none
+status-none-threads
+status-successful
+status-unfinished
+status-unfinished-threads
 statx
 swap
 sxetmask
diff --git a/tests/Makefile.am b/tests/Makefile.am
index fc914d54..ab2ae78d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -49,6 +49,7 @@ libtests_a_SOURCES = \
 	signal2name.c \
 	skip_unavailable.c \
 	sprintrc.c \
+	status.c \
 	tail_alloc.c \
 	test_netlink.h \
 	test_nlattr.h \
@@ -157,6 +158,8 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
 	sleep \
 	stack-fcall \
 	stack-fcall-mangled \
+	status-none-threads \
+	status-unfinished-threads \
 	threads-execve \
 	unblock_reset_raise \
 	unix-pair-send-recv \
@@ -191,6 +194,8 @@ preadv_pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 stat64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
 statfs_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
+status_none_threads_LDADD = -lpthread $(LDADD)
+status_unfinished_threads_LDADD = -lpthread $(LDADD)
 threads_execve_LDADD = -lpthread $(clock_LIBS) $(LDADD)
 times_LDADD = $(clock_LIBS) $(LDADD)
 truncate64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
@@ -338,6 +343,9 @@ MISC_TESTS = \
 	restart_syscall.test \
 	sigblock.test \
 	sigign.test \
+	status-detached.test \
+	status-none-threads.test \
+	status-unfinished-threads.test \
 	strace-C.test \
 	strace-E.test \
 	strace-S.test \
@@ -425,6 +433,7 @@ EXTRA_DIST = \
 	sockaddr_xlat.c \
 	sockname.c \
 	stack-fcall.h \
+	status-detached.expected \
 	strace-C.expected \
 	strace-E.expected \
 	strace-T.expected \
diff --git a/tests/gen_tests.in b/tests/gen_tests.in
index d2d311ad..f90910f1 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -484,6 +484,11 @@ stat	-a32 -v -P stat.sample -P /dev/full
 stat64	-a32 -v -P stat.sample -P /dev/full
 statfs	-a17
 statfs64	-a23
+status-all	-a10 -e trace=chdir -e status=detached,failed,successful,unavailable,unfinished
+status-failed	-a10 -e trace=chdir -Z
+status-none	-e trace=all -e status=none
+status-successful	-a10 -e trace=chdir -z
+status-unfinished	-a10 -e trace=all -e status=unfinished
 statx	-a32 -v -P stat.sample -P /dev/full
 swap	-a23 -e trace=swapon,swapoff
 sxetmask	-a11 -e trace=sgetmask,ssetmask
diff --git a/tests/pure_executables.list b/tests/pure_executables.list
index 96fad109..3224999e 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -491,6 +491,11 @@ stat
 stat64
 statfs
 statfs64
+status-all
+status-failed
+status-none
+status-successful
+status-unfinished
 statx
 swap
 sxetmask
diff --git a/tests/status-all.c b/tests/status-all.c
new file mode 100644
index 00000000..db9510af
--- /dev/null
+++ b/tests/status-all.c
@@ -0,0 +1,24 @@
+/*
+ * Check status=all filtering for failed and successful syscalls.
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+int
+main(void)
+{
+	static const char sample_valid[] = ".";
+	static const char sample_invalid[] = "";
+
+	test_status_chdir(sample_valid, 1, 1);
+	test_status_chdir(sample_invalid, 1, 1);
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/status-detached.expected b/tests/status-detached.expected
new file mode 100644
index 00000000..0a6325f5
--- /dev/null
+++ b/tests/status-detached.expected
@@ -0,0 +1 @@
+nanosleep\({tv_sec=2, tv_nsec=0},  <detached \.\.\.>
diff --git a/tests/status-detached.test b/tests/status-detached.test
new file mode 100755
index 00000000..febdc713
--- /dev/null
+++ b/tests/status-detached.test
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Check -e status=detached option.
+#
+# Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+# -I2 avoids blocking all fatal signals, the default when using -o.
+$STRACE -o "$LOG" -I2 -e status=detached ../sleep 2 &
+pid=$!
+../sleep 1
+kill $pid
+wait
+match_grep
diff --git a/tests/status-failed.c b/tests/status-failed.c
new file mode 100644
index 00000000..81d2885a
--- /dev/null
+++ b/tests/status-failed.c
@@ -0,0 +1,24 @@
+/*
+ * Check status=failed filtering for failed and successful syscalls.
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+int
+main(void)
+{
+	static const char sample_valid[] = ".";
+	static const char sample_invalid[] = "";
+
+	test_status_chdir(sample_valid, 0, 1);
+	test_status_chdir(sample_invalid, 0, 1);
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/status-none-threads.c b/tests/status-none-threads.c
new file mode 100644
index 00000000..8ba9857d
--- /dev/null
+++ b/tests/status-none-threads.c
@@ -0,0 +1,53 @@
+/*
+ * Check status=none filtering when a non-leader thread invokes execve.
+ *
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+
+static pid_t leader;
+
+static void *
+thread(void *arg)
+{
+	struct timespec ts = { .tv_nsec = 100000000 };
+	(void) nanosleep(&ts, NULL);
+
+	printf("%-5d +++ superseded by execve in pid %u +++\n",
+	       leader, (int) syscall(__NR_gettid));
+
+	char *argv[] = {((char **) arg)[0], (char *) "0", NULL};
+	execve(argv[0], argv, NULL);
+	perror_msg_and_fail("execve");
+}
+
+int
+main(int ac, char **av)
+{
+	setvbuf(stdout, NULL, _IONBF, 0);
+	leader = getpid();
+
+	if (ac > 1) {
+		printf("%-5d +++ exited with 0 +++\n", leader);
+		return 0;
+	}
+
+	pthread_t t;
+	errno = pthread_create(&t, NULL, thread, av);
+	if (errno)
+		perror_msg_and_fail("pthread_create");
+
+	struct timespec ts = { .tv_sec = 123 };
+	(void) nanosleep(&ts, 0);
+
+	return 1;
+}
diff --git a/tests/status-none-threads.test b/tests/status-none-threads.test
new file mode 100755
index 00000000..cae8a79f
--- /dev/null
+++ b/tests/status-none-threads.test
@@ -0,0 +1,44 @@
+#!/bin/sh
+#
+# Check status=none filtering when a non-leader thread invokes execve.
+#
+# Copyright (c) 2019 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+
+# Check that PTRACE_EVENT_EXEC support in kernel is good enough.
+# The kernel before commit v3.1-rc1~308^2~7 reported 0 instead of old pid.
+require_min_kernel_version_or_skip 3.1
+
+check_prog diff
+run_prog_skip_if_failed date +%s > /dev/null
+s0="$(date +%s)"
+
+run_prog > /dev/null
+
+set -- -a14 -f -e status=${status_filter:-none} $args
+
+# Due to probabilistic nature of the test, try it several times.
+while :; do
+	> "$LOG" || fail_ "failed to write $LOG"
+	rc=0
+	$STRACE -o "$LOG" "$@" > "$EXP" || {
+		rc=$?
+		cat < "$LOG" >&2
+	}
+
+	if [ "$rc" = 0 ] && diff -u -- "$EXP" "$LOG"; then
+		exit 0
+	fi
+
+	s1="$(date +%s)"
+	[ "$(($s1-$s0))" -gt "$(($TIMEOUT_DURATION/2))" ] ||
+		continue
+
+	[ "$rc" = 0 ] &&
+		fail_ "$STRACE $* output mismatch" ||
+		fail_ "$STRACE $* failed with code $rc"
+done
diff --git a/tests/status-none.c b/tests/status-none.c
new file mode 100644
index 00000000..0144a60c
--- /dev/null
+++ b/tests/status-none.c
@@ -0,0 +1,18 @@
+/*
+ * Check basic -e status=none syscall filtering.
+ *
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+int
+main(void)
+{
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/status-successful.c b/tests/status-successful.c
new file mode 100644
index 00000000..b37854af
--- /dev/null
+++ b/tests/status-successful.c
@@ -0,0 +1,24 @@
+/*
+ * Check status=successful filtering for failed and successful syscalls.
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+int
+main(void)
+{
+	static const char sample_valid[] = ".";
+	static const char sample_invalid[] = "";
+
+	test_status_chdir(sample_valid, 1, 0);
+	test_status_chdir(sample_invalid, 1, 0);
+	puts("+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/status-unfinished-threads.c b/tests/status-unfinished-threads.c
new file mode 100644
index 00000000..098096c6
--- /dev/null
+++ b/tests/status-unfinished-threads.c
@@ -0,0 +1,55 @@
+/*
+ * Check status=unfinished filtering when a non-leader thread invokes execve.
+ *
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <asm/unistd.h>
+
+static pid_t leader;
+
+static void *
+thread(void *arg)
+{
+	struct timespec ts = { .tv_nsec = 100000000 };
+	(void) nanosleep(&ts, NULL);
+
+	printf("%-5d nanosleep({tv_sec=123, tv_nsec=0},  <unfinished ...>) = ?\n"
+	       "%-5d +++ superseded by execve in pid %u +++\n",
+	       leader, leader, (int) syscall(__NR_gettid));
+
+	char *argv[] = {((char **) arg)[0], (char *) "0", NULL};
+	execve(argv[0], argv, NULL);
+	perror_msg_and_fail("execve");
+}
+
+int
+main(int ac, char **av)
+{
+	setvbuf(stdout, NULL, _IONBF, 0);
+	leader = getpid();
+
+	if (ac > 1) {
+		printf("%-5d exit_group(0) = ?\n"
+		       "%-5d +++ exited with 0 +++\n", leader, leader);
+		return 0;
+	}
+
+	pthread_t t;
+	errno = pthread_create(&t, NULL, thread, av);
+	if (errno)
+		perror_msg_and_fail("pthread_create");
+
+	struct timespec ts = { .tv_sec = 123 };
+	(void) nanosleep(&ts, 0);
+
+	return 1;
+}
diff --git a/tests/status-unfinished-threads.test b/tests/status-unfinished-threads.test
new file mode 100755
index 00000000..f54a323f
--- /dev/null
+++ b/tests/status-unfinished-threads.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Check status=unfinished filtering when a non-leader thread invokes execve.
+#
+# Copyright (c) 2019 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+status_filter=unfinished
+
+. "${srcdir=.}"/status-none-threads.test
diff --git a/tests/status-unfinished.c b/tests/status-unfinished.c
new file mode 100644
index 00000000..de78eee4
--- /dev/null
+++ b/tests/status-unfinished.c
@@ -0,0 +1,19 @@
+/*
+ * Check basic -e status=unfinished syscall filtering.
+ *
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+
+int
+main(void)
+{
+	puts("exit_group(0) = ?\n"
+	     "+++ exited with 0 +++");
+	return 0;
+}
diff --git a/tests/status.c b/tests/status.c
new file mode 100644
index 00000000..82fd8b18
--- /dev/null
+++ b/tests/status.c
@@ -0,0 +1,21 @@
+/*
+ * Helper function to check -e status option.
+ *
+ * Copyright (c) 2019 Intel Corporation
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+#include <unistd.h>
+
+void
+test_status_chdir(const char *dir, bool print_success, bool print_fail)
+{
+	long rc = chdir(dir);
+	if ((rc == -1 && print_fail) || (rc != -1 && print_success))
+		printf("chdir(\"%s\") = %s\n", dir, sprintrc(rc));
+}
diff --git a/tests/tests.h b/tests/tests.h
index 1a1b02c3..4fca9886 100644
--- a/tests/tests.h
+++ b/tests/tests.h
@@ -208,6 +208,9 @@ int printxval(const struct xlat *, const unsigned long long, const char *);
 int socketcall(const int nr, const int call,
 	       long a1, long a2, long a3, long a4, long a5);
 
+/* Call chdir and print strace output depending on flags. */
+void test_status_chdir(const char *dir, bool print_success, bool print_fail);
+
 /* Wrappers for recvmmsg and sendmmsg syscalls. */
 struct mmsghdr;
 struct timespec;
-- 
2.17.1



More information about the Strace-devel mailing list