@@ -21,7 +21,6 @@ use prelude::v1::*;
2121use io:: prelude:: * ;
2222
2323use any:: Any ;
24- use cell:: Cell ;
2524use cell:: RefCell ;
2625use fmt;
2726use intrinsics;
@@ -39,8 +38,6 @@ thread_local! {
3938 }
4039}
4140
42- thread_local ! { pub static PANIC_COUNT : Cell <usize > = Cell :: new( 0 ) }
43-
4441// Binary interface to the panic runtime that the standard library depends on.
4542//
4643// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
@@ -187,7 +184,7 @@ fn default_hook(info: &PanicInfo) {
187184 // for this panic. Otherwise only print it if logging is enabled.
188185 #[ cfg( any( not( cargobuild) , feature = "backtrace" ) ) ]
189186 let log_backtrace = {
190- let panics = PANIC_COUNT . with ( |c| c . get ( ) ) ;
187+ let panics = update_panic_count ( 0 ) ;
191188
192189 panics >= 2 || backtrace:: log_enabled ( )
193190 } ;
@@ -238,14 +235,31 @@ fn default_hook(info: &PanicInfo) {
238235 }
239236}
240237
238+
239+ #[ cfg( not( test) ) ]
240+ #[ doc( hidden) ]
241+ #[ unstable( feature = "update_panic_count" , issue = "0" ) ]
242+ pub fn update_panic_count ( amt : isize ) -> usize {
243+ use cell:: Cell ;
244+ thread_local ! { static PANIC_COUNT : Cell <usize > = Cell :: new( 0 ) }
245+
246+ PANIC_COUNT . with ( |c| {
247+ let next = ( c. get ( ) as isize + amt) as usize ;
248+ c. set ( next) ;
249+ return next
250+ } )
251+ }
252+
253+ #[ cfg( test) ]
254+ pub use realstd:: rt:: update_panic_count;
255+
241256/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
242257pub unsafe fn try < R , F : FnOnce ( ) -> R > ( f : F ) -> Result < R , Box < Any + Send > > {
243258 let mut slot = None ;
244259 let mut f = Some ( f) ;
245- let ret = PANIC_COUNT . with ( |s| {
246- let prev = s. get ( ) ;
247- s. set ( 0 ) ;
260+ let ret;
248261
262+ {
249263 let mut to_run = || {
250264 slot = Some ( f. take ( ) . unwrap ( ) ( ) ) ;
251265 } ;
@@ -258,18 +272,18 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
258272 dataptr,
259273 & mut any_data,
260274 & mut any_vtable) ;
261- s. set ( prev) ;
262-
263275 if r == 0 {
264- Ok ( ( ) )
276+ ret = Ok ( ( ) ) ;
265277 } else {
266- Err ( mem:: transmute ( raw:: TraitObject {
278+ update_panic_count ( -1 ) ;
279+ ret = Err ( mem:: transmute ( raw:: TraitObject {
267280 data : any_data as * mut _ ,
268281 vtable : any_vtable as * mut _ ,
269- } ) )
282+ } ) ) ;
270283 }
271- } ) ;
284+ }
272285
286+ debug_assert ! ( update_panic_count( 0 ) == 0 ) ;
273287 return ret. map ( |( ) | {
274288 slot. take ( ) . unwrap ( )
275289 } ) ;
@@ -285,7 +299,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
285299
286300/// Determines whether the current thread is unwinding because of panic.
287301pub fn panicking ( ) -> bool {
288- PANIC_COUNT . with ( |c| c . get ( ) != 0 )
302+ update_panic_count ( 0 ) != 0
289303}
290304
291305/// Entry point of panic from the libcore crate.
@@ -350,18 +364,14 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
350364 file_line : & ( & ' static str , u32 ) ) -> ! {
351365 let ( file, line) = * file_line;
352366
353- let panics = PANIC_COUNT . with ( |c| {
354- let prev = c. get ( ) ;
355- c. set ( prev + 1 ) ;
356- prev
357- } ) ;
367+ let panics = update_panic_count ( 1 ) ;
358368
359369 // If this is the third nested call (e.g. panics == 2, this is 0-indexed),
360370 // the panic hook probably triggered the last panic, otherwise the
361371 // double-panic check would have aborted the process. In this case abort the
362372 // process real quickly as we don't want to try calling it again as it'll
363373 // probably just panic again.
364- if panics > 1 {
374+ if panics > 2 {
365375 util:: dumb_print ( format_args ! ( "thread panicked while processing \
366376 panic. aborting.\n ") ) ;
367377 unsafe { intrinsics:: abort ( ) }
@@ -383,7 +393,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
383393 HOOK_LOCK . read_unlock ( ) ;
384394 }
385395
386- if panics > 0 {
396+ if panics > 1 {
387397 // If a thread panics while it's already unwinding then we
388398 // have limited options. Currently our preference is to
389399 // just abort. In the future we may consider resuming
@@ -396,6 +406,12 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
396406 rust_panic ( msg)
397407}
398408
409+ /// Shim around rust_panic. Called by resume_unwind.
410+ pub fn update_count_then_panic ( msg : Box < Any + Send > ) -> ! {
411+ update_panic_count ( 1 ) ;
412+ rust_panic ( msg)
413+ }
414+
399415/// A private no-mangle function on which to slap yer breakpoints.
400416#[ no_mangle]
401417#[ allow( private_no_mangle_fns) ] // yes we get it, but we like breakpoints
0 commit comments