1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
use std::env;
use std::panic;
use std::process::Command;
use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
use std::sync::Arc;
use std::thread;
const PANICS: usize = 100;
const THREADS: usize = 8;
const VAR: &str = "__THE_TEST_YOU_ARE_LUKE";
mod common;
fn main() {
// If we cannot re-exec this test, there's no point in trying to do it.
if common::cannot_reexec_the_test() {
println!("test result: ok");
return;
}
if env::var(VAR).is_err() {
parent();
} else {
child();
}
}
fn parent() {
let me = env::current_exe().unwrap();
let result = Command::new(&me)
.env("RUST_BACKTRACE", "1")
.env(VAR, "1")
.output()
.unwrap();
if result.status.success() {
println!("test result: ok");
return;
}
println!("stdout:\n{}", String::from_utf8_lossy(&result.stdout));
println!("stderr:\n{}", String::from_utf8_lossy(&result.stderr));
println!("code: {}", result.status);
panic!();
}
fn child() {
let done = Arc::new(AtomicBool::new(false));
let done2 = done.clone();
let a = thread::spawn(move || loop {
if done2.load(SeqCst) {
break format!("{:?}", backtrace::Backtrace::new());
}
});
let threads = (0..THREADS)
.map(|_| {
thread::spawn(|| {
for _ in 0..PANICS {
assert!(panic::catch_unwind(|| {
panic!();
})
.is_err());
}
})
})
.collect::<Vec<_>>();
for thread in threads {
thread.join().unwrap();
}
done.store(true, SeqCst);
a.join().unwrap();
}
|