Skip to content

[crash] Rust doesn't handle io:Error on command spawning #116897

@DmitryAstafyev

Description

@DmitryAstafyev

Code

I tried this code (repo):

use std::{io, process::Command, str::from_utf8};

fn spawn() -> Result<(String, String), io::Error> {
    let output = Command::new("bash")
        .args(vec!["-i", "-l", "-c", "printenv"])
        .output()?;
    let stdout = from_utf8(&output.stdout)
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
    let stderr = from_utf8(&output.stderr)
        .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?;
    Ok((stdout.to_owned(), stderr.to_owned()))
}

pub fn runner() {
    match spawn() {
        Ok((_stdout, stderr)) => {
            // println!("stdout: {stdout}");
            println!("stderr: {stderr}");
        }
        Err(e) => {
            eprintln!("Failed with: {e}");
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test() -> () {
        let mut i = 0;
        while i <= 10 {
            println!("Run #{i}");
            runner();
            i += 1;
        }
    }
}
[package]
name = "spawn_interective_cmd"
version = "0.1.0"
edition = "2021"

[lib]
name = "test"
path = "src/lib.rs"

[dependencies]

Explanation of issue

With

cargo test -- --nocapture

I'm expecting to see 10 iterations of the spawning command bash -i -l -c printenv but it does only 2 iterations and exits without any errors.

Output

> cargo test -- --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/envvars-4c1bc63551fc4ded)

running 1 test
Run #0
stderr: 
Run #1
fish: Job 6, 'cargo test -- --nocapture' has stopped

We can see only 2 iterations and after - exit.

At the same time if you run test "from" vscode with link "Run test",

Screenshot from 2023-10-18 18-40-44

output in console is correct:

 *  Executing task: cargo test --package spawn_interective_cmd --lib -- tests::test --exact --nocapture 

    Finished test [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/lib.rs (target/debug/deps/envvars-4c1bc63551fc4ded)

running 1 test
Run #0
stderr: 
Run #1
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #2
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #3
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #4
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #5
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #6
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #7
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #8
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #9
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

Run #10
stderr: bash: initialize_job_control: no job control in background: Bad file descriptor

test tests::test ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.21s

 *  Terminal will be reused by tasks, press any key to close it. 

We can see, starting from the second attempt to spawn the same command, there is an error:

bash: initialize_job_control: no job control in background: Bad file descriptor

The problem is, that this error isn't handled correctly if you running tests directly (not from vscode) in the context of the terminal.

Expectation

  • Rust should not exit/stops/crash(?) on such kind of error and should handle it as well.
  • At least rust should give some error traces

Important

  • An issue related to arg -i (interactive mode for shell)... if do not use this argument - everything is okay

Addition

  • No logs/traces in the terminal
  • No backtrace even with RUST_BACKTRACE=1
  • No related logs/traces in journalctl
  • Repo with this example - link

Meta

>rustc --version --verbose
rustc 1.73.0 (cc66ad468 2023-10-03)
binary: rustc
commit-hash: cc66ad468955717ab92600c770da8c1601a4ff33
commit-date: 2023-10-03
host: x86_64-unknown-linux-gnu
release: 1.73.0
LLVM version: 17.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`C-bugCategory: This is a bug.T-libsRelevant to the library 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