diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 3d305cd7310fd..5aae924029915 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -695,18 +695,94 @@ impl From for ExitStatus { } } +/// Convert a signal number to a readable, searchable name. +/// +/// This string should be displayed right after the signal number. +/// If a signal is unrecognized, it returns the empty string, so that +/// you just get the number like "0". If it is recognized, you'll get +/// something like "9 (SIGKILL)". +fn signal_string(signal: i32) -> &'static str { + match signal { + libc::SIGHUP => " (SIGHUP)", + libc::SIGINT => " (SIGINT)", + libc::SIGQUIT => " (SIGQUIT)", + libc::SIGILL => " (SIGILL)", + libc::SIGTRAP => " (SIGTRAP)", + libc::SIGABRT => " (SIGABRT)", + libc::SIGBUS => " (SIGBUS)", + libc::SIGFPE => " (SIGFPE)", + libc::SIGKILL => " (SIGKILL)", + libc::SIGUSR1 => " (SIGUSR1)", + libc::SIGSEGV => " (SIGSEGV)", + libc::SIGUSR2 => " (SIGUSR2)", + libc::SIGPIPE => " (SIGPIPE)", + libc::SIGALRM => " (SIGALRM)", + libc::SIGTERM => " (SIGTERM)", + libc::SIGCHLD => " (SIGCHLD)", + libc::SIGCONT => " (SIGCONT)", + libc::SIGSTOP => " (SIGSTOP)", + libc::SIGTSTP => " (SIGTSTP)", + libc::SIGTTIN => " (SIGTTIN)", + libc::SIGTTOU => " (SIGTTOU)", + libc::SIGURG => " (SIGURG)", + libc::SIGXCPU => " (SIGXCPU)", + libc::SIGXFSZ => " (SIGXFSZ)", + libc::SIGVTALRM => " (SIGVTALRM)", + libc::SIGPROF => " (SIGPROF)", + libc::SIGWINCH => " (SIGWINCH)", + libc::SIGIO => " (SIGIO)", + libc::SIGSYS => " (SIGSYS)", + // For information on Linux signals, run `man 7 signal` + #[cfg(all( + target_os = "linux", + any( + target_arch = "x86_64", + target_arch = "x86", + target_arch = "arm", + target_arch = "aarch64" + ) + ))] + libc::SIGSTKFLT => " (SIGSTKFLT)", + #[cfg(target_os = "linux")] + libc::SIGPWR => " (SIGPWR)", + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "dragonfly" + ))] + libc::SIGEMT => " (SIGEMT)", + #[cfg(any( + target_os = "macos", + target_os = "ios", + target_os = "tvos", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "dragonfly" + ))] + libc::SIGINFO => " (SIGINFO)", + _ => "", + } +} + impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if let Some(code) = self.code() { write!(f, "exit status: {code}") } else if let Some(signal) = self.signal() { + let signal_string = signal_string(signal); if self.core_dumped() { - write!(f, "signal: {signal} (core dumped)") + write!(f, "signal: {signal}{signal_string} (core dumped)") } else { - write!(f, "signal: {signal}") + write!(f, "signal: {signal}{signal_string}") } } else if let Some(signal) = self.stopped_signal() { - write!(f, "stopped (not terminated) by signal: {signal}") + let signal_string = signal_string(signal); + write!(f, "stopped (not terminated) by signal: {signal}{signal_string}") } else if self.continued() { write!(f, "continued (WIFCONTINUED)") } else { diff --git a/library/std/src/sys/unix/process/process_unix/tests.rs b/library/std/src/sys/unix/process/process_unix/tests.rs index 560c62155d931..e0e2d478fad73 100644 --- a/library/std/src/sys/unix/process/process_unix/tests.rs +++ b/library/std/src/sys/unix/process/process_unix/tests.rs @@ -14,8 +14,8 @@ fn exitstatus_display_tests() { let t = |v, s| assert_eq!(s, format!("{}", ::from_raw(v))); - t(0x0000f, "signal: 15"); - t(0x0008b, "signal: 11 (core dumped)"); + t(0x0000f, "signal: 15 (SIGTERM)"); + t(0x0008b, "signal: 11 (SIGSEGV) (core dumped)"); t(0x00000, "exit status: 0"); t(0x0ff00, "exit status: 255"); @@ -24,7 +24,7 @@ fn exitstatus_display_tests() { // The purpose of this test is to test our string formatting, not our understanding of the wait // status magic numbers. So restrict these to Linux. if cfg!(target_os = "linux") { - t(0x0137f, "stopped (not terminated) by signal: 19"); + t(0x0137f, "stopped (not terminated) by signal: 19 (SIGSTOP)"); t(0x0ffff, "continued (WIFCONTINUED)"); }