Actually abort in panic-abort-tests

This commit is contained in:
Tyler Mandry 2024-01-24 15:57:43 -08:00
parent 0c1fb2a1e6
commit f622e832d4
6 changed files with 33 additions and 41 deletions

View File

@ -5332,6 +5332,7 @@ version = "0.0.0"
dependencies = [ dependencies = [
"core", "core",
"getopts", "getopts",
"libc",
"panic_abort", "panic_abort",
"panic_unwind", "panic_unwind",
"std", "std",

View File

@ -9,3 +9,4 @@ std = { path = "../std" }
core = { path = "../core" } core = { path = "../core" }
panic_unwind = { path = "../panic_unwind" } panic_unwind = { path = "../panic_unwind" }
panic_abort = { path = "../panic_abort" } panic_abort = { path = "../panic_abort" }
libc = { version = "0.2.150", default-features = false }

View File

@ -1,20 +0,0 @@
//! Helper module to detect subprocess exit code.
use std::process::ExitStatus;
#[cfg(not(unix))]
pub fn get_exit_code(status: ExitStatus) -> Result<i32, String> {
status.code().ok_or_else(|| "received no exit code from child process".into())
}
#[cfg(unix)]
pub fn get_exit_code(status: ExitStatus) -> Result<i32, String> {
use std::os::unix::process::ExitStatusExt;
match status.code() {
Some(code) => Ok(code),
None => match status.signal() {
Some(signal) => Err(format!("child process exited with signal {signal}")),
None => Err("child process exited with unknown signal".into()),
},
}
}

View File

@ -2,6 +2,5 @@
//! but used in `libtest`. //! but used in `libtest`.
pub mod concurrency; pub mod concurrency;
pub mod exit_code;
pub mod metrics; pub mod metrics;
pub mod shuffle; pub mod shuffle;

View File

@ -85,7 +85,6 @@ pub mod test {
use core::any::Any; use core::any::Any;
use event::{CompletedTest, TestEvent}; use event::{CompletedTest, TestEvent};
use helpers::concurrency::get_concurrency; use helpers::concurrency::get_concurrency;
use helpers::exit_code::get_exit_code;
use helpers::shuffle::{get_shuffle_seed, shuffle_tests}; use helpers::shuffle::{get_shuffle_seed, shuffle_tests};
use options::RunStrategy; use options::RunStrategy;
use test_result::*; use test_result::*;
@ -712,17 +711,7 @@ fn spawn_test_subprocess(
formatters::write_stderr_delimiter(&mut test_output, &desc.name); formatters::write_stderr_delimiter(&mut test_output, &desc.name);
test_output.extend_from_slice(&stderr); test_output.extend_from_slice(&stderr);
let result = match (|| -> Result<TestResult, String> { let result = get_result_from_exit_code(&desc, status, &time_opts, &exec_time);
let exit_code = get_exit_code(status)?;
Ok(get_result_from_exit_code(&desc, exit_code, &time_opts, &exec_time))
})() {
Ok(r) => r,
Err(e) => {
write!(&mut test_output, "Unexpected error: {e}").unwrap();
TrFailed
}
};
(result, test_output, exec_time) (result, test_output, exec_time)
})(); })();
@ -751,7 +740,7 @@ fn run_test_in_spawned_subprocess(desc: TestDesc, runnable_test: RunnableTest) -
if let TrOk = test_result { if let TrOk = test_result {
process::exit(test_result::TR_OK); process::exit(test_result::TR_OK);
} else { } else {
process::exit(test_result::TR_FAILED); process::abort();
} }
}); });
let record_result2 = record_result.clone(); let record_result2 = record_result.clone();

View File

@ -1,4 +1,8 @@
use std::any::Any; use std::any::Any;
use std::process::ExitStatus;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
use super::bench::BenchSamples; use super::bench::BenchSamples;
use super::options::ShouldPanic; use super::options::ShouldPanic;
@ -7,11 +11,15 @@
pub use self::TestResult::*; pub use self::TestResult::*;
// Return codes for secondary process. // Return code for secondary process.
// Start somewhere other than 0 so we know the return code means what we think // Start somewhere other than 0 so we know the return code means what we think
// it means. // it means.
pub const TR_OK: i32 = 50; pub const TR_OK: i32 = 50;
pub const TR_FAILED: i32 = 51;
// On Windows we use __fastfail to abort, which is documented to use this
// exception code.
#[cfg(windows)]
const STATUS_ABORTED: i32 = 0xC0000409u32 as i32;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub enum TestResult { pub enum TestResult {
@ -81,14 +89,28 @@ pub fn calc_result<'a>(
/// Creates a `TestResult` depending on the exit code of test subprocess. /// Creates a `TestResult` depending on the exit code of test subprocess.
pub fn get_result_from_exit_code( pub fn get_result_from_exit_code(
desc: &TestDesc, desc: &TestDesc,
code: i32, status: ExitStatus,
time_opts: &Option<time::TestTimeOptions>, time_opts: &Option<time::TestTimeOptions>,
exec_time: &Option<time::TestExecTime>, exec_time: &Option<time::TestExecTime>,
) -> TestResult { ) -> TestResult {
let result = match code { let result = match status.code() {
TR_OK => TestResult::TrOk, Some(TR_OK) => TestResult::TrOk,
TR_FAILED => TestResult::TrFailed, #[cfg(windows)]
_ => TestResult::TrFailedMsg(format!("got unexpected return code {code}")), Some(STATUS_ABORTED) => TestResult::TrFailed,
#[cfg(unix)]
None => match status.signal() {
Some(libc::SIGABRT) => TestResult::TrFailed,
Some(signal) => {
TestResult::TrFailedMsg(format!("child process exited with signal {signal}"))
}
None => unreachable!("status.code() returned None but status.signal() was None"),
},
#[cfg(not(unix))]
None => TestResult::TrFailedMsg(format!("unknown return code")),
#[cfg(any(windows, unix))]
Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")),
#[cfg(not(any(windows, unix)))]
Some(_) => TestResult::TrFailed,
}; };
// If test is already failed (or allowed to fail), do not change the result. // If test is already failed (or allowed to fail), do not change the result.