Skip to content

panic! in Command child forked from non-main thread results in exit status 0 #79740

Closed
@ijackson

Description

@ijackson

If a panic occurs in a child process forked off by Command on a thread other than the main thread, the whole child process exits 0, so it looks like things have worked when in fact they've gone catastrophically wrong. This seems like a serious error handling bug.

@rustbot modify labels +T-libs +libs-impl

Steps to reproduce

use std::io;
use std::process::Command;
use std::os::unix::process::CommandExt;
use std::thread;

fn main() -> Result<(),io::Error> {
    let thr = thread::spawn(||{
        let mut c = Command::new("echo");
        c.arg("hi");
        unsafe {
            c.pre_exec(|| panic!("crash now!"));
        }
        let st = c.status().expect("get status");
        println!("{:?}", st);
    });
    thr.join().expect("joined");
    Ok(())
}

Actual behaviour

thread '<unnamed>' panicked at 'crash now!', t.rs:11:27
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
ExitStatus(ExitStatus(0))

Expected behaviour

  • The spawned thread builds the Command.
  • Command.status tries to run the command, so
  • Command.status forks, and then runs the pre_exec closure
  • The pre_exec closure panics
  • Consequently, the child process exits with SIGABRT or in any case nonzero
  • st is not a success

Specifically, the last line should be something like ExitStatus(ExitStatus(25856)) (which is what you get without the thread::spawn)

Meta

rustc --version --verbose:

rustc 1.50.0-nightly (3ff10e74a 2020-12-04)
binary: rustc
commit-hash: 3ff10e74a74ed093fcabac1de27fe1cd65bbbb4a
commit-date: 2020-12-04
host: x86_64-unknown-linux-gnu
release: 1.50.0-nightly
Backtrace (not particularly enlightening)

``` thread '' panicked at 'crash now!', t.rs:11:27 stack backtrace: 0: std::panicking::begin_panic 1: t::main::{{closure}}::{{closure}} 2: as core::ops::function::FnMut>::call_mut at /rustc/1773f60ea5d42e86b8fdf78d2fc5221ead222bc1/library/alloc/src/boxed.rs:1314:9 3: std::sys::unix::process::process_inner::::do_exec at /rustc/1773f60ea5d42e86b8fdf78d2fc5221ead222bc1/library/std/src/sys/unix/process/process_unix.rs:228:13 4: std::sys::unix::process::process_inner::::spawn at /rustc/1773f60ea5d42e86b8fdf78d2fc5221ead222bc1/library/std/src/sys/unix/process/process_unix.rs:58:36 5: std::process::Command::status at /rustc/1773f60ea5d42e86b8fdf78d2fc5221ead222bc1/library/std/src/process.rs:904:9 6: t::main::{{closure}} note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace. ExitStatus(ExitStatus(0))


</p>
</details>

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-runtimeArea: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflowsC-bugCategory: This is a bug.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions