|
| 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 | +#[derive(Debug,PartialEq)] |
| 16 | +enumBinary{ |
| 17 | +Rustc, |
| 18 | +Rustdoc, |
| 19 | +} |
| 20 | + |
| 21 | +fncheck_broken_pipe_handled_gracefully(bin:Binary,mutcmd:Command){ |
| 22 | +let(reader, writer) = std::pipe::pipe().unwrap(); |
| 23 | +drop(reader);// close read-end |
| 24 | + cmd.stdout(writer).stderr(Stdio::piped()); |
| 25 | + |
| 26 | +letmut child = cmd.spawn().unwrap(); |
| 27 | + |
| 28 | +letmut stderr = String::new(); |
| 29 | + child.stderr.as_mut().unwrap().read_to_string(&mut stderr).unwrap(); |
| 30 | +let status = child.wait().unwrap(); |
| 31 | + |
| 32 | +assert!(!status.success(),"{bin:?} unexpectedly succeeded"); |
| 33 | + |
| 34 | +constPANIC_ICE_EXIT_CODE:i32 = 101; |
| 35 | + |
| 36 | +#[cfg(not(windows))] |
| 37 | +{ |
| 38 | +// On non-Windows, rustc/rustdoc built with `-Zon-broken-pipe=kill` shouldn't have an exit |
| 39 | +// code of 101 because it should have an wait status that corresponds to SIGPIPE signal |
| 40 | +// number. |
| 41 | +assert_ne!(status.code(),Some(PANIC_ICE_EXIT_CODE),"{bin:?}"); |
| 42 | +// And the stderr should be empty because rustc/rustdoc should've gotten killed. |
| 43 | +assert!(stderr.is_empty(),"{bin:?} stderr:\n{}", stderr); |
| 44 | +} |
| 45 | + |
| 46 | +#[cfg(windows)] |
| 47 | +{ |
| 48 | +match bin { |
| 49 | +// On Windows, rustc has a paper that propagates the panic exit code of 101 but converts |
| 50 | +// broken pipe errors into fatal errors instead of ICEs. |
| 51 | +Binary::Rustc => { |
| 52 | +assert_eq!(status.code(),Some(PANIC_ICE_EXIT_CODE),"{bin:?}"); |
| 53 | +// But make sure it doesn't manifest as an ICE. |
| 54 | +assert!(!stderr.contains("internal compiler error"),"{bin:?} ICE'd"); |
| 55 | +} |
| 56 | +// On Windows, rustdoc seems to cleanly exit with exit code of 1. |
| 57 | +Binary::Rustdoc => { |
| 58 | +assert_eq!(status.code(),Some(1),"{bin:?}"); |
| 59 | +assert!(!stderr.contains("panic"),"{bin:?} stderr contains panic"); |
| 60 | +} |
| 61 | +} |
| 62 | +} |
| 63 | +} |
| 64 | + |
| 65 | +fnmain(){ |
| 66 | +letmut rustc = Command::new(env_var("RUSTC")); |
| 67 | + rustc.arg("--print=sysroot"); |
| 68 | +check_broken_pipe_handled_gracefully(Binary::Rustc, rustc); |
| 69 | + |
| 70 | +letmut rustdoc = Command::new(env_var("RUSTDOC")); |
| 71 | + rustdoc.arg("--version"); |
| 72 | +check_broken_pipe_handled_gracefully(Binary::Rustdoc, rustdoc); |
| 73 | +} |
0 commit comments