mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
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
|
*.iml
|
||||||
.vscode
|
.vscode
|
||||||
.project
|
.project
|
||||||
|
.vim/
|
||||||
.favorites.json
|
.favorites.json
|
||||||
.settings/
|
.settings/
|
||||||
.vs/
|
.vs/
|
||||||
|
@ -51,7 +51,8 @@ use rustc_metadata::creader::MetadataLoader;
|
|||||||
use rustc_metadata::locator;
|
use rustc_metadata::locator;
|
||||||
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
|
||||||
use rustc_session::config::{
|
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::getopts::{self, Matches};
|
||||||
use rustc_session::lint::{Lint, LintId};
|
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 Some(matches) = handle_options(&default_early_dcx, &args) else { return Ok(()) };
|
||||||
|
|
||||||
let sopts = config::build_session_options(&mut default_early_dcx, &matches);
|
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") {
|
if let Some(ref code) = matches.opt_str("explain") {
|
||||||
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
|
||||||
@ -315,7 +318,7 @@ fn run_compiler(
|
|||||||
input: Input::File(PathBuf::new()),
|
input: Input::File(PathBuf::new()),
|
||||||
output_file: ofile,
|
output_file: ofile,
|
||||||
output_dir: odir,
|
output_dir: odir,
|
||||||
ice_file: ice_path().clone(),
|
ice_file,
|
||||||
file_loader,
|
file_loader,
|
||||||
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
locale_resources: DEFAULT_LOCALE_RESOURCES,
|
||||||
lint_caps: Default::default(),
|
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();
|
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> {
|
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(|| {
|
ICE_PATH.get_or_init(|| {
|
||||||
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
if !rustc_feature::UnstableFeatures::from_environment(None).is_nightly_build() {
|
||||||
return None;
|
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") {
|
let mut path = match std::env::var_os("RUSTC_ICE") {
|
||||||
Some(s) => {
|
Some(s) => {
|
||||||
if s == "0" {
|
if s == "0" {
|
||||||
// Explicitly opting out of writing ICEs to disk.
|
// Explicitly opting out of writing ICEs to disk.
|
||||||
return None;
|
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)
|
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 now: OffsetDateTime = SystemTime::now().into();
|
||||||
let file_now = now
|
let file_now = now
|
||||||
|
@ -1827,6 +1827,8 @@ options! {
|
|||||||
the same values as the target option of the same name"),
|
the same values as the target option of the same name"),
|
||||||
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
meta_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"gather metadata statistics (default: no)"),
|
"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],
|
mir_emit_retag: bool = (false, parse_bool, [TRACKED],
|
||||||
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
"emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 \
|
||||||
(default: no)"),
|
(default: no)"),
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
// or full.
|
// or full.
|
||||||
// - Check that disabling ICE logging results in zero files created.
|
// - Check that disabling ICE logging results in zero files created.
|
||||||
// - Check that the ICE files contain some of the expected strings.
|
// - 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
|
// See https://github.com/rust-lang/rust/pull/108714
|
||||||
|
|
||||||
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
|
use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};
|
||||||
@ -11,8 +15,8 @@ use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_
|
|||||||
fn main() {
|
fn main() {
|
||||||
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
||||||
let default = get_text_from_ice(".").lines().count();
|
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();
|
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 ice_text = get_text_from_ice(cwd());
|
||||||
let default_set = ice_text.lines().count();
|
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();
|
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.
|
// Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows.
|
||||||
assert!(!ice_file_name.contains(":"), "{ice_file_name}");
|
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();
|
clear_ice_files();
|
||||||
rustc()
|
rustc()
|
||||||
.env("RUSTC_ICE", cwd())
|
.env("RUSTC_ICE", cwd())
|
||||||
@ -34,6 +59,11 @@ fn main() {
|
|||||||
.arg("-Ztreat-err-as-bug=1")
|
.arg("-Ztreat-err-as-bug=1")
|
||||||
.run_fail();
|
.run_fail();
|
||||||
let short = get_text_from_ice(cwd()).lines().count();
|
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();
|
clear_ice_files();
|
||||||
rustc()
|
rustc()
|
||||||
.env("RUSTC_ICE", cwd())
|
.env("RUSTC_ICE", cwd())
|
||||||
@ -42,23 +72,49 @@ fn main() {
|
|||||||
.arg("-Ztreat-err-as-bug=1")
|
.arg("-Ztreat-err-as-bug=1")
|
||||||
.run_fail();
|
.run_fail();
|
||||||
let full = get_text_from_ice(cwd()).lines().count();
|
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();
|
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.
|
fn metrics_dir(baseline: usize) {
|
||||||
rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();
|
test_flag_only(baseline);
|
||||||
let ice_files = shallow_find_files(cwd(), |path| {
|
test_flag_and_env(baseline);
|
||||||
has_prefix(path, "rustc-ice") && has_extension(path, "txt")
|
}
|
||||||
});
|
|
||||||
assert!(ice_files.is_empty()); // There should be 0 ICE files.
|
|
||||||
|
|
||||||
// The line count should not change.
|
fn test_flag_only(baseline: usize) {
|
||||||
assert_eq!(short, default_set);
|
clear_ice_files();
|
||||||
assert_eq!(short, default);
|
let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());
|
||||||
assert_eq!(full, default_set);
|
rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").arg(metrics_arg).run_fail();
|
||||||
assert!(default > 0);
|
let output = get_text_from_ice(cwd()).lines().count();
|
||||||
// Some of the expected strings in an ICE file should appear.
|
assert_eq!(output, baseline);
|
||||||
assert!(content.contains("thread 'rustc' panicked at"));
|
}
|
||||||
assert!(content.contains("stack backtrace:"));
|
|
||||||
|
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() {
|
fn clear_ice_files() {
|
||||||
|
Loading…
Reference in New Issue
Block a user