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.