Skip to content

ExitStatus Debug instance is misleading #74832

Closed
@infinity0

Description

@infinity0

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    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