[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250304-nolibc-kselftest-harness-v1-13-adca7cd231e2@linutronix.de>
Date: Tue, 04 Mar 2025 08:10:43 +0100
From: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
To: Shuah Khan <shuah@...nel.org>, Shuah Khan <skhan@...uxfoundation.org>,
Willy Tarreau <w@....eu>,
Thomas Weißschuh <linux@...ssschuh.net>
Cc: linux-kernel@...r.kernel.org, linux-kselftest@...r.kernel.org,
Thomas Weißschuh <thomas.weissschuh@...utronix.de>
Subject: [PATCH 13/32] selftests: harness: Stop using setjmp()/longjmp()
Usage of longjmp() was added to ensure that teardown is always run in
commit 63e6b2a42342 ("selftests/harness: Run TEARDOWN for ASSERT failures")
However instead of calling longjmp() to the teardown handler it is easier to
just call the teardown handler directly from __bail().
Any potential duplicate teardown invocations are harmless as the actual
handler will only ever be executed once since
commit fff37bd32c76 ("selftests/harness: Fix fixture teardown").
Additionally this removes a incompatibility with nolibc,
which does not support setjmp()/longjmp().
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@...utronix.de>
---
tools/testing/selftests/kselftest_harness.h | 49 ++++++++++-------------------
1 file changed, 17 insertions(+), 32 deletions(-)
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index efc855b93315892a822c9eefc8d7a3784793c754..b7842dd5302375b75416830c22fac0775e0d12d1 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -70,7 +70,6 @@
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
-#include <setjmp.h>
#endif
#include "kselftest.h"
@@ -182,9 +181,7 @@
struct __test_metadata *_metadata, \
struct __fixture_variant_metadata __attribute__((unused)) *variant) \
{ \
- if (setjmp(_metadata->env) == 0) \
- test_name(_metadata, NULL, NULL); \
- __test_check_assert(_metadata); \
+ test_name(_metadata, NULL, NULL); \
} \
static struct __test_metadata _##test_name##_object = \
{ .name = #test_name, \
@@ -429,24 +426,20 @@
self = &self_private; \
} \
} \
- if (setjmp(_metadata->env) == 0) { \
- /* _metadata and potentially self are shared with all forks. */ \
- child = fork(); \
- if (child == 0) { \
- fixture_name##_setup(_metadata, self, variant->data); \
- /* Let setup failure terminate early. */ \
- if (_metadata->exit_code) \
- _exit(0); \
- *_metadata->no_teardown = false; \
- fixture_name##_##test_name(_metadata, self, variant->data); \
- } else if (child < 0 || child != waitpid(child, &status, 0)) { \
- ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
- _metadata->exit_code = KSFT_FAIL; \
- } \
- } \
+ /* _metadata and potentially self are shared with all forks. */ \
+ child = fork(); \
if (child == 0) { \
+ fixture_name##_setup(_metadata, self, variant->data); \
+ /* Let setup failure terminate early. */ \
+ if (_metadata->exit_code) \
+ _exit(0); \
+ *_metadata->no_teardown = false; \
+ fixture_name##_##test_name(_metadata, self, variant->data); \
_metadata->teardown_fn(false, _metadata, self, variant->data); \
_exit(0); \
+ } else if (child < 0 || child != waitpid(child, &status, 0)) { \
+ ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
+ _metadata->exit_code = KSFT_FAIL; \
} \
_metadata->teardown_fn(true, _metadata, self, variant->data); \
munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \
@@ -460,7 +453,6 @@
/* Forward signal to __wait_for_test(). */ \
kill(getpid(), WTERMSIG(status)); \
} \
- __test_check_assert(_metadata); \
} \
static void wrapper_##fixture_name##_##test_name##_teardown( \
bool in_parent, struct __test_metadata *_metadata, \
@@ -761,7 +753,7 @@
*/
#define OPTIONAL_HANDLER(_assert) \
for (; _metadata->trigger; _metadata->trigger = \
- __bail(_assert, _metadata))
+ __bail(_assert, _metadata, self, variant))
#define is_signed_type(var) (!!(((__typeof__(var))(-1)) < (__typeof__(var))1))
@@ -931,7 +923,6 @@ struct __test_metadata {
int timeout; /* seconds to wait for test timeout */
bool aborted; /* stopped test due to failed ASSERT */
bool *no_teardown; /* fixture needs teardown */
- jmp_buf env; /* for exiting out of test early */
struct __test_results *results;
struct __test_metadata *prev, *next;
};
@@ -961,23 +952,18 @@ static inline void __register_xfail(struct __test_xfail *xf)
__LIST_APPEND(xf->variant->xfails, xf);
}
-static inline int __bail(int for_realz, struct __test_metadata *t)
+static inline int __bail(int for_realz, struct __test_metadata *t, void *self, const void *variant)
{
/* if this is ASSERT, return immediately. */
if (for_realz) {
- t->aborted = true;
- longjmp(t->env, 1);
+ if (t->teardown_fn)
+ t->teardown_fn(false, t, self, variant);
+ abort();
}
/* otherwise, end the for loop and continue. */
return 0;
}
-static inline void __test_check_assert(struct __test_metadata *t)
-{
- if (t->aborted)
- abort();
-}
-
static void __wait_for_test(struct __test_metadata *t)
{
/*
@@ -1210,7 +1196,6 @@ static void __run_test(struct __fixture_metadata *f,
t->trigger = 0;
t->aborted = false;
t->no_teardown = NULL;
- memset(t->env, 0, sizeof(t->env));
memset(t->results->reason, 0, sizeof(t->results->reason));
snprintf(test_name, sizeof(test_name), "%s%s%s.%s",
--
2.48.1
Powered by blists - more mailing lists