@@ -234,7 +234,16 @@ where
234
234
* hook = Hook :: Custom ( Box :: new ( move |info| hook_fn ( & prev, info) ) ) ;
235
235
}
236
236
237
+ /// The default panic handler.
237
238
fn default_hook ( info : & PanicInfo < ' _ > ) {
239
+ panic_hook_with_disk_dump ( info, None )
240
+ }
241
+
242
+ #[ unstable( feature = "ice_to_disk" , issue = "none" ) ]
243
+ /// The implementation of the default panic handler.
244
+ ///
245
+ /// It can also write the backtrace to a given `path`. This functionality is used only by `rustc`.
246
+ pub fn panic_hook_with_disk_dump ( info : & PanicInfo < ' _ > , path : Option < & crate :: path:: Path > ) {
238
247
// If this is a double panic, make sure that we print a backtrace
239
248
// for this panic. Otherwise only print it if logging is enabled.
240
249
let backtrace = if panic_count:: get_count ( ) >= 2 {
@@ -256,7 +265,7 @@ fn default_hook(info: &PanicInfo<'_>) {
256
265
let thread = thread_info:: current_thread ( ) ;
257
266
let name = thread. as_ref ( ) . and_then ( |t| t. name ( ) ) . unwrap_or ( "<unnamed>" ) ;
258
267
259
- let write = |err : & mut dyn crate :: io:: Write | {
268
+ let write = |err : & mut dyn crate :: io:: Write , backtrace : Option < BacktraceStyle > | {
260
269
let _ = writeln ! ( err, "thread '{name}' panicked at '{msg}', {location}" ) ;
261
270
262
271
static FIRST_PANIC : AtomicBool = AtomicBool :: new ( true ) ;
@@ -270,22 +279,37 @@ fn default_hook(info: &PanicInfo<'_>) {
270
279
}
271
280
Some ( BacktraceStyle :: Off ) => {
272
281
if FIRST_PANIC . swap ( false , Ordering :: SeqCst ) {
273
- let _ = writeln ! (
274
- err,
275
- "note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace"
276
- ) ;
282
+ if let Some ( path) = path {
283
+ let _ = writeln ! (
284
+ err,
285
+ "note: a backtrace for this error was stored at `{}`" ,
286
+ path. display( ) ,
287
+ ) ;
288
+ } else {
289
+ let _ = writeln ! (
290
+ err,
291
+ "note: run with `RUST_BACKTRACE=1` environment variable to display a \
292
+ backtrace"
293
+ ) ;
294
+ }
277
295
}
278
296
}
279
297
// If backtraces aren't supported, do nothing.
280
298
None => { }
281
299
}
282
300
} ;
283
301
302
+ if let Some ( path) = path
303
+ && let Ok ( mut out) = crate :: fs:: File :: options ( ) . create ( true ) . write ( true ) . open ( & path)
304
+ {
305
+ write ( & mut out, BacktraceStyle :: full ( ) ) ;
306
+ }
307
+
284
308
if let Some ( local) = set_output_capture ( None ) {
285
- write ( & mut * local. lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) ) ;
309
+ write ( & mut * local. lock ( ) . unwrap_or_else ( |e| e. into_inner ( ) ) , backtrace ) ;
286
310
set_output_capture ( Some ( local) ) ;
287
311
} else if let Some ( mut out) = panic_output ( ) {
288
- write ( & mut out) ;
312
+ write ( & mut out, backtrace ) ;
289
313
}
290
314
}
291
315
0 commit comments