diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 6f7ccde5e5bc7..18f5a1a58db93 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -136,10 +136,8 @@ fn main() { cmd.args(lint_flags.split_whitespace()); } - // Conditionally pass `-Zon-broken-pipe=kill` to rustc bin shim when this shim is *not* used to - // build cargo itself, i.e. set `-Zon-broken-pipe=kill` only when building non-cargo tools. - // - // See for more context. + // Conditionally pass `-Zon-broken-pipe=kill` to underlying rustc. Not all binaries want + // `-Zon-broken-pipe=kill`, which includes cargo itself. if env::var_os("FORCE_ON_BROKEN_PIPE_KILL").is_some() { cmd.arg("-Z").arg("on-broken-pipe=kill"); } diff --git a/tests/run-make/broken-pipe-no-ice/rmake.rs b/tests/run-make/broken-pipe-no-ice/rmake.rs new file mode 100644 index 0000000000000..1a41d1e1b0dc3 --- /dev/null +++ b/tests/run-make/broken-pipe-no-ice/rmake.rs @@ -0,0 +1,42 @@ +//! Check that `rustc` and `rustdoc` does not ICE upon encountering a broken pipe due to unhandled +//! panics from raw std `println!` usages. +//! +//! Regression test for . + +//@ ignore-cross-compile (needs to run test binary) + +#![feature(anonymous_pipe)] + +use std::io::Read; +use std::process::{Command, Stdio}; + +use run_make_support::env_var; + +fn check_broken_pipe_handled_gracefully(name: &str, mut cmd: Command) { + let (reader, writer) = std::pipe::pipe().unwrap(); + drop(reader); // close read-end + cmd.stdout(writer).stderr(Stdio::piped()); + + let mut child = cmd.spawn().unwrap(); + + let mut stderr = String::new(); + child.stderr.as_mut().unwrap().read_to_string(&mut stderr).unwrap(); + let status = child.wait().unwrap(); + + assert!(!status.success(), "{name}"); + + const PANIC_ICE_EXIT_STATUS: i32 = 101; + assert_ne!(status.code(), Some(101), "{name}"); + + assert!(stderr.is_empty(), "{name} stderr:\n{}", stderr); +} + +fn main() { + let mut rustc = Command::new(env_var("RUSTC")); + rustc.arg("--print=sysroot"); + check_broken_pipe_handled_gracefully("rustc", rustc); + + let mut rustdoc = Command::new(env_var("RUSTDOC")); + rustdoc.arg("--version"); + check_broken_pipe_handled_gracefully("rustdoc", rustdoc); +}