Closed
Description
On UNIX, c_int
is an alias for i32
or i16
depending on the platform. ExitStatus
is a wrapper around c_int
. However its Debug instance only exposes the last few bits:
test.c
#include <stdio.h>
void main() {
printf("%s\n", (void*)123);
}
running:
$ gcc test.c && ./a.out
Segmentation fault
exit code 139
test.rs
use std::process::Command;
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct X(i16);
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub struct XX(X);
pub fn main() {
let e = Command::new("./a.out").status().unwrap();
let i = XX(X(139));
println!("exit with {:?}", e);
println!("exit with {}", e);
println!("test reproduce {:?}", i);
}
running:
$ rustc test.rs && ./test
exit with ExitStatus(ExitStatus(11))
exit with signal: 11
test reproduce XX(X(139))
The Debug output makes it look like a regular exit, not a signal exit. This is relevant because this is what rustbuild's rustc wrapper does in src/bootstrap/bin/rustc.rs
, making rustc builds harder to debug.
As you can see I tried to recreate the weirdness with XX
which as far as I can tell, follows the structure of how ExitStatus
is defined. However I didn't recreate the platform-dependent logic in libstd/sys/mod.rs which also includes missing_debug_implementations
which might be interfering with the derivation logic.