I tried this:
$ rm -f /tmp/empty
$ touch /tmp/empty
$ chmod 0555 /tmp/empty
$ cargo new --bin hello
$ cd hello
$ $EDITOR src/main.rs
$ cat src/main.rs
use std::process::Command;
fn main() {
_ = dbg!(Command::new("/tmp/empty").status());
}
$ ldd --version | head -n1
ldd (Ubuntu GLIBC 2.31-0ubuntu9.17) 2.31
$ cargo run
[src/main.rs:3:9] Command::new("/tmp/empty").status() = Err(
Os {
code: 8,
kind: Uncategorized,
message: "Exec format error",
},
)
$ ldd --version | head -n1
ldd (GNU libc) 2.17
$ cargo run
[src/main.rs:3:9] Command::new("/tmp/empty").status() = Ok(
ExitStatus(
unix_wait_status(
0,
),
),
)
I expected to see this happen: the same behavior regardless of the glibc version.
Instead, this happened: whether you get an error or success depends on the system libc version
Meta
rustc --version --verbose:
binary: rustc
commit-hash: 12c36e2539c54397c51d6ea4401defd8768a4f5b
commit-date: 2026-08-10
host: x86_64-unknown-linux-gnu
release: 1.99.0-nightly
LLVM version: 23.1.0
Investigation
AFAICT, the difference is due to Command::spawn using libc::posix_spawn on GLIBC 2.24 and newer; and execvp older GLIBC versions 1. the posix_spawn logic produces the Err outcome; the execvp logic produces the Ok outcome
patching libstd to never take the posix_spawn lets me reproduce the Ok outcome on Ubuntu 22.04 (glibc 2.35)
I tried this:
I expected to see this happen: the same behavior regardless of the glibc version.
Instead, this happened: whether you get an error or success depends on the system libc version
Meta
rustc --version --verbose:Investigation
AFAICT, the difference is due to
Command::spawnusinglibc::posix_spawnon GLIBC 2.24 and newer; andexecvpolder GLIBC versions 1. theposix_spawnlogic produces theErroutcome; theexecvplogic produces theOkoutcomepatching
libstdto never take theposix_spawnlets me reproduce theOkoutcome on Ubuntu 22.04 (glibc 2.35)