Auto merge of #128958 - jieyouxu:freezing-over-here, r= · rust-lang/rust@c83dfe4 (original) (raw)

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

`+

// FIXME(#128911): @jieyouxu: This test is sometimes for whatever forsaken reason flakey in CI, and

`

``

19

`+

// I cannot reproduce it locally. The error messages upon assertion failure in this test is

`

``

20

`+

// intentionally extremely verbose to aid debugging that issue.

`

12

21

``

13

``

`-

use run_make_support::{cwd, has_extension, has_prefix, rfs, rustc, shallow_find_files};

`

``

22

`+

use std::cell::OnceCell;

`

``

23

`+

use std::path::{Path, PathBuf};

`

14

24

``

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

``

`-

});

`

``

25

`+

use run_make_support::{

`

``

26

`+

cwd, filename_contains, has_extension, has_prefix, rfs, run_in_tmpdir, rustc,

`

``

27

`+

shallow_find_files,

`

``

28

`+

};

`

``

29

+

``

30

`+

#[derive(Debug)]

`

``

31

`+

struct IceDump {

`

``

32

`+

name: &'static str,

`

``

33

`+

path: PathBuf,

`

``

34

`+

message: String,

`

``

35

`+

}

`

``

36

+

``

37

`+

impl IceDump {

`

``

38

`+

fn lines_count(&self) -> usize {

`

``

39

`+

self.message.lines().count()

`

``

40

`+

}

`

``

41

`+

}

`

``

42

+

``

43

`+

#[track_caller]

`

``

44

`+

fn assert_ice_len_equals(left: &IceDump, right: &IceDump) {

`

``

45

`+

let left_len = left.lines_count();

`

``

46

`+

let right_len = right.lines_count();

`

``

47

+

``

48

`+

if left_len != right_len {

`

``

49

`+

eprintln!("=== {} ICE MESSAGE ({} lines) ====", left.name, left_len);

`

``

50

`+

eprintln!("{}", left.message);

`

``

51

+

``

52

`+

eprintln!("=== {} ICE MESSAGE ({} lines) ====", right.name, right_len);

`

``

53

`+

eprintln!("{}", right.message);

`

``

54

+

``

55

`+

eprintln!("====================================");

`

``

56

`+

panic!(

`

``

57

`+

"ICE message length mismatch: {} has {} lines but {} has {} lines",

`

``

58

`+

left.name, left_len, right.name, right_len

`

``

59

`+

);

`

``

60

`+

}

`

``

61

`+

}

`

``

62

+

``

63

`+

fn find_ice_dumps_in_dir<P: AsRef>(dir: P) -> Vec {

`

``

64

`+

shallow_find_files(dir, |path| has_prefix(path, "rustc-ice") && has_extension(path, "txt"))

`

``

65

`+

}

`

``

66

+

``

67

`` +

// Assert only one rustc-ice*.txt ICE file exists, and extract the ICE message from the ICE file.

``

``

68

`+

#[track_caller]

`

``

69

`+

fn extract_exactly_one_ice_file<P: AsRef>(name: &'static str, dir: P) -> IceDump {

`

``

70

`+

let ice_files = find_ice_dumps_in_dir(dir);

`

27

71

`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")

`

``

72

`+

let path = ice_files.get(0).unwrap();

`

``

73

`+

let message = rfs::read_to_string(path);

`

``

74

`+

IceDump { name, path: path.to_path_buf(), message }

`

``

75

`+

}

`

``

76

+

``

77

`+

fn main() {

`

``

78

`+

// Establish baseline ICE message.

`

``

79

`+

let mut default_ice_dump = OnceCell::new();

`

``

80

`+

run_in_tmpdir(|| {

`

``

81

`+

rustc().env("RUSTC_ICE", cwd()).input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();

`

``

82

`+

let dump = extract_exactly_one_ice_file("baseline", cwd());

`

``

83

`` +

// Ensure that the ICE dump path doesn't contain :, because they cause problems on

``

``

84

`+

// Windows.

`

``

85

`` +

assert!(!filename_contains(&dump.path, ":"), "{} contains :", dump.path.display());

``

``

86

`+

// Some of the expected strings in an ICE file should appear.

`

``

87

`+

assert!(dump.message.contains("thread 'rustc' panicked at"));

`

``

88

`+

assert!(dump.message.contains("stack backtrace:"));

`

``

89

`+

default_ice_dump.set(dump).unwrap();

`

47

90

`});

`

48

``

`-

assert!(ice_files.is_empty()); // There should be 0 ICE files.

`

``

91

`+

let default_ice_dump = default_ice_dump.get().unwrap();

`

49

92

``

50

``

`-

metrics_dir(default);

`

51

``

`-

}

`

``

93

`+

test_backtrace_short(default_ice_dump);

`

``

94

`+

test_backtrace_full(default_ice_dump);

`

``

95

`+

test_backtrace_disabled(default_ice_dump);

`

``

96

`+

test_ice_dump_disabled();

`

52

97

``

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);

`

``

98

`+

test_metrics_dir(default_ice_dump);

`

64

99

`}

`

65

100

``

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);

`

``

101

`+

#[track_caller]

`

``

102

`+

fn test_backtrace_short(baseline: &IceDump) {

`

``

103

`+

run_in_tmpdir(|| {

`

``

104

`+

rustc()

`

``

105

`+

.env("RUSTC_ICE", cwd())

`

``

106

`+

.input("lib.rs")

`

``

107

`+

.env("RUST_BACKTRACE", "short")

`

``

108

`+

.arg("-Ztreat-err-as-bug=1")

`

``

109

`+

.run_fail();

`

``

110

`+

let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=short", cwd());

`

``

111

`` +

// Backtrace length in dump shouldn't be changed by RUST_BACKTRACE.

``

``

112

`+

assert_ice_len_equals(baseline, &dump);

`

``

113

`+

});

`

77

114

`}

`

78

115

``

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);

`

``

116

`+

#[track_caller]

`

``

117

`+

fn test_backtrace_full(baseline: &IceDump) {

`

``

118

`+

run_in_tmpdir(|| {

`

``

119

`+

rustc()

`

``

120

`+

.env("RUSTC_ICE", cwd())

`

``

121

`+

.input("lib.rs")

`

``

122

`+

.env("RUST_BACKTRACE", "full")

`

``

123

`+

.arg("-Ztreat-err-as-bug=1")

`

``

124

`+

.run_fail();

`

``

125

`+

let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=full", cwd());

`

``

126

`` +

// Backtrace length in dump shouldn't be changed by RUST_BACKTRACE.

``

``

127

`+

assert_ice_len_equals(baseline, &dump);

`

``

128

`+

});

`

90

129

`}

`

91

130

``

92

``

`-

fn metrics_dir(baseline: usize) {

`

93

``

`-

test_flag_only(baseline);

`

94

``

`-

test_flag_and_env(baseline);

`

``

131

`+

#[track_caller]

`

``

132

`+

fn test_backtrace_disabled(baseline: &IceDump) {

`

``

133

`+

run_in_tmpdir(|| {

`

``

134

`+

rustc()

`

``

135

`+

.env("RUSTC_ICE", cwd())

`

``

136

`+

.input("lib.rs")

`

``

137

`+

.env("RUST_BACKTRACE", "0")

`

``

138

`+

.arg("-Ztreat-err-as-bug=1")

`

``

139

`+

.run_fail();

`

``

140

`+

let dump = extract_exactly_one_ice_file("RUST_BACKTRACE=disabled", cwd());

`

``

141

`` +

// Backtrace length in dump shouldn't be changed by RUST_BACKTRACE.

``

``

142

`+

assert_ice_len_equals(baseline, &dump);

`

``

143

`+

});

`

95

144

`}

`

96

145

``

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);

`

``

146

`+

#[track_caller]

`

``

147

`+

fn test_ice_dump_disabled() {

`

``

148

`+

// The ICE dump is explicitly disabled. Therefore, this should produce no files.

`

``

149

`+

run_in_tmpdir(|| {

`

``

150

`+

rustc().env("RUSTC_ICE", "0").input("lib.rs").arg("-Ztreat-err-as-bug=1").run_fail();

`

``

151

`+

let ice_files = find_ice_dumps_in_dir(cwd());

`

``

152

`` +

assert!(ice_files.is_empty(), "there should be no ICE files if RUSTC_ICE=0 is set");

``

``

153

`+

});

`

103

154

`}

`

104

155

``

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);

`

``

156

`+

#[track_caller]

`

``

157

`+

fn test_metrics_dir(baseline: &IceDump) {

`

``

158

`+

test_flag_only(baseline);

`

``

159

`+

test_flag_and_env(baseline);

`

118

160

`}

`

119

161

``

120

``

`-

fn clear_ice_files() {

`

121

``

`-

let ice_files = shallow_find_files(cwd(), |path| {

`

122

``

`-

has_prefix(path, "rustc-ice") && has_extension(path, "txt")

`

``

162

`+

#[track_caller]

`

``

163

`+

fn test_flag_only(baseline: &IceDump) {

`

``

164

`+

run_in_tmpdir(|| {

`

``

165

`+

let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());

`

``

166

`+

rustc()

`

``

167

`+

.env_remove("RUSTC_ICE") // prevent interference from environment

`

``

168

`+

.input("lib.rs")

`

``

169

`+

.arg("-Ztreat-err-as-bug=1")

`

``

170

`+

.arg(metrics_arg)

`

``

171

`+

.run_fail();

`

``

172

`+

let dump = extract_exactly_one_ice_file("-Zmetrics-dir only", cwd());

`

``

173

`+

assert_ice_len_equals(baseline, &dump);

`

123

174

`});

`

124

``

`-

for file in ice_files {

`

125

``

`-

rfs::remove_file(file);

`

126

``

`-

}

`

127

175

`}

`

128

176

``

129

177

`#[track_caller]

`

130

``

`-

fn get_text_from_ice(dir: impl AsRefstd::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

`

``

178

`+

fn test_flag_and_env(baseline: &IceDump) {

`

``

179

`+

run_in_tmpdir(|| {

`

``

180

`+

let metrics_arg = format!("-Zmetrics-dir={}", cwd().display());

`

``

181

`+

let real_dir = cwd().join("actually_put_ice_here");

`

``

182

`+

rfs::create_dir(&real_dir);

`

``

183

`+

rustc()

`

``

184

`+

.input("lib.rs")

`

``

185

`+

.env("RUSTC_ICE", &real_dir)

`

``

186

`+

.arg("-Ztreat-err-as-bug=1")

`

``

187

`+

.arg(metrics_arg)

`

``

188

`+

.run_fail();

`

``

189

+

``

190

`+

let cwd_ice_files = find_ice_dumps_in_dir(cwd());

`

``

191

`+

assert!(cwd_ice_files.is_empty(), "RUSTC_ICE should override -Zmetrics-dir");

`

``

192

+

``

193

`+

let dump = extract_exactly_one_ice_file("RUSTC_ICE overrides -Zmetrics-dir", real_dir);

`

``

194

`+

assert_ice_len_equals(baseline, &dump);

`

``

195

`+

});

`

137

196

`}

`