aboutsummaryrefslogtreecommitdiff
path: root/vendor/backtrace/tests/concurrent-panics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/backtrace/tests/concurrent-panics.rs')
-rw-r--r--vendor/backtrace/tests/concurrent-panics.rs72
1 files changed, 72 insertions, 0 deletions
diff --git a/vendor/backtrace/tests/concurrent-panics.rs b/vendor/backtrace/tests/concurrent-panics.rs
new file mode 100644
index 0000000..a44a267
--- /dev/null
+++ b/vendor/backtrace/tests/concurrent-panics.rs
@@ -0,0 +1,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 || {
+ while !done2.load(SeqCst) {
+ 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();
+}