Skip to content

Commit c7b8490

Browse files
committed
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.
1 parent 44d1b14 commit c7b8490

File tree

2 files changed

+26
-20
lines changed

2 files changed

+26
-20
lines changed

src/libstd/panicking.rs

+22-2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@ use prelude::v1::*;
1212
use io::prelude::*;
1313

1414
use any::Any;
15+
use cell::Cell;
1516
use cell::RefCell;
17+
use intrinsics;
1618
use sys::stdio::Stderr;
1719
use sys_common::backtrace;
1820
use sys_common::thread_info;
19-
use sys_common::unwind;
21+
use sys_common::util;
22+
23+
thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
2024

2125
thread_local! {
2226
pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
@@ -61,8 +65,24 @@ fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
6165
}
6266

6367
pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
68+
let panics = PANIC_COUNT.with(|s| {
69+
let count = s.get() + 1;
70+
s.set(count);
71+
count
72+
});
73+
6474
// If this is a double panic, make sure that we print a backtrace
6575
// for this panic. Otherwise only print it if logging is enabled.
66-
let log_backtrace = unwind::panicking() || backtrace::log_enabled();
76+
let log_backtrace = panics >= 2 || backtrace::log_enabled();
6777
log_panic(obj, file, line, log_backtrace);
78+
79+
if panics >= 2 {
80+
// If a thread panics while it's already unwinding then we
81+
// have limited options. Currently our preference is to
82+
// just abort. In the future we may consider resuming
83+
// unwinding or otherwise exiting the thread cleanly.
84+
util::dumb_print(format_args!("thread panicked while panicking. \
85+
aborting."));
86+
unsafe { intrinsics::abort() }
87+
}
6888
}

src/libstd/sys/common/unwind/mod.rs

+4-18
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,8 @@ use prelude::v1::*;
6464

6565
use any::Any;
6666
use boxed;
67-
use cell::Cell;
6867
use cmp;
69-
use panicking;
68+
use panicking::{self,PANIC_COUNT};
7069
use fmt;
7170
use intrinsics;
7271
use mem;
@@ -92,8 +91,6 @@ pub mod imp;
9291
#[path = "gcc.rs"] #[doc(hidden)]
9392
pub mod imp;
9493

95-
thread_local! { static PANICKING: Cell<bool> = Cell::new(false) }
96-
9794
/// Invoke a closure, capturing the cause of panic if one occurs.
9895
///
9996
/// This function will return `Ok(())` if the closure did not panic, and will
@@ -131,9 +128,9 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
131128
// care of exposing correctly.
132129
unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
133130
-> Result<(), Box<Any + Send>> {
134-
PANICKING.with(|s| {
131+
PANIC_COUNT.with(|s| {
135132
let prev = s.get();
136-
s.set(false);
133+
s.set(0);
137134
let ep = intrinsics::try(f, data);
138135
s.set(prev);
139136
if ep.is_null() {
@@ -161,7 +158,7 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
161158

162159
/// Determines whether the current thread is unwinding because of panic.
163160
pub fn panicking() -> bool {
164-
PANICKING.with(|s| s.get())
161+
PANIC_COUNT.with(|s| s.get() != 0)
165162
}
166163

167164
// An uninlined, unmangled function upon which to slap yer breakpoints
@@ -234,17 +231,6 @@ fn begin_unwind_inner(msg: Box<Any + Send>,
234231
// First, invoke the default panic handler.
235232
panicking::on_panic(&*msg, file, line);
236233

237-
if panicking() {
238-
// If a thread panics while it's already unwinding then we
239-
// have limited options. Currently our preference is to
240-
// just abort. In the future we may consider resuming
241-
// unwinding or otherwise exiting the thread cleanly.
242-
super::util::dumb_print(format_args!("thread panicked while panicking. \
243-
aborting."));
244-
unsafe { intrinsics::abort() }
245-
}
246-
PANICKING.with(|s| s.set(true));
247-
248234
// Finally, perform the unwinding.
249235
rust_panic(msg);
250236
}

0 commit comments

Comments
 (0)