diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2023-03-03 22:25:18 +0000 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2023-07-19 14:10:07 +0000 |
| commit | 8eb5843a592afbee8ae5352828f8f0b74034b9e0 (patch) | |
| tree | a8f3bd019a4c355babb7e5b5ae0bc58c0b5007b3 /library/std/src | |
| parent | 77e24f90f599070af2d8051ef9adad7fe528dd78 (diff) | |
| download | rust-8eb5843a592afbee8ae5352828f8f0b74034b9e0.tar.gz rust-8eb5843a592afbee8ae5352828f8f0b74034b9e0.zip | |
On nightly, dump ICE backtraces to disk
Implement rust-lang/compiler-team#578. When an ICE is encountered on nightly releases, the new rustc panic handler will also write the contents of the backtrace to disk. If any `delay_span_bug`s are encountered, their backtrace is also added to the file. The platform and rustc version will also be collected.
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/lib.rs | 3 | ||||
| -rw-r--r-- | library/std/src/panicking.rs | 38 |
2 files changed, 34 insertions, 7 deletions
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d287397aab3..5bf66850f03 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -604,6 +604,9 @@ pub mod alloc; // Private support modules mod panicking; +#[unstable(feature = "ice_to_disk", issue = "none")] +pub use panicking::panic_hook_with_disk_dump; + #[path = "../../backtrace/src/lib.rs"] #[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] mod backtrace_rs; diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index a6a370409c0..0e90d618ad4 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -234,7 +234,16 @@ where *hook = Hook::Custom(Box::new(move |info| hook_fn(&prev, info))); } +/// The default panic handler. fn default_hook(info: &PanicInfo<'_>) { + panic_hook_with_disk_dump(info, None) +} + +#[unstable(feature = "ice_to_disk", issue = "none")] +/// The implementation of the default panic handler. +/// +/// It can also write the backtrace to a given `path`. This functionality is used only by `rustc`. +pub fn panic_hook_with_disk_dump(info: &PanicInfo<'_>, path: Option<&crate::path::Path>) { // If this is a double panic, make sure that we print a backtrace // for this panic. Otherwise only print it if logging is enabled. let backtrace = if panic_count::get_count() >= 2 { @@ -256,7 +265,7 @@ fn default_hook(info: &PanicInfo<'_>) { let thread = thread_info::current_thread(); let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>"); - let write = |err: &mut dyn crate::io::Write| { + let write = |err: &mut dyn crate::io::Write, backtrace: Option<BacktraceStyle>| { let _ = writeln!(err, "thread '{name}' panicked at '{msg}', {location}"); static FIRST_PANIC: AtomicBool = AtomicBool::new(true); @@ -270,10 +279,19 @@ fn default_hook(info: &PanicInfo<'_>) { } Some(BacktraceStyle::Off) => { if FIRST_PANIC.swap(false, Ordering::SeqCst) { - let _ = writeln!( - err, - "note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace" - ); + if let Some(path) = path { + let _ = writeln!( + err, + "note: a backtrace for this error was stored at `{}`", + path.display(), + ); + } else { + let _ = writeln!( + err, + "note: run with `RUST_BACKTRACE=1` environment variable to display a \ + backtrace" + ); + } } } // If backtraces aren't supported, do nothing. @@ -281,11 +299,17 @@ fn default_hook(info: &PanicInfo<'_>) { } }; + if let Some(path) = path + && let Ok(mut out) = crate::fs::File::options().create(true).write(true).open(&path) + { + write(&mut out, BacktraceStyle::full()); + } + if let Some(local) = set_output_capture(None) { - write(&mut *local.lock().unwrap_or_else(|e| e.into_inner())); + write(&mut *local.lock().unwrap_or_else(|e| e.into_inner()), backtrace); set_output_capture(Some(local)); } else if let Some(mut out) = panic_output() { - write(&mut out); + write(&mut out, backtrace); } } |
