diff options
| author | Andrea Canciani <ranma42@gmail.com> | 2015-09-24 23:49:38 +0200 |
|---|---|---|
| committer | Andrea Canciani <ranma42@gmail.com> | 2015-09-24 23:49:38 +0200 |
| commit | c7b84909b00dcf5f762778b4aa9783770c69416d (patch) | |
| tree | 0a437b3fff3d718e04267f2523266fcf039d1432 /src/libstd/panicking.rs | |
| parent | 44d1b149d2831192503a7797b98f108a3b5b1032 (diff) | |
| download | rust-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.rs | 24 |
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() } + } } |
