fix: scope panic suppression to individual jobs and threads

This commit is contained in:
Momoko-Ayase committed 2026-11-04 12:34:41 +08:00
1 parent db2729737f
commit 312a70b7c6
5 files changed
+273 -143

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Barrier};
#[test]
fn folder_runs_preserve_the_host_panic_hook() {
const CHILD: &str = "SENBEI_PANIC_HOOK_TEST_CHILD";
if std::env::var_os(CHILD).is_none() {
let output = std::process::Command::new(std::env::current_exe().unwrap())
.args([
"--exact",
"folder_runs_preserve_the_host_panic_hook",
"--nocapture",
])
.env(CHILD, "1")
.output()
.unwrap();
assert!(
output.status.success(),
"child failed: {}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
return;
}
static CALLS: AtomicUsize = AtomicUsize::new(0);
std::panic::set_hook(Box::new(|_| {
CALLS.fetch_add(1, Ordering::SeqCst);
}));
let root = tempfile::tempdir().unwrap();
// Exercise repeated job lifetimes both before and after engine capture.
for _ in 0..2 {
senbei_io::job::run_folder_opts(root.path(), None, 2, false, true, false).unwrap();
assert!(senbei_engine::catch_unwind_quiet(|| panic!("captured")).is_err());
assert!(std::panic::catch_unwind(|| panic!("host")).is_err());
}
assert_eq!(CALLS.load(Ordering::SeqCst), 2);
let barrier = Arc::new(Barrier::new(2));
let worker_barrier = barrier.clone();
let worker = std::thread::spawn(move || {
senbei_engine::catch_unwind_quiet(|| {
worker_barrier.wait();
worker_barrier.wait();
panic!("captured in another thread");
})
.unwrap_err();
});
barrier.wait();
// A quiet capture in another thread must not silence unrelated panics.
assert!(std::panic::catch_unwind(|| panic!("unrelated host panic")).is_err());
barrier.wait();
worker.join().unwrap();
assert_eq!(CALLS.load(Ordering::SeqCst), 3);
std::thread::scope(|scope| {
for _ in 0..4 {
let path = root.path();
scope.spawn(move || {
senbei_io::job::run_folder_opts(path, None, 2, false, true, false).unwrap();
assert!(
senbei_engine::catch_unwind_quiet(|| panic!("after concurrent job")).is_err()
);
});
}
});
assert_eq!(CALLS.load(Ordering::SeqCst), 3);
}