@@ -21,7 +21,6 @@ use prelude::v1::*;
21
21
use io:: prelude:: * ;
22
22
23
23
use any:: Any ;
24
- use cell:: Cell ;
25
24
use cell:: RefCell ;
26
25
use fmt;
27
26
use intrinsics;
@@ -39,8 +38,6 @@ thread_local! {
39
38
}
40
39
}
41
40
42
- thread_local ! { pub static PANIC_COUNT : Cell <usize > = Cell :: new( 0 ) }
43
-
44
41
// Binary interface to the panic runtime that the standard library depends on.
45
42
//
46
43
// The standard library is tagged with `#![needs_panic_runtime]` (introduced in
@@ -187,7 +184,7 @@ fn default_hook(info: &PanicInfo) {
187
184
// for this panic. Otherwise only print it if logging is enabled.
188
185
#[ cfg( any( not( cargobuild) , feature = "backtrace" ) ) ]
189
186
let log_backtrace = {
190
- let panics = PANIC_COUNT . with ( |c| c . get ( ) ) ;
187
+ let panics = update_panic_count ( 0 ) ;
191
188
192
189
panics >= 2 || backtrace:: log_enabled ( )
193
190
} ;
@@ -238,6 +235,24 @@ fn default_hook(info: &PanicInfo) {
238
235
}
239
236
}
240
237
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
+
241
256
/// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
242
257
pub unsafe fn try < R , F : FnOnce ( ) -> R > ( f : F ) -> Result < R , Box < Any + Send > > {
243
258
let mut slot = None ;
@@ -260,18 +275,15 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
260
275
if r == 0 {
261
276
ret = Ok ( ( ) ) ;
262
277
} else {
263
- PANIC_COUNT . with ( |s| {
264
- let prev = s. get ( ) ;
265
- s. set ( prev - 1 ) ;
266
- } ) ;
278
+ update_panic_count ( -1 ) ;
267
279
ret = Err ( mem:: transmute ( raw:: TraitObject {
268
280
data : any_data as * mut _ ,
269
281
vtable : any_vtable as * mut _ ,
270
282
} ) ) ;
271
283
}
272
284
}
273
285
274
- debug_assert ! ( PANIC_COUNT . with ( |c| c . get ( ) == 0 ) ) ;
286
+ debug_assert ! ( update_panic_count ( 0 ) == 0 ) ;
275
287
return ret. map ( |( ) | {
276
288
slot. take ( ) . unwrap ( )
277
289
} ) ;
@@ -287,7 +299,7 @@ pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
287
299
288
300
/// Determines whether the current thread is unwinding because of panic.
289
301
pub fn panicking ( ) -> bool {
290
- PANIC_COUNT . with ( |c| c . get ( ) != 0 )
302
+ update_panic_count ( 0 ) != 0
291
303
}
292
304
293
305
/// Entry point of panic from the libcore crate.
@@ -352,18 +364,14 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
352
364
file_line : & ( & ' static str , u32 ) ) -> ! {
353
365
let ( file, line) = * file_line;
354
366
355
- let panics = PANIC_COUNT . with ( |c| {
356
- let prev = c. get ( ) ;
357
- c. set ( prev + 1 ) ;
358
- prev
359
- } ) ;
367
+ let panics = update_panic_count ( 1 ) ;
360
368
361
369
// If this is the third nested call (e.g. panics == 2, this is 0-indexed),
362
370
// the panic hook probably triggered the last panic, otherwise the
363
371
// double-panic check would have aborted the process. In this case abort the
364
372
// process real quickly as we don't want to try calling it again as it'll
365
373
// probably just panic again.
366
- if panics > 1 {
374
+ if panics > 2 {
367
375
util:: dumb_print ( format_args ! ( "thread panicked while processing \
368
376
panic. aborting.\n ") ) ;
369
377
unsafe { intrinsics:: abort ( ) }
@@ -385,7 +393,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
385
393
HOOK_LOCK . read_unlock ( ) ;
386
394
}
387
395
388
- if panics > 0 {
396
+ if panics > 1 {
389
397
// If a thread panics while it's already unwinding then we
390
398
// have limited options. Currently our preference is to
391
399
// just abort. In the future we may consider resuming
@@ -400,11 +408,7 @@ fn rust_panic_with_hook(msg: Box<Any + Send>,
400
408
401
409
/// Shim around rust_panic. Called by resume_unwind.
402
410
pub fn update_count_then_panic ( msg : Box < Any + Send > ) -> ! {
403
- PANIC_COUNT . with ( |c| {
404
- let prev = c. get ( ) ;
405
- c. set ( prev + 1 ) ;
406
- } ) ;
407
-
411
+ update_panic_count ( 1 ) ;
408
412
rust_panic ( msg)
409
413
}
410
414
0 commit comments