Skip to content

Don't panic on broken pipes when built without termcolor #221

@oherrala

Description

@oherrala

Depending on if termcolor crate is used or not env_logger's behavior on closed stderr (or stdout) is different. When using termcolor and the output is closed the process just hangs. When not using termcolor a panic occurs because of broken pipe and process is terminated.

I'm not sure how this case should work. Hanging indefinitely is bad and might lead to hard to debug issues. But to panic without possibility to recover is also bad.

An example for reproducing and testing (tested on macOS 11.6):

Cargo.toml:

[package]
name = "envltest"
version = "0.1.0"
edition = "2021"

[features]
termcolor = [ "env_logger/termcolor" ]

[dependencies]
env_logger = { version = "0.9", default_features = false }
log = "0.4"

main.rs:

fn main() {
    env_logger::builder()
        // This is to not hide error messages on stderr
        .target(env_logger::Target::Stdout)
        .init();

    for i in 0.. {
        log::info!("{}", i);
        std::thread::sleep(std::time::Duration::from_secs(1));
    }
}

When env_logger is build with no default features (as seen in Cargo.toml) the process is terminated as soon as stdout is closed (head -n3 takes three lines and closes stdout):

% cargo build && RUST_LOG=info /tmp/rust/target/debug/envltest | head -n3                     
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
[INFO  envltest] 0
[INFO  envltest] 1
[INFO  envltest] 2
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1193:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

however, when compiled with termcolor crate the process just hangs until the process is terminated manually:

% cargo build --features termcolor && RUST_LOG=info /tmp/rust/target/debug/envltest | head -n3
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
[INFO  envltest] 0
[INFO  envltest] 1
[INFO  envltest] 2
^C

Backtrace of broken pipe:

thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1193:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:517:5
   1: std::panicking::begin_panic_fmt
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/panicking.rs:460:5
   2: std::io::stdio::print_to
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/io/stdio.rs:1193:9
   3: std::io::stdio::_print
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/io/stdio.rs:1205:5
   4: env_logger::fmt::writer::termcolor::imp::BufferWriter::print
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/fmt/writer/termcolor/shim_impl.rs:47:39
   5: env_logger::fmt::writer::Writer::print
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/fmt/writer/mod.rs:120:9
   6: env_logger::fmt::Formatter::print
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/fmt/mod.rs:115:9
   7: <env_logger::Logger as log::Log>::log::{{closure}}::{{closure}}
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/lib.rs:928:67
   8: core::result::Result<T,E>::and_then
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/result.rs:966:22
   9: <env_logger::Logger as log::Log>::log::{{closure}}
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/lib.rs:928:21
  10: <env_logger::Logger as log::Log>::log::{{closure}}
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/lib.rs:947:33
  11: std::thread::local::LocalKey<T>::try_with
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/std/src/thread/local.rs:399:16
  12: <env_logger::Logger as log::Log>::log
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/env_logger-0.9.0/src/lib.rs:934:27
  13: log::__private_api_log
             at /Users/oherrala/.cargo/registry/src/github.com-1ecc6299db9ec823/log-0.4.14/src/lib.rs:1460:5
  14: envltest::main
             at ./src/main.rs:7:9
  15: core::ops::function::FnOnce::call_once
             at /rustc/09c42c45858d5f3aedfa670698275303a3d19afa/library/core/src/ops/function.rs:227:5

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions