]> git.proxmox.com Git - rustc.git/blob - library/backtrace/tests/concurrent-panics.rs
New upstream version 1.49.0~beta.4+dfsg1
[rustc.git] / library / backtrace / tests / concurrent-panics.rs
1 use std::env;
2 use std::panic;
3 use std::process::Command;
4 use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
5 use std::sync::Arc;
6 use std::thread;
7
8 const PANICS: usize = 100;
9 const THREADS: usize = 8;
10 const VAR: &str = "__THE_TEST_YOU_ARE_LUKE";
11
12 fn main() {
13 // These run in docker containers on CI where they can't re-exec the test,
14 // so just skip these for CI. No other reason this can't run on those
15 // platforms though.
16 // Miri does not have support for re-execing a file
17 if cfg!(unix) && (cfg!(target_arch = "arm") || cfg!(target_arch = "aarch64")) || cfg!(miri) {
18 println!("test result: ok");
19 return;
20 }
21
22 if env::var(VAR).is_err() {
23 parent();
24 } else {
25 child();
26 }
27 }
28
29 fn parent() {
30 let me = env::current_exe().unwrap();
31 let result = Command::new(&me)
32 .env("RUST_BACKTRACE", "1")
33 .env(VAR, "1")
34 .output()
35 .unwrap();
36 if result.status.success() {
37 println!("test result: ok");
38 return;
39 }
40 println!("stdout:\n{}", String::from_utf8_lossy(&result.stdout));
41 println!("stderr:\n{}", String::from_utf8_lossy(&result.stderr));
42 println!("code: {}", result.status);
43 panic!();
44 }
45
46 fn child() {
47 let done = Arc::new(AtomicBool::new(false));
48 let done2 = done.clone();
49 let a = thread::spawn(move || {
50 while !done2.load(SeqCst) {
51 format!("{:?}", backtrace::Backtrace::new());
52 }
53 });
54
55 let threads = (0..THREADS)
56 .map(|_| {
57 thread::spawn(|| {
58 for _ in 0..PANICS {
59 assert!(panic::catch_unwind(|| {
60 panic!();
61 })
62 .is_err());
63 }
64 })
65 })
66 .collect::<Vec<_>>();
67 for thread in threads {
68 thread.join().unwrap();
69 }
70
71 done.store(true, SeqCst);
72 a.join().unwrap();
73 }