Skip to content

Commit 869c788

Browse files
committed
selftests: harness: Stop using setjmp()/longjmp()
Usage of longjmp() was added to ensure that teardown is always run in commit 63e6b2a ("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 fff37bd ("selftests/harness: Fix fixture teardown"). Additionally this removes a incompatibility with nolibc, which does not support setjmp()/longjmp(). Signed-off-by: Thomas Weißschuh <[email protected]> Acked-by: Shuah Khan <[email protected]> Link: https://lore.kernel.org/r/20250505-nolibc-kselftest-harness-v4-12-ee4dd5257135@linutronix.de Signed-off-by: Thomas Weißschuh <[email protected]>
1 parent f46ddc2 commit 869c788

File tree

1 file changed

+15
-30
lines changed

1 file changed

+15
-30
lines changed

tools/testing/selftests/kselftest_harness.h

Lines changed: 15 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
#include <sys/types.h>
6868
#include <sys/wait.h>
6969
#include <unistd.h>
70-
#include <setjmp.h>
7170

7271
#include "kselftest.h"
7372

@@ -178,9 +177,7 @@
178177
struct __test_metadata *_metadata, \
179178
struct __fixture_variant_metadata __attribute__((unused)) *variant) \
180179
{ \
181-
if (setjmp(_metadata->env) == 0) \
182-
test_name(_metadata); \
183-
__test_check_assert(_metadata); \
180+
test_name(_metadata); \
184181
} \
185182
static struct __test_metadata _##test_name##_object = \
186183
{ .name = #test_name, \
@@ -425,24 +422,20 @@
425422
} \
426423
_metadata->variant = variant->data; \
427424
_metadata->self = self; \
428-
if (setjmp(_metadata->env) == 0) { \
429-
/* _metadata and potentially self are shared with all forks. */ \
430-
child = fork(); \
431-
if (child == 0) { \
432-
fixture_name##_setup(_metadata, self, variant->data); \
433-
/* Let setup failure terminate early. */ \
434-
if (_metadata->exit_code) \
435-
_exit(0); \
436-
*_metadata->no_teardown = false; \
437-
fixture_name##_##test_name(_metadata, self, variant->data); \
438-
} else if (child < 0 || child != waitpid(child, &status, 0)) { \
439-
ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
440-
_metadata->exit_code = KSFT_FAIL; \
441-
} \
442-
} \
425+
/* _metadata and potentially self are shared with all forks. */ \
426+
child = fork(); \
443427
if (child == 0) { \
428+
fixture_name##_setup(_metadata, self, variant->data); \
429+
/* Let setup failure terminate early. */ \
430+
if (_metadata->exit_code) \
431+
_exit(0); \
432+
*_metadata->no_teardown = false; \
433+
fixture_name##_##test_name(_metadata, self, variant->data); \
444434
_metadata->teardown_fn(false, _metadata, self, variant->data); \
445435
_exit(0); \
436+
} else if (child < 0 || child != waitpid(child, &status, 0)) { \
437+
ksft_print_msg("ERROR SPAWNING TEST GRANDCHILD\n"); \
438+
_metadata->exit_code = KSFT_FAIL; \
446439
} \
447440
_metadata->teardown_fn(true, _metadata, self, variant->data); \
448441
munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \
@@ -456,7 +449,6 @@
456449
/* Forward signal to __wait_for_test(). */ \
457450
kill(getpid(), WTERMSIG(status)); \
458451
} \
459-
__test_check_assert(_metadata); \
460452
} \
461453
static void wrapper_##fixture_name##_##test_name##_teardown( \
462454
bool in_parent, struct __test_metadata *_metadata, \
@@ -927,7 +919,6 @@ struct __test_metadata {
927919
int timeout; /* seconds to wait for test timeout */
928920
bool aborted; /* stopped test due to failed ASSERT */
929921
bool *no_teardown; /* fixture needs teardown */
930-
jmp_buf env; /* for exiting out of test early */
931922
void *self;
932923
const void *variant;
933924
struct __test_results *results;
@@ -963,19 +954,14 @@ static inline int __bail(int for_realz, struct __test_metadata *t)
963954
{
964955
/* if this is ASSERT, return immediately. */
965956
if (for_realz) {
966-
t->aborted = true;
967-
longjmp(t->env, 1);
957+
if (t->teardown_fn)
958+
t->teardown_fn(false, t, t->self, t->variant);
959+
abort();
968960
}
969961
/* otherwise, end the for loop and continue. */
970962
return 0;
971963
}
972964

973-
static inline void __test_check_assert(struct __test_metadata *t)
974-
{
975-
if (t->aborted)
976-
abort();
977-
}
978-
979965
static void __wait_for_test(struct __test_metadata *t)
980966
{
981967
/*
@@ -1208,7 +1194,6 @@ static void __run_test(struct __fixture_metadata *f,
12081194
t->trigger = 0;
12091195
t->aborted = false;
12101196
t->no_teardown = NULL;
1211-
memset(t->env, 0, sizeof(t->env));
12121197
memset(t->results->reason, 0, sizeof(t->results->reason));
12131198

12141199
snprintf(test_name, sizeof(test_name), "%s%s%s.%s",

0 commit comments

Comments
 (0)