Fix panic=abort tests on fuchsia by c6c7 · Pull Request #127595 · rust-lang/rust (original) (raw)
The longer story with citations....
There are cases in this repository that attempt to detect whether a process aborted or not. The first is in fn get_result_from_exit_code(..., status: ExitStatus, ...) -> TestResult
(defined in test::test_result
) which returns whether a test failed based on an ExitStatus
. If a platform implements libc::abort
abort as defined in ISO C, a panic in a test will result in calling libc::abort
which will call libc::raise(SIGABRT)
. Thus, get_result_from_exit_code
will return a test failed when ExitStatus::signal
returns Some(SIGABRT)
. The story does not end here though because Fuchsia and Windows don't support signals, and thus ExitStatus::signal
always returns None
on those platforms.
(For Windows, it's apparently sufficient to check for STATUS_FAIL_FAST_EXCEPTION
, but I don't know the details beyond the existing comments in test::test_result
)
For Fuchsia, libc::abort
does not call libc::raise(SIGABRT)
because Fuchsia in this case deviates from the ISO C definition of libc::abort
. Instead, Fuchsia executes the LLVM intrinsic __builtin_trap()
1 which generally raises an Zircon kernel exception. Unless the process installed an exception handler, the exception will go uncaught, and the kernel will kill the process with the code ZX_TASK_RETCODE_EXCEPTION_KILL
. Thus, for get_result_from_exit_code
, the best we can do to check if a process aborted is to observe the return code ZX_TASK_RETCODE_EXCEPTION_KILL
.
The second case is tests/ui/process/signal-exit-status.rs
which tests whether a process aborted as expected upon calling core::intrinsics::abort()
. The goal is very similar to get_result_from_exit_code
, but the result is not a TestResult
. For Fuchsia, the hindrance for writing this test is not knowing what the return code from the process should be. My first thought was, "Oh, we should just implement ExitStatus::aborted_code(&self) -> Option<i32>
." But this is fraught because of there is no return code in Fuchsia that is set if and only if a process aborted. The closest approximation to detecting if a process aborted is to check if the process returned ZX_TASK_RETCODE_EXCEPTION_KILL
.
Taking a step back though, it's not actually the primary goal of signal-exit-status
to determine that the process returned ZX_TASK_RETCODE_EXCEPTION_KILL
and no other possible uncaught exception was raised. There is some potential for a test flake where the Zircon kernel during the signal-exit-status
test raises an exception for a reason other than the abort()
call; this seems very unlikely though. Thus, it's sufficient for signal-exit-status
to merely check for ZX_TASK_RETCODE_EXCEPTION_KILL
.