Rollup merge of #48266 - pietroalbini:report-compiler-flags-on-ice, r=michaelwoerister

Report non-standard compile flags on ICE

Some ICEs (such as the recent #48248) only happens when a non-standard compiler flag is provided to rustc, but users don't always report the used flags. This can slow down reproducing the issue, so this PR shows all the non-standard compiler flags in the ICE error message.

For example, the output of #48248 with this PR is:

```
error: internal compiler error: [...]

thread 'rustc' panicked at [...]
note: Run with `RUST_BACKTRACE=1` for a backtrace.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: [...]

note: rustc 1.25.0-dev running on x86_64-unknown-linux-gnu

note: compiler flags: -C link-dead-code
```

### Open questions

* At the moment, only `-C` and `-Z` flags are shown by default, and all the ones provided by cargo in a standard build are ignored: I did this to only show the flags that probably caused the ICE, and to remove some noise from the message. This removed flags like `opt-level` and `debuginfo` though, could those be useful for reproducing ICEs?
This commit is contained in:
kennytm 2018-02-28 19:15:27 +08:00 committed by GitHub
commit f933dd243a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -139,6 +139,19 @@ pub mod target_features {
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
md#bug-reports";
const ICE_REPORT_COMPILER_FLAGS: &'static [&'static str] = &[
"Z",
"C",
"crate-type",
];
const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &'static [&'static str] = &[
"metadata",
"extra-filename",
];
const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &'static [&'static str] = &[
"incremental",
];
pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) -> T {
match result {
Err(CompileIncomplete::Errored(ErrorReported)) => {
@ -1431,6 +1444,57 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
thread.unwrap().join()
}
/// Get a list of extra command-line flags provided by the user, as strings.
///
/// This function is used during ICEs to show more information useful for
/// debugging, since some ICEs only happens with non-default compiler flags
/// (and the users don't always report them).
fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
let mut args = Vec::new();
for arg in env::args_os() {
args.push(arg.to_string_lossy().to_string());
}
let matches = if let Some(matches) = handle_options(&args) {
matches
} else {
return None;
};
let mut result = Vec::new();
let mut excluded_cargo_defaults = false;
for flag in ICE_REPORT_COMPILER_FLAGS {
let prefix = if flag.len() == 1 { "-" } else { "--" };
for content in &matches.opt_strs(flag) {
// Split always returns the first element
let name = if let Some(first) = content.split('=').next() {
first
} else {
&content
};
let content = if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&name) {
name
} else {
content
};
if !ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&name) {
result.push(format!("{}{} {}", prefix, flag, content));
} else {
excluded_cargo_defaults = true;
}
}
}
if result.len() > 0 {
Some((result, excluded_cargo_defaults))
} else {
None
}
}
/// Run a procedure which will detect panics in the compiler and print nicer
/// error messages rather than just failing the test.
///
@ -1462,11 +1526,22 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
errors::Level::Bug);
}
let xs = ["the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}", BUG_REPORT_URL),
format!("rustc {} running on {}",
option_env!("CFG_VERSION").unwrap_or("unknown_version"),
config::host_triple())];
let mut xs = vec![
"the compiler unexpectedly panicked. this is a bug.".to_string(),
format!("we would appreciate a bug report: {}", BUG_REPORT_URL),
format!("rustc {} running on {}",
option_env!("CFG_VERSION").unwrap_or("unknown_version"),
config::host_triple()),
];
if let Some((flags, excluded_cargo_defaults)) = extra_compiler_flags() {
xs.push(format!("compiler flags: {}", flags.join(" ")));
if excluded_cargo_defaults {
xs.push("some of the compiler flags provided by cargo are hidden".to_string());
}
}
for note in &xs {
handler.emit(&MultiSpan::new(),
&note,