diff --git a/src/uucore/src/lib/lib.rs b/src/uucore/src/lib/lib.rs index a636fcdab..6142e688d 100644 --- a/src/uucore/src/lib/lib.rs +++ b/src/uucore/src/lib/lib.rs @@ -4,6 +4,8 @@ // file that was distributed with this source code. //! library ~ (core/bundler file) // #![deny(missing_docs)] //TODO: enable this +// +// spell-checker:ignore sigaction SIGBUS SIGSEGV // * feature-gated external crates (re-shared as public internal modules) #[cfg(feature = "libc")] @@ -100,6 +102,12 @@ pub use crate::features::fsxattr; //## core functions +#[cfg(unix)] +use nix::errno::Errno; +#[cfg(unix)] +use nix::sys::signal::{ + sigaction, SaFlags, SigAction, SigHandler::SigDfl, SigSet, Signal::SIGBUS, Signal::SIGSEGV, +}; use std::borrow::Cow; use std::ffi::OsStr; use std::ffi::OsString; @@ -112,6 +120,25 @@ use std::sync::atomic::Ordering; use once_cell::sync::Lazy; +/// Disables the custom signal handlers installed by Rust for stack-overflow handling. With those custom signal handlers processes ignore the first SIGBUS and SIGSEGV signal they receive. +/// See for details. +#[cfg(unix)] +pub fn disable_rust_signal_handlers() -> Result<(), Errno> { + unsafe { + sigaction( + SIGSEGV, + &SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()), + ) + }?; + unsafe { + sigaction( + SIGBUS, + &SigAction::new(SigDfl, SaFlags::empty(), SigSet::all()), + ) + }?; + Ok(()) +} + /// Execute utility code for `util`. /// /// This macro expands to a main function that invokes the `uumain` function in `util` diff --git a/src/uucore_procs/src/lib.rs b/src/uucore_procs/src/lib.rs index 11d89c97e..650417104 100644 --- a/src/uucore_procs/src/lib.rs +++ b/src/uucore_procs/src/lib.rs @@ -3,7 +3,7 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. // -// spell-checker:ignore backticks uuhelp +// spell-checker:ignore backticks uuhelp SIGSEGV //! A collection of procedural macros for uutils. #![deny(missing_docs)] @@ -25,6 +25,10 @@ pub fn main(_args: TokenStream, stream: TokenStream) -> TokenStream { let new = quote!( pub fn uumain(args: impl uucore::Args) -> i32 { #stream + + // disable rust signal handlers (otherwise processes don't dump core after e.g. one SIGSEGV) + #[cfg(unix)] + uucore::disable_rust_signal_handlers().expect("Disabling rust signal handlers failed"); let result = uumain(args); match result { Ok(()) => uucore::error::get_exit_code(),