|
1 |
| -// This test checks if internal compilation error (ICE) log files work as expected. |
2 |
| -// - Get the number of lines from the log files without any configuration options, |
3 |
| -// then check that the line count doesn't change if the backtrace gets configured to be short |
4 |
| -// or full. |
5 |
| -// - Check that disabling ICE logging results in zero files created. |
6 |
| -// - Check that the ICE files contain some of the expected strings. |
7 |
| -// - exercise the -Zmetrics-dir nightly flag |
8 |
| -// - verify what happens when both the nightly flag and env variable are set |
9 |
| -// - test the RUST_BACKTRACE=0 behavior against the file creation |
| 1 | +//! This test checks if Internal Compilation Error (ICE) dump files `rustc-ice*.txt` work as |
| 2 | +//! expected. |
| 3 | +//! |
| 4 | +//! - Basic sanity checks on a default ICE dump. |
| 5 | +//! - Get the number of lines from the dump files without any `RUST_BACKTRACE` options, then check |
| 6 | +//! ICE dump file (line count) is not affected by `RUSTC_BACKTRACE` settings. |
| 7 | +//! - Check that disabling ICE dumping results in zero dump files created. |
| 8 | +//! - Check that the ICE dump contain some of the expected strings. |
| 9 | +//! - Check that `RUST_BACKTRACE=0` prevents ICE dump from created. |
| 10 | +//! - Exercise the `-Zmetrics-dir` nightly flag (#128914): |
| 11 | +//! - When `-Zmetrics=dir=PATH` is present but `RUSTC_ICE` is not set, check that the ICE dump |
| 12 | +//! is placed under `PATH`. |
| 13 | +//! - When `RUSTC_ICE=RUSTC_ICE_PATH` and `-Zmetrics-dir=METRICS_PATH` are both provided, check |
| 14 | +//! that `RUSTC_ICE_PATH` takes precedence and no ICE dump is emitted under `METRICS_PATH`. |
| 15 | +//! |
| 16 | +//! See <https://github.com/rust-lang/rust/pull/108714>. |
10 | 17 |
|
11 |
| -// See https://github.com/rust-lang/rust/pull/108714 |
| 18 | +//@ ignore-windows |
| 19 | +// FIXME(#128911): @jieyouxu: This test is sometimes for whatever forsaken reason flakey in |
| 20 | +// `i686-mingw`, and I cannot reproduce it locally. The error messages upon assertion failure in |
| 21 | +// this test is intentionally extremely verbose to aid debugging that issue. |
12 | 22 |
|
13 |
| -use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files}; |
| 23 | +use std::cell::OnceCell; |
| 24 | +use std::path::{Path, PathBuf}; |
14 | 25 |
|
15 |
| -fn main() { |
16 |
| - rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); |
17 |
| - let default = get_text_from_ice(".").lines().count(); |
18 |
| - |
19 |
| - clear_ice_files(); |
20 |
| - rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); |
21 |
| - let ice_text = get_text_from_ice(cwd()); |
22 |
| - let default_set = ice_text.lines().count(); |
23 |
| - let content = ice_text; |
24 |
| - let ice_files = shallow_find_files(cwd(), |path| { |
25 |
| - has_prefix(path, "rustc-ice") && has_extension(path, "txt") |
26 |
| - }); |
| 26 | +use run_make_support::{ |
| 27 | + cwd, filename_contains, has_extension, has_prefix, rfs, run_in_tmpdir, rustc, |
| 28 | + shallow_find_files, |
| 29 | +}; |
| 30 | + |
| 31 | +#[derive(Debug)] |
| 32 | +struct IceDump { |
| 33 | + name: &'static str, |
| 34 | + path: PathBuf, |
| 35 | + message: String, |
| 36 | +} |
| 37 | + |
| 38 | +impl IceDump { |
| 39 | + fn lines_count(&self) -> usize { |
| 40 | + self.message.lines().count() |
| 41 | + } |
| 42 | +} |
| 43 | + |
| 44 | +#[track_caller] |
| 45 | +fn assert_ice_len_equals(left: &IceDump, right: &IceDump) { |
| 46 | + let left_len = left.lines_count(); |
| 47 | + let right_len = right.lines_count(); |
| 48 | + |
| 49 | + if left_len != right_len { |
| 50 | + eprintln!("=== {} ICE MESSAGE ({} lines) ====", left.name, left_len); |
| 51 | + eprintln!("{}", left.message); |
| 52 | + |
| 53 | + eprintln!("=== {} ICE MESSAGE ({} lines) ====", right.name, right_len); |
| 54 | + eprintln!("{}", right.message); |
| 55 | + |
| 56 | + eprintln!("===================================="); |
| 57 | + panic!( |
| 58 | + "ICE message length mismatch: {} has {} lines but {} has {} lines", |
| 59 | + left.name, left_len, right.name, right_len |
| 60 | + ); |
| 61 | + } |
| 62 | +} |
| 63 | + |
| 64 | +fn find_ice_dumps_in_dir<P: AsRef<Path>>(dir: P) -> Vec<PathBuf> { |
| 65 | + shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt")) |
| 66 | +} |
| 67 | + |
| 68 | +// Assert only one `rustc-ice*.txt` ICE file exists, and extract the ICE message from the ICE file. |
| 69 | +#[track_caller] |
| 70 | +fn extract_exactly_one_ice_file<P: AsRef<Path>>(name: &'static str, dir: P) -> IceDump { |
| 71 | + let ice_files = find_ice_dumps_in_dir(dir); |
27 | 72 | assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file.
|
28 |
| - let ice_file_name = |
29 |
| - ice_files.first().and_then(|f| f.file_name()).and_then(|n| n.to_str()).unwrap(); |
30 |
| - // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on Windows. |
31 |
| - assert!(!ice_file_name.contains(":"), "{ice_file_name}"); |
32 |
| - assert_eq!(default, default_set); |
33 |
| - assert!(default > 0); |
34 |
| - // Some of the expected strings in an ICE file should appear. |
35 |
| - assert!(content.contains("thread 'rustc' panicked at")); |
36 |
| - assert!(content.contains("stack backtrace:")); |
37 |
| - |
38 |
| - test_backtrace_short(default); |
39 |
| - test_backtrace_full(default); |
40 |
| - test_backtrace_disabled(default); |
41 |
| - |
42 |
| - clear_ice_files(); |
43 |
| - // The ICE dump is explicitly disabled. Therefore, this should produce no files. |
44 |
| - rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); |
45 |
| - let ice_files = shallow_find_files(cwd(), |path| { |
46 |
| - has_prefix(path, "rustc-ice") && has_extension(path, "txt") |
| 73 | + let path = ice_files.get(0).unwrap(); |
| 74 | + let message = rfs::read_to_string(path); |
| 75 | + IceDump { name, path: path.to_path_buf(), message } |
| 76 | +} |
| 77 | + |
| 78 | +fn main() { |
| 79 | + // Establish baseline ICE message. |
| 80 | + let mut default_ice_dump = OnceCell::new(); |
| 81 | + run_in_tmpdir(|| { |
| 82 | + rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); |
| 83 | + let dump = extract_exactly_one_ice_file("baseline", cwd()); |
| 84 | + // Ensure that the ICE dump path doesn't contain `:`, because they cause problems on |
| 85 | + // Windows. |
| 86 | + assert!(!filename_contains(&dump.path, ":"), "{} contains `:`", dump.path.display()); |
| 87 | + // Some of the expected strings in an ICE file should appear. |
| 88 | + assert!(dump.message.contains("thread 'rustc' panicked at")); |
| 89 | + assert!(dump.message.contains("stack backtrace:")); |
| 90 | + default_ice_dump.set(dump).unwrap(); |
47 | 91 | });
|
48 |
| - assert!(ice_files.is_empty()); // There should be 0 ICE files. |
| 92 | + let default_ice_dump = default_ice_dump.get().unwrap(); |
49 | 93 |
|
50 |
| - metrics_dir(default); |
51 |
| -} |
| 94 | + test_backtrace_short(default_ice_dump); |
| 95 | + test_backtrace_full(default_ice_dump); |
| 96 | + test_backtrace_disabled(default_ice_dump); |
| 97 | + test_ice_dump_disabled(); |
52 | 98 |
|
53 |
| -fn test_backtrace_short(baseline: usize) { |
54 |
| - clear_ice_files(); |
55 |
| - rustc() |
56 |
| - .env("RUSTC_ICE", cwd()) |
57 |
| - .input("lib.rs") |
58 |
| - .env("RUST_BACKTRACE", "short") |
59 |
| - .arg("-Ztreat-err-as-bug=1") |
60 |
| - .run_fail(); |
61 |
| - let short = get_text_from_ice(cwd()).lines().count(); |
62 |
| - // backtrace length in dump shouldn't be changed by RUST_BACKTRACE |
63 |
| - assert_eq!(short, baseline); |
| 99 | + test_metrics_dir(default_ice_dump); |
64 | 100 | }
|
65 | 101 |
|
66 |
| -fn test_backtrace_full(baseline: usize) { |
67 |
| - clear_ice_files(); |
68 |
| - rustc() |
69 |
| - .env("RUSTC_ICE", cwd()) |
70 |
| - .input("lib.rs") |
71 |
| - .env("RUST_BACKTRACE", "full") |
72 |
| - .arg("-Ztreat-err-as-bug=1") |
73 |
| - .run_fail(); |
74 |
| - let full = get_text_from_ice(cwd()).lines().count(); |
75 |
| - // backtrace length in dump shouldn't be changed by RUST_BACKTRACE |
76 |
| - assert_eq!(full, baseline); |
| 102 | +#[track_caller] |
| 103 | +fn test_backtrace_short(baseline: &IceDump) { |
| 104 | + run_in_tmpdir(|| { |
| 105 | + rustc() |
| 106 | + .env("RUSTC_ICE", cwd()) |
| 107 | + .input("lib.rs") |
| 108 | + .env("RUST_BACKTRACE", "short") |
| 109 | + .arg("-Ztreat-err-as-bug=1") |
| 110 | + .run_fail(); |
| 111 | + let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=short", cwd()); |
| 112 | + // Backtrace length in dump shouldn't be changed by `RUST_BACKTRACE`. |
| 113 | + assert_ice_len_equals(baseline, &dump); |
| 114 | + }); |
77 | 115 | }
|
78 | 116 |
|
79 |
| -fn test_backtrace_disabled(baseline: usize) { |
80 |
| - clear_ice_files(); |
81 |
| - rustc() |
82 |
| - .env("RUSTC_ICE", cwd()) |
83 |
| - .input("lib.rs") |
84 |
| - .env("RUST_BACKTRACE", "0") |
85 |
| - .arg("-Ztreat-err-as-bug=1") |
86 |
| - .run_fail(); |
87 |
| - let disabled = get_text_from_ice(cwd()).lines().count(); |
88 |
| - // backtrace length in dump shouldn't be changed by RUST_BACKTRACE |
89 |
| - assert_eq!(disabled, baseline); |
| 117 | +#[track_caller] |
| 118 | +fn test_backtrace_full(baseline: &IceDump) { |
| 119 | + run_in_tmpdir(|| { |
| 120 | + rustc() |
| 121 | + .env("RUSTC_ICE", cwd()) |
| 122 | + .input("lib.rs") |
| 123 | + .env("RUST_BACKTRACE", "full") |
| 124 | + .arg("-Ztreat-err-as-bug=1") |
| 125 | + .run_fail(); |
| 126 | + let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=full", cwd()); |
| 127 | + // Backtrace length in dump shouldn't be changed by `RUST_BACKTRACE`. |
| 128 | + assert_ice_len_equals(baseline, &dump); |
| 129 | + }); |
90 | 130 | }
|
91 | 131 |
|
92 |
| -fn metrics_dir(baseline: usize) { |
93 |
| - test_flag_only(baseline); |
94 |
| - test_flag_and_env(baseline); |
| 132 | +#[track_caller] |
| 133 | +fn test_backtrace_disabled(baseline: &IceDump) { |
| 134 | + run_in_tmpdir(|| { |
| 135 | + rustc() |
| 136 | + .env("RUSTC_ICE", cwd()) |
| 137 | + .input("lib.rs") |
| 138 | + .env("RUST_BACKTRACE", "0") |
| 139 | + .arg("-Ztreat-err-as-bug=1") |
| 140 | + .run_fail(); |
| 141 | + let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=disabled", cwd()); |
| 142 | + // Backtrace length in dump shouldn't be changed by `RUST_BACKTRACE`. |
| 143 | + assert_ice_len_equals(baseline, &dump); |
| 144 | + }); |
95 | 145 | }
|
96 | 146 |
|
97 |
| -fn test_flag_only(baseline: usize) { |
98 |
| - clear_ice_files(); |
99 |
| - let metrics_arg = format!("-Zmetrics-dir={}", cwd().display()); |
100 |
| - rustc().input("lib.rs").arg("-Ztreat-err-as-bug=1").arg(metrics_arg).run_fail(); |
101 |
| - let output = get_text_from_ice(cwd()).lines().count(); |
102 |
| - assert_eq!(output, baseline); |
| 147 | +#[track_caller] |
| 148 | +fn test_ice_dump_disabled() { |
| 149 | + // The ICE dump is explicitly disabled. Therefore, this should produce no files. |
| 150 | + run_in_tmpdir(|| { |
| 151 | + rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail(); |
| 152 | + let ice_files = find_ice_dumps_in_dir(cwd()); |
| 153 | + assert!(ice_files.is_empty(), "there should be no ICE files if `RUSTC_ICE=0` is set"); |
| 154 | + }); |
103 | 155 | }
|
104 | 156 |
|
105 |
| -fn test_flag_and_env(baseline: usize) { |
106 |
| - clear_ice_files(); |
107 |
| - let metrics_arg = format!("-Zmetrics-dir={}", cwd().display()); |
108 |
| - let real_dir = cwd().join("actually_put_ice_here"); |
109 |
| - rfs::create_dir(real_dir.clone()); |
110 |
| - rustc() |
111 |
| - .input("lib.rs") |
112 |
| - .env("RUSTC_ICE", real_dir.clone()) |
113 |
| - .arg("-Ztreat-err-as-bug=1") |
114 |
| - .arg(metrics_arg) |
115 |
| - .run_fail(); |
116 |
| - let output = get_text_from_ice(real_dir).lines().count(); |
117 |
| - assert_eq!(output, baseline); |
| 157 | +#[track_caller] |
| 158 | +fn test_metrics_dir(baseline: &IceDump) { |
| 159 | + test_flag_only(baseline); |
| 160 | + test_flag_and_env(baseline); |
118 | 161 | }
|
119 | 162 |
|
120 |
| -fn clear_ice_files() { |
121 |
| - let ice_files = shallow_find_files(cwd(), |path| { |
122 |
| - has_prefix(path, "rustc-ice") && has_extension(path, "txt") |
| 163 | +#[track_caller] |
| 164 | +fn test_flag_only(baseline: &IceDump) { |
| 165 | + run_in_tmpdir(|| { |
| 166 | + let metrics_arg = format!("-Zmetrics-dir={}", cwd().display()); |
| 167 | + rustc() |
| 168 | + .env_remove("RUSTC_ICE") // prevent interference from environment |
| 169 | + .input("lib.rs") |
| 170 | + .arg("-Ztreat-err-as-bug=1") |
| 171 | + .arg(metrics_arg) |
| 172 | + .run_fail(); |
| 173 | + let dump = extract_exactly_one_ice_file("-Zmetrics-dir only", cwd()); |
| 174 | + assert_ice_len_equals(baseline, &dump); |
123 | 175 | });
|
124 |
| - for file in ice_files { |
125 |
| - rfs::remove_file(file); |
126 |
| - } |
127 | 176 | }
|
128 | 177 |
|
129 | 178 | #[track_caller]
|
130 |
| -fn get_text_from_ice(dir: impl AsRef<std::path::Path>) -> String { |
131 |
| - let ice_files = |
132 |
| - shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt")); |
133 |
| - assert_eq!(ice_files.len(), 1); // There should only be 1 ICE file. |
134 |
| - let ice_file = ice_files.get(0).unwrap(); |
135 |
| - let output = rfs::read_to_string(ice_file); |
136 |
| - output |
| 179 | +fn test_flag_and_env(baseline: &IceDump) { |
| 180 | + run_in_tmpdir(|| { |
| 181 | + let metrics_arg = format!("-Zmetrics-dir={}", cwd().display()); |
| 182 | + let real_dir = cwd().join("actually_put_ice_here"); |
| 183 | + rfs::create_dir(&real_dir); |
| 184 | + rustc() |
| 185 | + .input("lib.rs") |
| 186 | + .env("RUSTC_ICE", &real_dir) |
| 187 | + .arg("-Ztreat-err-as-bug=1") |
| 188 | + .arg(metrics_arg) |
| 189 | + .run_fail(); |
| 190 | + |
| 191 | + let cwd_ice_files = find_ice_dumps_in_dir(cwd()); |
| 192 | + assert!(cwd_ice_files.is_empty(), "RUSTC_ICE should override -Zmetrics-dir"); |
| 193 | + |
| 194 | + let dump = extract_exactly_one_ice_file("RUSTC_ICE overrides -Zmetrics-dir", real_dir); |
| 195 | + assert_ice_len_equals(baseline, &dump); |
| 196 | + }); |
137 | 197 | }
|
0 commit comments