tests: ASSERT_SIGNAL: Ensure sanitisers do not mask expected signals

ASAN installs signal handlers to catch crashes like SIGSEGV or SIGILL.
When these signals are raised, ASAN traps them, prints an error report,
and then typically terminates the process with a different signal (often
SIGABRT) or a non-zero exit code.

This interferes with ASSERT_SIGNAL when checking for specific crash
signals (for example, checking that a function raises SIGSEGV). In such
a case, the test harness sees the ASAN termination signal rather than
the expected signal, causing the test to fail.

Fix this by resetting the signal handler to SIG_DFL in the child process
immediately before executing the test expression. This ensures the
kernel kills the process directly with the expected signal, bypassing
ASAN's interceptors.
This commit is contained in:
Chris Down
2025-11-19 21:45:40 +08:00
parent 39adecfcd8
commit d759ed527c

View File

@@ -598,18 +598,19 @@ int assert_signal_internal(void);
# define ASSERT_SIGNAL(expr, signal) __coverity_check__(((expr), false))
#else
# define ASSERT_SIGNAL(expr, signal) __ASSERT_SIGNAL(UNIQ, expr, signal)
# define __ASSERT_SIGNAL(uniq, expr, signal) \
# define __ASSERT_SIGNAL(uniq, expr, sgnl) \
({ \
ASSERT_TRUE(SIGNAL_VALID(signal)); \
ASSERT_TRUE(SIGNAL_VALID(sgnl)); \
int UNIQ_T(_r, uniq) = assert_signal_internal(); \
ASSERT_OK_ERRNO(UNIQ_T(_r, uniq)); \
if (UNIQ_T(_r, uniq) == 0) { \
(void) signal(sgnl, SIG_DFL); \
expr; \
_exit(EXIT_SUCCESS); \
} \
if (UNIQ_T(_r, uniq) != signal) \
if (UNIQ_T(_r, uniq) != sgnl) \
log_test_failed("\"%s\" died with signal %s, but %s was expected", \
#expr, signal_to_string(UNIQ_T(_r, uniq)), signal_to_string(signal)); \
#expr, signal_to_string(UNIQ_T(_r, uniq)), signal_to_string(sgnl)); \
})
#endif