Skip to content

Commit a45d0d9

Browse files
committed
Add regression test for rustc/rustdoc broken pipe ICEs
1 parent 03abf67 commit a45d0d9

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/bootstrap/src/bin/rustc.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,8 @@ fn main() {
136136
cmd.args(lint_flags.split_whitespace());
137137
}
138138

139-
// Conditionally pass `-Zon-broken-pipe=kill` to rustc bin shim when this shim is *not* used to
140-
// build cargo itself, i.e. set `-Zon-broken-pipe=kill` only when building non-cargo tools.
141-
//
142-
// See <https://github.com/rust-lang/rust/issues/131059> for more context.
139+
// Conditionally pass `-Zon-broken-pipe=kill` to underlying rustc. Not all binaries want
140+
// `-Zon-broken-pipe=kill`, which includes cargo itself.
143141
if env::var_os("FORCE_ON_BROKEN_PIPE_KILL").is_some() {
144142
cmd.arg("-Z").arg("on-broken-pipe=kill");
145143
}
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//! 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+
8+
#![feature(anonymous_pipe)]
9+
10+
use std::io::Read;
11+
use std::process::{Command, Stdio};
12+
13+
use run_make_support::env_var;
14+
15+
fn check_broken_pipe_handled_gracefully(name: &str, mut cmd: Command) {
16+
let (reader, writer) = std::pipe::pipe().unwrap();
17+
drop(reader); // close read-end
18+
cmd.stdout(writer).stderr(Stdio::piped());
19+
20+
let mut child = cmd.spawn().unwrap();
21+
22+
let mut stderr = String::new();
23+
child.stderr.as_mut().unwrap().read_to_string(&mut stderr).unwrap();
24+
let status = child.wait().unwrap();
25+
26+
assert!(!status.success(), "{name}");
27+
28+
const PANIC_ICE_EXIT_STATUS: i32 = 101;
29+
assert_ne!(status.code(), Some(101), "{name}");
30+
31+
assert!(stderr.is_empty(), "{name} stderr:\n{}", stderr);
32+
}
33+
34+
fn main() {
35+
let mut rustc = Command::new(env_var("RUSTC"));
36+
rustc.arg("--print=sysroot");
37+
check_broken_pipe_handled_gracefully("rustc", rustc);
38+
39+
let mut rustdoc = Command::new(env_var("RUSTDOC"));
40+
rustdoc.arg("--version");
41+
check_broken_pipe_handled_gracefully("rustdoc", rustdoc);
42+
}

0 commit comments

Comments
 (0)