@@ -234,7 +234,16 @@ where
234234 * hook = Hook :: Custom ( Box :: new ( move |info| hook_fn ( & prev, info) ) ) ;
235235}
236236
237+ /// The default panic handler.
237238fn 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 > ) {
238247 // If this is a double panic, make sure that we print a backtrace
239248 // for this panic. Otherwise only print it if logging is enabled.
240249 let backtrace = if panic_count:: get_count ( ) >= 2 {
@@ -256,7 +265,7 @@ fn default_hook(info: &PanicInfo<'_>) {
256265 let thread = thread_info:: current_thread ( ) ;
257266 let name = thread. as_ref ( ) . and_then ( |t| t. name ( ) ) . unwrap_or ( "<unnamed>" ) ;
258267
259- let write = |err : & mut dyn crate :: io:: Write | {
268+ let write = |err : & mut dyn crate :: io:: Write , backtrace : Option < BacktraceStyle > | {
260269 let _ = writeln ! ( err, "thread '{name}' panicked at '{msg}', {location}" ) ;
261270
262271 static FIRST_PANIC : AtomicBool = AtomicBool :: new ( true ) ;
@@ -270,22 +279,37 @@ fn default_hook(info: &PanicInfo<'_>) {
270279 }
271280 Some ( BacktraceStyle :: Off ) => {
272281 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+ }
277295 }
278296 }
279297 // If backtraces aren't supported, do nothing.
280298 None => { }
281299 }
282300 } ;
283301
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+
284308 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 ) ;
286310 set_output_capture ( Some ( local) ) ;
287311 } else if let Some ( mut out) = panic_output ( ) {
288- write ( & mut out) ;
312+ write ( & mut out, backtrace ) ;
289313 }
290314}
291315
0 commit comments