Do not panic in Termination impl on closed stderr
Repro:
#![feature(backtrace)]
use std::backtrace::Backtrace;
use std::io::{self, Write as _};
use std::panic::{self, PanicInfo};
#[derive(Debug)]
pub struct Error;
fn panic_hook(panic_info: &PanicInfo) {
let backtrace = Backtrace::force_capture();
let _ = write!(io::stdout(), "{}\n{}", panic_info, backtrace);
}
fn main() -> Result<(), Error> {
panic::set_hook(Box::new(panic_hook));
let stderr = io::stderr();
let mut stderr = stderr.lock();
while stderr.write_all(b".\n").is_ok() {}
Err(Error)
}
Before:
$ RUST_BACKTRACE=1 target/debug/testing 3>&2 2>&1 1>&3 | head
.
.
.
.
.
.
.
.
.
.
panicked at 'failed printing to stderr: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9
0: testing::panic_hook
at ./src/main.rs:11:21
1: core::ops::function::Fn::call
at /git/rust/library/core/src/ops/function.rs:77:5
2: std::panicking::rust_panic_with_hook
3: std::panicking::begin_panic_handler::{{closure}}
4: std::sys_common::backtrace::__rust_end_short_backtrace
5: rust_begin_unwind
6: core::panicking::panic_fmt
7: std::io::stdio::_eprint
8: <core::result::Result<!,E> as std::process::Termination>::report
at /git/rust/library/std/src/process.rs:2164:9
9: <core::result::Result<(),E> as std::process::Termination>::report
at /git/rust/library/std/src/process.rs:2148:25
10: std::rt::lang_start::{{closure}}
at /git/rust/library/std/src/rt.rs:145:18
11: std::rt::lang_start_internal
12: std::rt::lang_start
at /git/rust/library/std/src/rt.rs:144:17
13: main
14: __libc_start_main
at /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
15: _start
After:
$ RUST_BACKTRACE=1 target/debug/testing 3>&2 2>&1 1>&3 | head
.
.
.
.
.
.
.
.
.
.