about summary refs log tree commit diff
path: root/src/libstd/panicking.rs
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2015-09-24 23:49:38 +0200
committerAndrea Canciani <ranma42@gmail.com>2015-09-24 23:49:38 +0200
commitc7b84909b00dcf5f762778b4aa9783770c69416d (patch)
tree0a437b3fff3d718e04267f2523266fcf039d1432 /src/libstd/panicking.rs
parent44d1b149d2831192503a7797b98f108a3b5b1032 (diff)
downloadrust-c7b84909b00dcf5f762778b4aa9783770c69416d.tar.gz
rust-c7b84909b00dcf5f762778b4aa9783770c69416d.zip
Explicitly count the number of panics
Move the panic handling logic from the `unwind` module to `panicking`
and use a panic counter to distinguish between normal state, panics
and double panics.
Diffstat (limited to 'src/libstd/panicking.rs')
-rw-r--r--src/libstd/panicking.rs24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 01a3900f24f..fc242dee99f 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -12,11 +12,15 @@ use prelude::v1::*;
 use io::prelude::*;
 
 use any::Any;
+use cell::Cell;
 use cell::RefCell;
+use intrinsics;
 use sys::stdio::Stderr;
 use sys_common::backtrace;
 use sys_common::thread_info;
-use sys_common::unwind;
+use sys_common::util;
+
+thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
 
 thread_local! {
     pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
@@ -61,8 +65,24 @@ fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
 }
 
 pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
+    let panics = PANIC_COUNT.with(|s| {
+        let count = s.get() + 1;
+        s.set(count);
+        count
+    });
+
     // If this is a double panic, make sure that we print a backtrace
     // for this panic. Otherwise only print it if logging is enabled.
-    let log_backtrace = unwind::panicking() || backtrace::log_enabled();
+    let log_backtrace = panics >= 2 || backtrace::log_enabled();
     log_panic(obj, file, line, log_backtrace);
+
+    if panics >= 2 {
+        // If a thread panics while it's already unwinding then we
+        // have limited options. Currently our preference is to
+        // just abort. In the future we may consider resuming
+        // unwinding or otherwise exiting the thread cleanly.
+        util::dumb_print(format_args!("thread panicked while panicking. \
+                                       aborting."));
+        unsafe { intrinsics::abort() }
+    }
 }