Add -Zerror-metrics=PATH to save diagnostic metadata to disk
This commit is contained in:
parent
2b78d92096
commit
5212c75907
1
.gitignore
vendored
1
.gitignore
vendored
@ -19,6 +19,7 @@ Session.vim
|
||||
*.iml
|
||||
.vscode
|
||||
.project
|
||||
.vim/
|
||||
.favorites.json
|
||||
.settings/
|
||||
.vs/
|
||||
|
@ -51,7 +51,8 @@
|
||||
use rustc_metadata::locator;
|
||||
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
||||
use rustc_session::config::{
|
||||
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, CG_OPTIONS, Z_OPTIONS,
|
||||
nightly_options, ErrorOutputType, Input, OutFileName, OutputType, UnstableOptions, CG_OPTIONS,
|
||||
Z_OPTIONS,
|
||||
};
|
||||
use rustc_session::getopts::{self, Matches};
|
||||
use rustc_session::lint::{Lint, LintId};
|
||||
@ -301,6 +302,8 @@ fn run_compiler(
|
||||
let Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
|
||||
|
||||
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
|
||||
// fully initialize ice path static once unstable options are available as context
|
||||
let ice_file = ice_path_with_config(Some(&sopts.unstable_opts)).clone();
|
||||
|
||||
if let Some(ref code) = matches.opt_str("explain") {
|
||||
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
||||
@ -315,7 +318,7 @@ fn run_compiler(
|
||||
input: Input::File(PathBuf::new()),
|
||||
output_file: ofile,
|
||||
output_dir: odir,
|
||||
ice_file: ice_path().clone(),
|
||||
ice_file,
|
||||
file_loader,
|
||||
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
||||
lint_caps: Default::default(),
|
||||
@ -1306,25 +1309,43 @@ pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
|
||||
|
||||
static ICE_PATH: OnceLock<Option<PathBuf>> = OnceLock::new();
|
||||
|
||||
// This function should only be called from the ICE hook.
|
||||
//
|
||||
// The intended behavior is that `run_compiler` will invoke `ice_path_with_config` early in the
|
||||
// initialization process to properly initialize the ICE_PATH static based on parsed CLI flags.
|
||||
//
|
||||
// Subsequent calls to either function will then return the proper ICE path as configured by
|
||||
// the environment and cli flags
|
||||
fn ice_path() -> &'static Option<PathBuf> {
|
||||
ice_path_with_config(None)
|
||||
}
|
||||
|
||||
fn ice_path_with_config(config: Option<&UnstableOptions>) -> &'static Option<PathBuf> {
|
||||
if ICE_PATH.get().is_some() && config.is_some() && cfg!(debug_assertions) {
|
||||
tracing::warn!(
|
||||
"ICE_PATH has already been initialized -- files may be emitted at unintended paths"
|
||||
)
|
||||
}
|
||||
|
||||
ICE_PATH.get_or_init(|| {
|
||||
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
||||
return None;
|
||||
}
|
||||
if let Some(s) = std::env::var_os("RUST_BACKTRACE")
|
||||
&& s == "0"
|
||||
{
|
||||
return None;
|
||||
}
|
||||
let mut path = match std::env::var_os("RUSTC_ICE") {
|
||||
Some(s) => {
|
||||
if s == "0" {
|
||||
// Explicitly opting out of writing ICEs to disk.
|
||||
return None;
|
||||
}
|
||||
if let Some(unstable_opts) = config && unstable_opts.metrics_dir.is_some() {
|
||||
tracing::warn!("ignoring -Zerror-metrics in favor of RUSTC_ICE for destination of ICE report files");
|
||||
}
|
||||
PathBuf::from(s)
|
||||
}
|
||||
None => std::env::current_dir().unwrap_or_default(),
|
||||
None => config
|
||||
.and_then(|unstable_opts| unstable_opts.metrics_dir.to_owned())
|
||||
.or_else(|| std::env::current_dir().ok())
|
||||
.unwrap_or_default(),
|
||||
};
|
||||
let now: OffsetDateTime = SystemTime::now().into();
|
||||
let file_now = now
|
||||
|
@ -1827,6 +1827,8 @@ pub(crate) fn parse_wasm_c_abi(slot: &mut WasmCAbi, v: Option<&str>) -> bool {
|
||||
the same values as the target option of the same name"),
|
||||
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||
"gather metadata statistics (default: no)"),
|
||||
metrics_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
|
||||
"stores metrics about the errors being emitted by rustc to disk"),
|
||||
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
|
||||
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
||||
(default: no)"),
|
||||
|
@ -4,6 +4,10 @@
|
||||
// or full.
|
||||
// - Check that disabling ICE logging results in zero files created.
|
||||
// - Check that the ICE files contain some of the expected strings.
|
||||
// - exercise the -Zmetrics-dir nightly flag
|
||||
// - verify what happens when both the nightly flag and env variable are set
|
||||
// - test the RUST_BACKTRACE=0 behavior against the file creation
|
||||
|
||||
// See https://github.com/rust-lang/rust/pull/108714
|
||||
|
||||
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
|
||||
@ -11,8 +15,8 @@
|
||||
fn main() {
|
||||
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||
let default = get_text_from_ice(".").lines().count();
|
||||
clear_ice_files();
|
||||
|
||||
clear_ice_files();
|
||||
rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||
let ice_text = get_text_from_ice(cwd());
|
||||
let default_set = ice_text.lines().count();
|
||||
@ -25,7 +29,28 @@ fn main() {
|
||||
ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap();
|
||||
// Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
|
||||
assert!(!ice_file_name.contains(":"), "{ice_file_name}");
|
||||
assert_eq!(default, default_set);
|
||||
assert!(default > 0);
|
||||
// Some of the expected strings in an ICE file should appear.
|
||||
assert!(content.contains("thread 'rustc' panicked at"));
|
||||
assert!(content.contains("stack backtrace:"));
|
||||
|
||||
test_backtrace_short(default);
|
||||
test_backtrace_full(default);
|
||||
test_backtrace_disabled(default);
|
||||
|
||||
clear_ice_files();
|
||||
// The ICE dump is explicitly disabled. Therefore, this should produce no files.
|
||||
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||
let ice_files = shallow_find_files(cwd(), |path| {
|
||||
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
|
||||
});
|
||||
assert!(ice_files.is_empty()); // There should be 0 ICE files.
|
||||
|
||||
metrics_dir(default);
|
||||
}
|
||||
|
||||
fn test_backtrace_short(baseline: usize) {
|
||||
clear_ice_files();
|
||||
rustc()
|
||||
.env("RUSTC_ICE", cwd())
|
||||
@ -34,6 +59,11 @@ fn main() {
|
||||
.arg("-Ztreat-err-as-bug=1")
|
||||
.run_fail();
|
||||
let short = get_text_from_ice(cwd()).lines().count();
|
||||
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
|
||||
assert_eq!(short, baseline);
|
||||
}
|
||||
|
||||
fn test_backtrace_full(baseline: usize) {
|
||||
clear_ice_files();
|
||||
rustc()
|
||||
.env("RUSTC_ICE", cwd())
|
||||
@ -42,23 +72,49 @@ fn main() {
|
||||
.arg("-Ztreat-err-as-bug=1")
|
||||
.run_fail();
|
||||
let full = get_text_from_ice(cwd()).lines().count();
|
||||
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
|
||||
assert_eq!(full, baseline);
|
||||
}
|
||||
|
||||
fn test_backtrace_disabled(baseline: usize) {
|
||||
clear_ice_files();
|
||||
rustc()
|
||||
.env("RUSTC_ICE", cwd())
|
||||
.input("lib.rs")
|
||||
.env("RUST_BACKTRACE", "0")
|
||||
.arg("-Ztreat-err-as-bug=1")
|
||||
.run_fail();
|
||||
let disabled = get_text_from_ice(cwd()).lines().count();
|
||||
// backtrace length in dump shouldn't be changed by RUST_BACKTRACE
|
||||
assert_eq!(disabled, baseline);
|
||||
}
|
||||
|
||||
// The ICE dump is explicitly disabled. Therefore, this should produce no files.
|
||||
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||
let ice_files = shallow_find_files(cwd(), |path| {
|
||||
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
|
||||
});
|
||||
assert!(ice_files.is_empty()); // There should be 0 ICE files.
|
||||
fn metrics_dir(baseline: usize) {
|
||||
test_flag_only(baseline);
|
||||
test_flag_and_env(baseline);
|
||||
}
|
||||
|
||||
// The line count should not change.
|
||||
assert_eq!(short, default_set);
|
||||
assert_eq!(short, default);
|
||||
assert_eq!(full, default_set);
|
||||
assert!(default > 0);
|
||||
// Some of the expected strings in an ICE file should appear.
|
||||
assert!(content.contains("thread 'rustc' panicked at"));
|
||||
assert!(content.contains("stack backtrace:"));
|
||||
fn test_flag_only(baseline: usize) {
|
||||
clear_ice_files();
|
||||
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
|
||||
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").arg(metrics_arg).run_fail();
|
||||
let output = get_text_from_ice(cwd()).lines().count();
|
||||
assert_eq!(output, baseline);
|
||||
}
|
||||
|
||||
fn test_flag_and_env(baseline: usize) {
|
||||
clear_ice_files();
|
||||
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
|
||||
let real_dir = cwd().join("actually_put_ice_here");
|
||||
rfs::create_dir(real_dir.clone());
|
||||
rustc()
|
||||
.input("lib.rs")
|
||||
.env("RUSTC_ICE", real_dir.clone())
|
||||
.arg("-Ztreat-err-as-bug=1")
|
||||
.arg(metrics_arg)
|
||||
.run_fail();
|
||||
let output = get_text_from_ice(real_dir).lines().count();
|
||||
assert_eq!(output, baseline);
|
||||
}
|
||||
|
||||
fn clear_ice_files() {
|
||||
|
Loading…
Reference in New Issue
Block a user