From 47030d300a7f3fe40fbab3454d298354c863fa10 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Fri, 8 Apr 2022 13:39:24 -0700 Subject: [PATCH 1/3] std: `::fmt` name the signal it died from --- .../std/src/sys/unix/process/process_unix.rs | 63 +++++++++++++++++++ .../sys/unix/process/process_unix/tests.rs | 6 +- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 3d305cd7310fd..188e356a8b4e0 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -695,17 +695,80 @@ impl From for ExitStatus { } } +/// Convert a signal number to a readable, searchable name. +fn signal_string(signal: i32) -> String { + (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", + #[cfg(target_os = "linux")] + 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", + _ => return format!("{signal}"), + }) + .to_string() +} + 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 = signal_string(signal); if self.core_dumped() { write!(f, "signal: {signal} (core dumped)") } else { write!(f, "signal: {signal}") } } else if let Some(signal) = self.stopped_signal() { + let signal = signal_string(signal); write!(f, "stopped (not terminated) by signal: {signal}") } else if self.continued() { write!(f, "continued (WIFCONTINUED)") 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..8d4f6b5179e9e 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: SIGTERM"); + t(0x0008b, "signal: 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: SIGSTOP"); t(0x0ffff, "continued (WIFCONTINUED)"); } From 267a6c815663582e651b32dcd33c07da05cd3371 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 1 Jun 2022 11:20:11 -0700 Subject: [PATCH 2/3] std: show signal number along with name --- .../std/src/sys/unix/process/process_unix.rs | 90 ++++++++++--------- .../sys/unix/process/process_unix/tests.rs | 6 +- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 188e356a8b4e0..31f1ea76701e3 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -696,41 +696,46 @@ impl From for ExitStatus { } /// Convert a signal number to a readable, searchable name. -fn signal_string(signal: i32) -> String { - (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", +/// +/// 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)", #[cfg(target_os = "linux")] - libc::SIGSTKFLT => "SIGSTKFLT", + libc::SIGSTKFLT => " (SIGSTKFLT)", #[cfg(target_os = "linux")] - libc::SIGPWR => "SIGPWR", + libc::SIGPWR => " (SIGPWR)", #[cfg(any( target_os = "macos", target_os = "ios", @@ -740,7 +745,7 @@ fn signal_string(signal: i32) -> String { target_os = "openbsd", target_os = "dragonfly" ))] - libc::SIGEMT => "SIGEMT", + libc::SIGEMT => " (SIGEMT)", #[cfg(any( target_os = "macos", target_os = "ios", @@ -750,10 +755,9 @@ fn signal_string(signal: i32) -> String { target_os = "openbsd", target_os = "dragonfly" ))] - libc::SIGINFO => "SIGINFO", - _ => return format!("{signal}"), - }) - .to_string() + libc::SIGINFO => " (SIGINFO)", + _ => "", + } } impl fmt::Display for ExitStatus { @@ -761,15 +765,15 @@ impl fmt::Display for ExitStatus { if let Some(code) = self.code() { write!(f, "exit status: {code}") } else if let Some(signal) = self.signal() { - let signal = signal_string(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() { - let signal = signal_string(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 8d4f6b5179e9e..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: SIGTERM"); - t(0x0008b, "signal: SIGSEGV (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: SIGSTOP"); + t(0x0137f, "stopped (not terminated) by signal: 19 (SIGSTOP)"); t(0x0ffff, "continued (WIFCONTINUED)"); } From 22791bbccd6dd8c1c3981fc9cb662774f2117d3b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 2 Jun 2022 15:18:16 -0700 Subject: [PATCH 3/3] Fix MIPS-specific signal bug --- library/std/src/sys/unix/process/process_unix.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 31f1ea76701e3..5aae924029915 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -732,7 +732,16 @@ fn signal_string(signal: i32) -> &'static str { libc::SIGWINCH => " (SIGWINCH)", libc::SIGIO => " (SIGIO)", libc::SIGSYS => " (SIGSYS)", - #[cfg(target_os = "linux")] + // 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)",