mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-04 20:19:47 +08:00
selftests: harness: Stop using setjmp()/longjmp()
Usage of longjmp() was added to ensure that teardown is always run in commit63e6b2a423
("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 commitfff37bd32c
("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@linutronix.de> Acked-by: Shuah Khan <skhan@linuxfoundation.org> Link: https://lore.kernel.org/r/20250505-nolibc-kselftest-harness-v4-12-ee4dd5257135@linutronix.de Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
This commit is contained in:
parent
f46ddc2cba
commit
869c788909
@ -67,7 +67,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <setjmp.h>
|
|
||||||
|
|
||||||
#include "kselftest.h"
|
#include "kselftest.h"
|
||||||
|
|
||||||
@ -178,9 +177,7 @@
|
|||||||
struct __test_metadata *_metadata, \
|
struct __test_metadata *_metadata, \
|
||||||
struct __fixture_variant_metadata __attribute__((unused)) *variant) \
|
struct __fixture_variant_metadata __attribute__((unused)) *variant) \
|
||||||
{ \
|
{ \
|
||||||
if (setjmp(_metadata->env) == 0) \
|
test_name(_metadata); \
|
||||||
test_name(_metadata); \
|
|
||||||
__test_check_assert(_metadata); \
|
|
||||||
} \
|
} \
|
||||||
static struct __test_metadata _##test_name##_object = \
|
static struct __test_metadata _##test_name##_object = \
|
||||||
{ .name = #test_name, \
|
{ .name = #test_name, \
|
||||||
@ -425,24 +422,20 @@
|
|||||||
} \
|
} \
|
||||||
_metadata->variant = variant->data; \
|
_metadata->variant = variant->data; \
|
||||||
_metadata->self = self; \
|
_metadata->self = self; \
|
||||||
if (setjmp(_metadata->env) == 0) { \
|
/* _metadata and potentially self are shared with all forks. */ \
|
||||||
/* _metadata and potentially self are shared with all forks. */ \
|
child = fork(); \
|
||||||
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; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
if (child == 0) { \
|
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); \
|
_metadata->teardown_fn(false, _metadata, self, variant->data); \
|
||||||
_exit(0); \
|
_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); \
|
_metadata->teardown_fn(true, _metadata, self, variant->data); \
|
||||||
munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \
|
munmap(_metadata->no_teardown, sizeof(*_metadata->no_teardown)); \
|
||||||
@ -456,7 +449,6 @@
|
|||||||
/* Forward signal to __wait_for_test(). */ \
|
/* Forward signal to __wait_for_test(). */ \
|
||||||
kill(getpid(), WTERMSIG(status)); \
|
kill(getpid(), WTERMSIG(status)); \
|
||||||
} \
|
} \
|
||||||
__test_check_assert(_metadata); \
|
|
||||||
} \
|
} \
|
||||||
static void wrapper_##fixture_name##_##test_name##_teardown( \
|
static void wrapper_##fixture_name##_##test_name##_teardown( \
|
||||||
bool in_parent, struct __test_metadata *_metadata, \
|
bool in_parent, struct __test_metadata *_metadata, \
|
||||||
@ -927,7 +919,6 @@ struct __test_metadata {
|
|||||||
int timeout; /* seconds to wait for test timeout */
|
int timeout; /* seconds to wait for test timeout */
|
||||||
bool aborted; /* stopped test due to failed ASSERT */
|
bool aborted; /* stopped test due to failed ASSERT */
|
||||||
bool *no_teardown; /* fixture needs teardown */
|
bool *no_teardown; /* fixture needs teardown */
|
||||||
jmp_buf env; /* for exiting out of test early */
|
|
||||||
void *self;
|
void *self;
|
||||||
const void *variant;
|
const void *variant;
|
||||||
struct __test_results *results;
|
struct __test_results *results;
|
||||||
@ -963,19 +954,14 @@ static inline int __bail(int for_realz, struct __test_metadata *t)
|
|||||||
{
|
{
|
||||||
/* if this is ASSERT, return immediately. */
|
/* if this is ASSERT, return immediately. */
|
||||||
if (for_realz) {
|
if (for_realz) {
|
||||||
t->aborted = true;
|
if (t->teardown_fn)
|
||||||
longjmp(t->env, 1);
|
t->teardown_fn(false, t, t->self, t->variant);
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
/* otherwise, end the for loop and continue. */
|
/* otherwise, end the for loop and continue. */
|
||||||
return 0;
|
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)
|
static void __wait_for_test(struct __test_metadata *t)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -1208,7 +1194,6 @@ static void __run_test(struct __fixture_metadata *f,
|
|||||||
t->trigger = 0;
|
t->trigger = 0;
|
||||||
t->aborted = false;
|
t->aborted = false;
|
||||||
t->no_teardown = NULL;
|
t->no_teardown = NULL;
|
||||||
memset(t->env, 0, sizeof(t->env));
|
|
||||||
memset(t->results->reason, 0, sizeof(t->results->reason));
|
memset(t->results->reason, 0, sizeof(t->results->reason));
|
||||||
|
|
||||||
snprintf(test_name, sizeof(test_name), "%s%s%s.%s",
|
snprintf(test_name, sizeof(test_name), "%s%s%s.%s",
|
||||||
|
Loading…
Reference in New Issue
Block a user