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

Paul Chaignon paul.chaignon at gmail.com
Fri Jun 28 09:34:40 UTC 2019


This patch adds 6 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).  The test cases for unfinished
and none rely on a child thread execve'ing the lead thread.  The test case
for detached interrupts strace while attached to a sleeping process.

* tests/status-all.c: New test.
* tests/status-detached.test: New test.
* tests/status-detached.expected: New file.
* tests/status-failed.c: New test.
* tests/status-none.c: New test.
* tests/status-successful.c: New test.
* tests/status-unfinished.c: New test.
* tests/status.c: New file.
* tests/tests.h (test_status_chdir): New prototype.
* tests/.gitignore: Add status-all, status-failed, status-none,
status-successful, and status-unfinished.
* tests/gen_tests.in: Likewise.
* tests/pure_executables.list: Likewise.
* tests/Makefile.am: Add status.c, status_none_LDADD,
status_unfinished_LDADD, and status-detached.test.

Signed-off-by: Paul Chaignon <paul.chaignon at gmail.com>
Co-Authored-by: Burkhard Kohl <burkhard.kohl at intel.com>
---
 tests/.gitignore               |  5 +++
 tests/Makefile.am              |  5 +++
 tests/gen_tests.in             |  5 +++
 tests/pure_executables.list    |  5 +++
 tests/status-all.c             | 25 ++++++++++++
 tests/status-detached.expected |  1 +
 tests/status-detached.test     | 17 ++++++++
 tests/status-failed.c          | 25 ++++++++++++
 tests/status-none.c            | 65 ++++++++++++++++++++++++++++++
 tests/status-successful.c      | 25 ++++++++++++
 tests/status-unfinished.c      | 72 ++++++++++++++++++++++++++++++++++
 tests/status.c                 | 22 +++++++++++
 tests/tests.h                  |  3 ++
 13 files changed, 275 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.c
 create mode 100644 tests/status-successful.c
 create mode 100644 tests/status-unfinished.c
 create mode 100644 tests/status.c

diff --git a/tests/.gitignore b/tests/.gitignore
index 94420216..ed02a7cd 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -559,6 +559,11 @@ stat
 stat64
 statfs
 statfs64
+status-all
+status-failed
+status-none
+status-successful
+status-unfinished
 statx
 swap
 sxetmask
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7247a597..9a518159 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 \
@@ -190,6 +191,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_LDADD = -lpthread $(LDADD)
+status_unfinished_LDADD = -lpthread $(LDADD)
 threads_execve_LDADD = -lpthread $(clock_LIBS) $(LDADD)
 times_LDADD = $(clock_LIBS) $(LDADD)
 truncate64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
@@ -336,6 +339,7 @@ MISC_TESTS = \
 	restart_syscall.test \
 	sigblock.test \
 	sigign.test \
+	status-detached.test \
 	strace-C.test \
 	strace-E.test \
 	strace-S.test \
@@ -423,6 +427,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 487b9608..eaea6908 100644
--- a/tests/gen_tests.in
+++ b/tests/gen_tests.in
@@ -465,6 +465,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	-f -e trace=execve,exit_group,nanosleep -e status=none
+status-successful	-a10 -e trace=chdir -z
+status-unfinished	-a14 -f -e trace=execve,exit_group,nanosleep -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 1e509dcf..6d8d5f30 100755
--- a/tests/pure_executables.list
+++ b/tests/pure_executables.list
@@ -471,6 +471,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..d530c831
--- /dev/null
+++ b/tests/status-all.c
@@ -0,0 +1,25 @@
+/*
+ * Check status 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..d6eefab9
--- /dev/null
+++ b/tests/status-detached.test
@@ -0,0 +1,17 @@
+#!/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 trace=nanosleep -e status=detached ../sleep 2 &
+pid=$!
+../sleep 1
+kill $pid
+match_grep
diff --git a/tests/status-failed.c b/tests/status-failed.c
new file mode 100644
index 00000000..40e3f844
--- /dev/null
+++ b/tests/status-failed.c
@@ -0,0 +1,25 @@
+/*
+ * Check status 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.c b/tests/status-none.c
new file mode 100644
index 00000000..3c6db4a8
--- /dev/null
+++ b/tests/status-none.c
@@ -0,0 +1,65 @@
+/*
+ * Check status 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 <asm/unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static pid_t leader;
+static pid_t tid;
+
+static pid_t
+k_gettid(void)
+{
+	return syscall(__NR_gettid);
+}
+
+static void *
+thread(void *arg)
+{
+	tid = k_gettid();
+
+	printf("%-5d +++ superseded by execve in pid %u +++\n",
+	       leader, tid);
+
+	struct timespec ts = { .tv_nsec = 100000000 };
+	(void) clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
+
+	ts.tv_nsec = 12345;
+	(void) nanosleep(&ts, NULL);
+
+	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-successful.c b/tests/status-successful.c
new file mode 100644
index 00000000..4c550290
--- /dev/null
+++ b/tests/status-successful.c
@@ -0,0 +1,25 @@
+/*
+ * Check status 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.c b/tests/status-unfinished.c
new file mode 100644
index 00000000..b751daf7
--- /dev/null
+++ b/tests/status-unfinished.c
@@ -0,0 +1,72 @@
+/*
+ * Check status 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 <asm/unistd.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static pid_t leader;
+static pid_t tid;
+
+static pid_t
+k_gettid(void)
+{
+	return syscall(__NR_gettid);
+}
+
+static void *
+thread(void *arg)
+{
+	tid = k_gettid();
+
+	printf("%-5d <... nanosleep resumed> <unfinished ...>) = ?\n"
+	       "%-5d +++ superseded by execve in pid %u +++\n",
+	       leader, leader, tid);
+
+	struct timespec ts = { .tv_nsec = 100000000 };
+	(void) clock_nanosleep(CLOCK_REALTIME, 0, &ts, NULL);
+
+	ts.tv_nsec = 12345;
+	(void) nanosleep(&ts, NULL);
+
+	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 };
+	static char leader_str[sizeof(leader) * 3];
+	snprintf(leader_str, sizeof(leader_str), "%-5d", leader);
+	printf("%s nanosleep({tv_sec=%u, tv_nsec=0}"
+	       ",  <unfinished ...>\n",
+	       leader_str, (unsigned int) ts.tv_sec);
+	(void) nanosleep(&ts, 0);
+
+	return 1;
+}
diff --git a/tests/status.c b/tests/status.c
new file mode 100644
index 00000000..64280d8c
--- /dev/null
+++ b/tests/status.c
@@ -0,0 +1,22 @@
+/*
+ * 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