Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE on "rustc --help | false" #34376

Closed
est31 opened this issue Jun 20, 2016 · 11 comments
Closed

ICE on "rustc --help | false" #34376

est31 opened this issue Jun 20, 2016 · 11 comments
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@est31
Copy link
Member

est31 commented Jun 20, 2016

Minimal steps to reproduce: rustc --help | false.

Yields an ICE. Tested in latest nightly (2016-06-15) as well as on latest stable(1.9.0).

@est31 est31 changed the title ICE on --help if pipe partner exits with non zero exit status ICE on "rustc --help | false" Jun 20, 2016
@est31
Copy link
Member Author

est31 commented Jun 20, 2016

Yields an ICE when you pipe with true as well, or with echo.

@retep998
Copy link
Member

Cannot replicate on Windows inside Powershell.

@nagisa
Copy link
Member

nagisa commented Jun 20, 2016

Yes, this ICE happens always when the pipe for output is broken. You can reproduce this by piping rustc output to whatever command which exits before consuming all of the rustc’s output. For example: rustc | grep --help, rustc | cat /dev/null et cetera.

@nagisa
Copy link
Member

nagisa commented Jun 20, 2016

Backtrace:

error: internal compiler error: unexpected panic
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
note: run with `RUST_BACKTRACE=1` for a backtrace
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', ../src/libstd/io/stdio.rs:617
stack backtrace:
   1:     0x7f973012861f - std::sys::backtrace::tracing::imp::write::h6528da8103c51ab9
   2:     0x7f973013629b - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::hbe741a5cc3c49508
   3:     0x7f9730135ecf - std::panicking::default_hook::he0146e6a74621cb4
   4:     0x7f97300fc16e - std::panicking::rust_panic_with_hook::h983af77c1a2e581b
   5:     0x7f97301364e1 - std::panicking::begin_panic::he426e15a3766089a
   6:     0x7f97300fe1ca - std::panicking::begin_panic_fmt::hdddb415186c241e7
   7:     0x7f973010ad7b - std::io::stdio::_print::h4cd911b6be2080b8
   8:     0x7f973060cbd0 - rustc_driver::run::h2fcb030617c036bd
   9:     0x7f9730647ef9 - rustc_driver::main::h01ed9408eefe73b5
  10:     0x7f9730135828 - std::panicking::try::call::h852b0d5f2eec25e4
  11:     0x7f973014475b - __rust_try
  12:     0x7f97301446fe - __rust_maybe_catch_panic
  13:     0x7f97301352ce - std::rt::lang_start::hfe4efe1fc39e4a30
  14:     0x7f972fcbc740 - __libc_start_main
  15:     0x55ccd21ed798 - <unknown>

@pnkfelix
Copy link
Member

I wonder if there is overlap between this and #14505 (which was closed because the problem stopped occurring for rustc --version, but I'm not exactly clear on why the problem there stopped happening).

@steveklabnik steveklabnik added the A-frontend Area: frontend (errors, parsing and HIR) label Jun 20, 2016
@phiresky
Copy link

phiresky commented Dec 6, 2016

Same thing happened for me when I tried to pipe the AST into something that failed

rustc -Z ast-json-noexpand test.rs|jq|wc -l

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', ../src/libstd/io/stdio.rs:661

@steveklabnik steveklabnik added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Dec 15, 2016
@Mark-Simulacrum
Copy link
Member

Copying from #36415.

So investigating this leads me to believe that we're handling something incorrectly here:

panic!("failed printing to {}: {}", label, e);
. The panic! seems to still be called despite the error being IO-related:

$ rustc -vV | test
error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

thread 'rustc' panicked at 'failed printing to stdout: Broken pipe (os error 32)', src/libstd/io/stdio.rs:691
note: Run with `RUST_BACKTRACE=1` for a backtrace.

@zackmdavis
Copy link
Member

This gets reported sufficiently often (q.v. #38396, #36415, #44492, #45705, #47985, #48916) that we should probably just fix it. Is there a specific reason to care that print_to panics when given an unusable stream? (Recursive blame dates back to 2015.)

@est31
Copy link
Member Author

est31 commented Mar 11, 2018

Another option would be to remove the "we would appreciate a bug report" line if the behaviour is intended.

@cperepelitsa
Copy link

cperepelitsa commented Apr 1, 2018

Simply terminating successfully (exit(0)) would be the most appropriate, because this is the expectation when using a UNIX pipe when the second program fails or does not exist:

$ cat /dev/null | false
$ echo ${PIPESTATUS[*]}
0 1
$ cat /dev/null | does-not-exist
bash: does-not-exist: command not found
$ echo ${PIPESTATUS[*]}
0 127

In both cases, cat simply calls exit(0) and produces no error output about a broken pipe.

This is a common issue when writing shell utilities that produce output the user might pipe to a program that does not read all of the output, e.g. head, which can sometimes cause this exception. If the broken pipe exception is not caught and handled, the usual result is an ugly stack trace and non-zero exit for what is actually correct and expected behavior. (Try searching for e.g. "python head broken pipe".)
The convention is to simply exit, under the assumption that the other end of the pipe didn't need any more input.
rustc should follow this convention.
(I just ran into this crash trying to pipe the output of rust --explain to les, when I meant less.)

kennytm added a commit to kennytm/rust that referenced this issue Apr 16, 2018
Prevent broken pipes causing ICEs

As the private `std::io::print_to` panics if there is an I/O error, which is used by `println!`, the compiler would ICE if one attempted to use a broken pipe (e.g. `rustc --help | false`). This introduces a new (private) macro `try_println!` which allows us to avoid this.

As a side note, it seems this macro might be useful publicly (and actually there seems to be [a crate specifically for this purpose](https://crates.io/crates/try_print/)), though that can probably be left for a future discussion.

One slight alternative approach would be to simply early exit without an error (i.e. exit code `0`), which [this comment](rust-lang#34376 (comment)) suggests is the usual approach. I've opted not to take that approach initially, because I think it's more helpful to know when there is a broken pipe.

Fixes rust-lang#34376.
@est31
Copy link
Member Author

est31 commented Apr 16, 2018

Thank you @varkor for fixing this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-frontend Area: frontend (errors, parsing and HIR) C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

9 participants