Added an update_panic_count function to handle access to PANIC_COUNT
This commit is contained in:
parent
00b1e88680
commit
ea2216cba8
@ -278,6 +278,7 @@
|
|||||||
#![feature(unwind_attributes)]
|
#![feature(unwind_attributes)]
|
||||||
#![feature(vec_push_all)]
|
#![feature(vec_push_all)]
|
||||||
#![feature(zero_one)]
|
#![feature(zero_one)]
|
||||||
|
#![cfg_attr(test, feature(update_panic_count))]
|
||||||
|
|
||||||
// Issue# 30592: Systematically use alloc_system during stage0 since jemalloc
|
// Issue# 30592: Systematically use alloc_system during stage0 since jemalloc
|
||||||
// might be unavailable or disabled
|
// might be unavailable or disabled
|
||||||
|
@ -21,7 +21,6 @@ use prelude::v1::*;
|
|||||||
use io::prelude::*;
|
use io::prelude::*;
|
||||||
|
|
||||||
use any::Any;
|
use any::Any;
|
||||||
use cell::Cell;
|
|
||||||
use cell::RefCell;
|
use cell::RefCell;
|
||||||
use fmt;
|
use fmt;
|
||||||
use intrinsics;
|
use intrinsics;
|
||||||
@ -39,8 +38,6 @@ thread_local! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
|
|
||||||
|
|
||||||
// Binary interface to the panic runtime that the standard library depends on.
|
// Binary interface to the panic runtime that the standard library depends on.
|
||||||
//
|
//
|
||||||
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
|
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
|
||||||
@ -187,7 +184,7 @@ fn default_hook(info: &PanicInfo) {
|
|||||||
// for this panic. Otherwise only print it if logging is enabled.
|
// for this panic. Otherwise only print it if logging is enabled.
|
||||||
#[cfg(any(not(cargobuild), feature = "backtrace"))]
|
#[cfg(any(not(cargobuild), feature = "backtrace"))]
|
||||||
let log_backtrace = {
|
let log_backtrace = {
|
||||||
let panics = PANIC_COUNT.with(|c| c.get());
|
let panics = update_panic_count(0);
|
||||||
|
|
||||||
panics >= 2 || backtrace::log_enabled()
|
panics >= 2 || backtrace::log_enabled()
|
||||||
};
|
};
|
||||||
@ -238,6 +235,24 @@ fn default_hook(info: &PanicInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[unstable(feature = "update_panic_count", issue = "0")]
|
||||||
|
pub fn update_panic_count(amt: isize) -> usize {
|
||||||
|
use cell::Cell;
|
||||||
|
thread_local! { static PANIC_COUNT: Cell<usize> = Cell::new(0) }
|
||||||
|
|
||||||
|
PANIC_COUNT.with(|c| {
|
||||||
|
let next = (c.get() as isize + amt) as usize;
|
||||||
|
c.set(next);
|
||||||
|
return next
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub use realstd::rt::update_panic_count;
|
||||||
|
|
||||||
/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
|
/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
|
||||||
pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
|
pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
|
||||||
let mut slot = None;
|
let mut slot = None;
|
||||||
@ -260,10 +275,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
|
|||||||
if r == 0 {
|
if r == 0 {
|
||||||
ret = Ok(());
|
ret = Ok(());
|
||||||
} else {
|
} else {
|
||||||
PANIC_COUNT.with(|s| {
|
update_panic_count(-1);
|
||||||
let prev = s.get();
|
|
||||||
s.set(prev - 1);
|
|
||||||
});
|
|
||||||
ret = Err(mem::transmute(raw::TraitObject {
|
ret = Err(mem::transmute(raw::TraitObject {
|
||||||
data: any_data as *mut _,
|
data: any_data as *mut _,
|
||||||
vtable: any_vtable as *mut _,
|
vtable: any_vtable as *mut _,
|
||||||
@ -271,7 +283,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert!(PANIC_COUNT.with(|c| c.get() == 0));
|
debug_assert!(update_panic_count(0) == 0);
|
||||||
return ret.map(|()| {
|
return ret.map(|()| {
|
||||||
slot.take().unwrap()
|
slot.take().unwrap()
|
||||||
});
|
});
|
||||||
@ -287,7 +299,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
|
|||||||
|
|
||||||
/// Determines whether the current thread is unwinding because of panic.
|
/// Determines whether the current thread is unwinding because of panic.
|
||||||
pub fn panicking() -> bool {
|
pub fn panicking() -> bool {
|
||||||
PANIC_COUNT.with(|c| c.get() != 0)
|
update_panic_count(0) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Entry point of panic from the libcore crate.
|
/// Entry point of panic from the libcore crate.
|
||||||
@ -352,18 +364,14 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
|
|||||||
file_line: &(&'static str, u32)) -> ! {
|
file_line: &(&'static str, u32)) -> ! {
|
||||||
let (file, line) = *file_line;
|
let (file, line) = *file_line;
|
||||||
|
|
||||||
let panics = PANIC_COUNT.with(|c| {
|
let panics = update_panic_count(1);
|
||||||
let prev = c.get();
|
|
||||||
c.set(prev + 1);
|
|
||||||
prev
|
|
||||||
});
|
|
||||||
|
|
||||||
// If this is the third nested call (e.g. panics == 2, this is 0-indexed),
|
// If this is the third nested call (e.g. panics == 2, this is 0-indexed),
|
||||||
// the panic hook probably triggered the last panic, otherwise the
|
// the panic hook probably triggered the last panic, otherwise the
|
||||||
// double-panic check would have aborted the process. In this case abort the
|
// double-panic check would have aborted the process. In this case abort the
|
||||||
// process real quickly as we don't want to try calling it again as it'll
|
// process real quickly as we don't want to try calling it again as it'll
|
||||||
// probably just panic again.
|
// probably just panic again.
|
||||||
if panics > 1 {
|
if panics > 2 {
|
||||||
util::dumb_print(format_args!("thread panicked while processing \
|
util::dumb_print(format_args!("thread panicked while processing \
|
||||||
panic. aborting.\n"));
|
panic. aborting.\n"));
|
||||||
unsafe { intrinsics::abort() }
|
unsafe { intrinsics::abort() }
|
||||||
@ -385,7 +393,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
|
|||||||
HOOK_LOCK.read_unlock();
|
HOOK_LOCK.read_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if panics > 0 {
|
if panics > 1 {
|
||||||
// If a thread panics while it's already unwinding then we
|
// If a thread panics while it's already unwinding then we
|
||||||
// have limited options. Currently our preference is to
|
// have limited options. Currently our preference is to
|
||||||
// just abort. In the future we may consider resuming
|
// just abort. In the future we may consider resuming
|
||||||
@ -400,11 +408,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
|
|||||||
|
|
||||||
/// Shim around rust_panic. Called by resume_unwind.
|
/// Shim around rust_panic. Called by resume_unwind.
|
||||||
pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
|
pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
|
||||||
PANIC_COUNT.with(|c| {
|
update_panic_count(1);
|
||||||
let prev = c.get();
|
|
||||||
c.set(prev + 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
rust_panic(msg)
|
rust_panic(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
|
|
||||||
// Reexport some of our utilities which are expected by other crates.
|
// Reexport some of our utilities which are expected by other crates.
|
||||||
pub use panicking::{begin_panic, begin_panic_fmt};
|
pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count};
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
#[lang = "start"]
|
#[lang = "start"]
|
||||||
|
Loading…
Reference in New Issue
Block a user