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 /compiler/rustc_errors | |
| 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 'compiler/rustc_errors')
| -rw-r--r-- | compiler/rustc_errors/src/json/tests.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 31 |
2 files changed, 29 insertions, 4 deletions
diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 671dc449eaa..db0dd4ffe8e 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -64,7 +64,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { ); let span = Span::with_root_ctxt(BytePos(span.0), BytePos(span.1)); - let handler = Handler::with_emitter(true, None, Box::new(je)); + let handler = Handler::with_emitter(true, None, Box::new(je), None); handler.span_err(span, "foo"); let bytes = output.lock().unwrap(); diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b9db25103a3..31410c39d36 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -47,9 +47,10 @@ use std::borrow::Cow; use std::error::Report; use std::fmt; use std::hash::Hash; +use std::io::Write; use std::num::NonZeroUsize; use std::panic; -use std::path::Path; +use std::path::{Path, PathBuf}; use termcolor::{Color, ColorSpec}; @@ -461,6 +462,10 @@ struct HandlerInner { /// /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html fulfilled_expectations: FxHashSet<LintExpectationId>, + + /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be + /// stored along side the main panic backtrace. + ice_file: Option<PathBuf>, } /// A key denoting where from a diagnostic was stashed. @@ -550,6 +555,7 @@ impl Handler { sm: Option<Lrc<SourceMap>>, fluent_bundle: Option<Lrc<FluentBundle>>, fallback_bundle: LazyFallbackBundle, + ice_file: Option<PathBuf>, ) -> Self { Self::with_tty_emitter_and_flags( color_config, @@ -557,6 +563,7 @@ impl Handler { fluent_bundle, fallback_bundle, HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, + ice_file, ) } @@ -566,6 +573,7 @@ impl Handler { fluent_bundle: Option<Lrc<FluentBundle>>, fallback_bundle: LazyFallbackBundle, flags: HandlerFlags, + ice_file: Option<PathBuf>, ) -> Self { let emitter = Box::new(EmitterWriter::stderr( color_config, @@ -579,23 +587,26 @@ impl Handler { flags.track_diagnostics, TerminalUrl::No, )); - Self::with_emitter_and_flags(emitter, flags) + Self::with_emitter_and_flags(emitter, flags, ice_file) } pub fn with_emitter( can_emit_warnings: bool, treat_err_as_bug: Option<NonZeroUsize>, emitter: Box<dyn Emitter + sync::Send>, + ice_file: Option<PathBuf>, ) -> Self { Handler::with_emitter_and_flags( emitter, HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() }, + ice_file, ) } pub fn with_emitter_and_flags( emitter: Box<dyn Emitter + sync::Send>, flags: HandlerFlags, + ice_file: Option<PathBuf>, ) -> Self { Self { flags, @@ -618,6 +629,7 @@ impl Handler { check_unstable_expect_diagnostics: false, unstable_expect_diagnostics: Vec::new(), fulfilled_expectations: Default::default(), + ice_file, }), } } @@ -1657,8 +1669,21 @@ impl HandlerInner { explanation: impl Into<DiagnosticMessage> + Copy, ) { let mut no_bugs = true; + // If backtraces are enabled, also print the query stack + let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(true, |x| &x != "0"); for bug in bugs { - let mut bug = bug.decorate(); + if let Some(file) = self.ice_file.as_ref() + && let Ok(mut out) = std::fs::File::options().append(true).open(file) + { + let _ = write!( + &mut out, + "\n\ndelayed span bug: {}\n{}", + bug.inner.styled_message().iter().filter_map(|(msg, _)| msg.as_str()).collect::<String>(), + &bug.note + ); + } + let mut bug = + if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner }; if no_bugs { // Put the overall explanation before the `DelayedBug`s, to |
