Skip to content

Commit 384c0c1

Browse files
committed
Add regression test for rustc/rustdoc broken pipe ICEs
1 parent a60bd9d commit 384c0c1

File tree

1 file changed

+50
-0
lines changed
  • tests/run-make/broken-pipe-no-ice

1 file changed

+50
-0
lines changed
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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+
// FIXME(jieyouxu): should test for Windows too, but rustc currently has a hack on Windows that
7+
// suppresses broken pipe errors.
8+
//@ only-unix (related to `-Zon-broken-pipe` behavior)
9+
//@ ignore-cross-compile (needs to run test binary)
10+
11+
use std::io::Read;
12+
use std::os::unix::process::ExitStatusExt;
13+
use std::process::{Command, Stdio};
14+
15+
use run_make_support::{env_var, libc};
16+
17+
fn check_broken_pipe_handled_gracefully(name: &str, mut cmd: Command) {
18+
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
19+
20+
let mut child = cmd.spawn().unwrap();
21+
// Close stdout
22+
drop(child.stdout.take());
23+
// Read stderr
24+
let mut stderr = String::new();
25+
child.stderr.as_mut().unwrap().read_to_string(&mut stderr).unwrap();
26+
let status = child.wait().unwrap();
27+
28+
assert!(!status.success(), "{name}");
29+
30+
const PANIC_ICE_EXIT_STATUS: i32 = 101;
31+
assert_ne!(status.code(), Some(101), "{name}");
32+
33+
// By default with `SIG_DFL`, `SIGPIPE` get `Term` action.
34+
//
35+
// See <https://man7.org/linux/man-pages/man7/signal.7.html>. `SIGPIPE` seems to be signal
36+
// number 13 pretty consistently.
37+
assert_eq!(status.signal(), Some(libc::SIGPIPE), "{name}");
38+
39+
assert!(stderr.is_empty(), "{name} stderr:\n{}", stderr);
40+
}
41+
42+
fn main() {
43+
let mut rustc = Command::new(env_var("RUSTC"));
44+
rustc.arg("--print=sysroot");
45+
check_broken_pipe_handled_gracefully("rustc", rustc);
46+
47+
let mut rustdoc = Command::new(env_var("RUSTDOC"));
48+
rustdoc.arg("--version");
49+
check_broken_pipe_handled_gracefully("rustdoc", rustdoc);
50+
}

0 commit comments

Comments
 (0)