Skip to content

Commit

Permalink
Added an update_panic_count function to handle access to PANIC_COUNT
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilshagri committed Aug 10, 2016
1 parent 00b1e88 commit ea2216c
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/libstd/lib.rs
Expand Up @@ -278,6 +278,7 @@
#![feature(unwind_attributes)]
#![feature(vec_push_all)]
#![feature(zero_one)]
#![cfg_attr(test, feature(update_panic_count))]

// Issue# 30592: Systematically use alloc_system during stage0 since jemalloc
// might be unavailable or disabled
Expand Down
48 changes: 26 additions & 22 deletions src/libstd/panicking.rs
Expand Up @@ -21,7 +21,6 @@ use prelude::v1::*;
use io::prelude::*;

use any::Any;
use cell::Cell;
use cell::RefCell;
use fmt;
use intrinsics;
Expand All @@ -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.
//
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
Expand Down Expand Up @@ -187,7 +184,7 @@ fn default_hook(info: &PanicInfo) {
// for this panic. Otherwise only print it if logging is enabled.
#[cfg(any(not(cargobuild), feature = "backtrace"))]
let log_backtrace = {
let panics = PANIC_COUNT.with(|c| c.get());
let panics = update_panic_count(0);

panics >= 2 || backtrace::log_enabled()
};
Expand Down Expand Up @@ -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.
pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
let mut slot = None;
Expand All @@ -260,18 +275,15 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
if r == 0 {
ret = Ok(());
} else {
PANIC_COUNT.with(|s| {
let prev = s.get();
s.set(prev - 1);
});
update_panic_count(-1);
ret = Err(mem::transmute(raw::TraitObject {
data: any_data as *mut _,
vtable: any_vtable as *mut _,
}));
}
}

debug_assert!(PANIC_COUNT.with(|c| c.get() == 0));
debug_assert!(update_panic_count(0) == 0);
return ret.map(|()| {
slot.take().unwrap()
});
Expand All @@ -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.
pub fn panicking() -> bool {
PANIC_COUNT.with(|c| c.get() != 0)
update_panic_count(0) != 0
}

/// Entry point of panic from the libcore crate.
Expand Down Expand Up @@ -352,18 +364,14 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
file_line: &(&'static str, u32)) -> ! {
let (file, line) = *file_line;

let panics = PANIC_COUNT.with(|c| {
let prev = c.get();
c.set(prev + 1);
prev
});
let panics = update_panic_count(1);

// 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
// 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
// probably just panic again.
if panics > 1 {
if panics > 2 {
util::dumb_print(format_args!("thread panicked while processing \
panic. aborting.\n"));
unsafe { intrinsics::abort() }
Expand All @@ -385,7 +393,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
HOOK_LOCK.read_unlock();
}

if panics > 0 {
if panics > 1 {
// 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
Expand All @@ -400,11 +408,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,

/// Shim around rust_panic. Called by resume_unwind.
pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
PANIC_COUNT.with(|c| {
let prev = c.get();
c.set(prev + 1);
});

update_panic_count(1);
rust_panic(msg)
}

Expand Down
2 changes: 1 addition & 1 deletion src/libstd/rt.rs
Expand Up @@ -25,7 +25,7 @@


// 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))]
#[lang = "start"]
Expand Down

0 comments on commit ea2216c

Please sign in to comment.