blob: b0a28b6c899da040e3cb5de057132dc70653ddaf [file] [log] [blame]
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:111//! Check that `rustc` and `rustdoc` does not ICE upon encountering a broken pipe due to unhandled
2//! panics from raw std `println!` usages.
3//!
4//! Regression test for <https://github.com/rust-lang/rust/issues/34376>.
5
6//@ ignore-cross-compile (needs to run test binary)
7
许杰友 Jieyou Xu (Joe)fe874872024-10-09 04:49:278//@ ignore-apple
9// FIXME(#131436): on macOS rustc is still reporting the std broken pipe io error panick but it
10// doesn't fail with 101 exit status (it terminates with a wait status of SIGPIPE). It doesn't say
11// Internal Compiler Error strangely, but it doesn't even go through normal diagnostic infra. Very
12// strange.
13
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1114use std::io::Read;
15use std::process::{Command, Stdio};
16
Jieyou Xu84ed40d2025-05-09 11:52:3617use run_make_support::{bare_rustc, rustdoc};
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1118
19#[derive(Debug, PartialEq)]
20enum Binary {
21 Rustc,
22 Rustdoc,
23}
24
25fn check_broken_pipe_handled_gracefully(bin: Binary, mut cmd: Command) {
Jieyou Xu83af9f52025-04-17 15:20:3026 let (reader, writer) = std::io::pipe().unwrap();
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1127 drop(reader); // close read-end
28 cmd.stdout(writer).stderr(Stdio::piped());
29
30 let mut child = cmd.spawn().unwrap();
31
32 let mut stderr = String::new();
33 child.stderr.as_mut().unwrap().read_to_string(&mut stderr).unwrap();
34 let status = child.wait().unwrap();
35
36 assert!(!status.success(), "{bin:?} unexpectedly succeeded");
37
38 const PANIC_ICE_EXIT_CODE: i32 = 101;
39
40 #[cfg(not(windows))]
41 {
42 // On non-Windows, rustc/rustdoc built with `-Zon-broken-pipe=kill` shouldn't have an exit
43 // code of 101 because it should have an wait status that corresponds to SIGPIPE signal
44 // number.
45 assert_ne!(status.code(), Some(PANIC_ICE_EXIT_CODE), "{bin:?}");
46 // And the stderr should be empty because rustc/rustdoc should've gotten killed.
47 assert!(stderr.is_empty(), "{bin:?} stderr:\n{}", stderr);
48 }
49
50 #[cfg(windows)]
51 {
52 match bin {
53 // On Windows, rustc has a paper that propagates the panic exit code of 101 but converts
54 // broken pipe errors into fatal errors instead of ICEs.
55 Binary::Rustc => {
56 assert_eq!(status.code(), Some(PANIC_ICE_EXIT_CODE), "{bin:?}");
57 // But make sure it doesn't manifest as an ICE.
58 assert!(!stderr.contains("internal compiler error"), "{bin:?} ICE'd");
59 }
60 // On Windows, rustdoc seems to cleanly exit with exit code of 1.
61 Binary::Rustdoc => {
62 assert_eq!(status.code(), Some(1), "{bin:?}");
63 assert!(!stderr.contains("panic"), "{bin:?} stderr contains panic");
64 }
65 }
66 }
67}
68
69fn main() {
Jieyou Xu84ed40d2025-05-09 11:52:3670 let mut rustc = bare_rustc();
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1171 rustc.arg("--print=sysroot");
Jieyou Xu84ed40d2025-05-09 11:52:3672 let rustc = rustc.into_raw_command();
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1173 check_broken_pipe_handled_gracefully(Binary::Rustc, rustc);
74
Jieyou Xu84ed40d2025-05-09 11:52:3675 let mut rustdoc = rustdoc();
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1176 rustdoc.arg("--version");
Jieyou Xu84ed40d2025-05-09 11:52:3677 let rustdoc = rustdoc.into_raw_command();
许杰友 Jieyou Xu (Joe)5c013162024-10-03 16:27:1178 check_broken_pipe_handled_gracefully(Binary::Rustdoc, rustdoc);
79}