pub fn enable_sigbus_sigsegv_backtraces() -> Result<(), anyhow::Error> {
    // This code is derived from the code in the backtrace-on-stack-overflow
    // crate, which is freely available under the terms of the Apache 2.0
    // license. The modifications here provide better error messages if any of
    // the various system calls fail.
    //
    // See: https://github.com/matklad/backtrace-on-stack-overflow

    // NOTE(benesch): The stack size was chosen to match the default Rust thread
    // stack size of 2MiB. Probably overkill, but we'd much rather have
    // backtraces on stack overflow than squabble over a few megabytes. Using
    // libc::SIGSTKSZ is tempting, but its default of 8KiB on my system makes me
    // nervous. Rust code isn't used to running with a stack that small.
    const STACK_SIZE: usize = 2 << 20;

    // x86_64 and aarch64 require 16-byte alignment. Its hard to imagine other
    // platforms that would have more stringent requirements.
    const STACK_ALIGN: usize = 16;

    // Allocate a stack.
    let buf_layout =
        Layout::from_size_align(STACK_SIZE, STACK_ALIGN).expect("layout known to be valid");
    // SAFETY: layout has non-zero size and the uninitialized memory that is
    // returned is never read (at least, not by Rust).
    let buf = unsafe { alloc::alloc(buf_layout) };

    // Request that signals be delivered to this alternate stack.
    let stack = libc::stack_t {
        ss_sp: buf as *mut libc::c_void,
        ss_flags: 0,
        ss_size: STACK_SIZE,
    };
    // SAFETY: `stack` is a valid pointer to a `stack_t` object and the second
    // parameter, `old_ss`, is permitted to be `NULL` according to POSIX.
    let ret = unsafe { libc::sigaltstack(&stack, ptr::null_mut()) };
    if ret == -1 {
        let errno = errno::from_i32(errno::errno());
        bail!("failed to configure alternate signal stack: {}", errno);
    }

    // Install a handler for SIGSEGV.
    let action = signal::SigAction::new(
        signal::SigHandler::Handler(handle_sigbus_sigsegv),
        signal::SaFlags::SA_NODEFER | signal::SaFlags::SA_ONSTACK,
        signal::SigSet::empty(),
    );
    // SAFETY: see `handle_sigbus_sigsegv`.
    unsafe { signal::sigaction(signal::SIGBUS, &action) }
        .context("failed to install SIGBUS handler")?;
    unsafe { signal::sigaction(signal::SIGSEGV, &action) }
        .context("failed to install SIGSEGV handler")?;
    Ok(())
}
/// Attempts to enable backtraces when SIGBUS or SIGSEGV occurs.
///
/// In particular, this means producing backtraces on stack overflow, as stack
/// overflow raises SIGBUS or SIGSEGV via guard pages. The approach here
/// involves making system calls to handle SIGBUS/SIGSEGV on an alternate signal
/// stack, which seems to work well in practice but may technically be undefined
/// behavior.
///
/// Rust may someday do this by default. Follow:
/// https://github.com/rust-lang/rust/issues/51405.
Attempts to enable backtraces when SIGBUS or SIGSEGV occurs.
In particular, this means producing backtraces on stack overflow, as stack
overflow raises SIGBUS or SIGSEGV via guard pages. The approach here
involves making system calls to handle SIGBUS/SIGSEGV on an alternate signal
stack, which seems to work well in practice but may technically be undefined
behavior.

Rust may someday do this by default.
Attempts to enable backtraces when SIGBUS or SIGSEGV occurs . In particular this means producing backtraces on stack overflow as stack overflow raises SIGBUS or SIGSEGV via guard pages . The approach here involves making system calls to handle SIGBUS / SIGSEGV on an alternate signal stack which seems to work well in practice but may technically be undefined behavior . Rust may someday do this by default .
pub fn enable_sigbus_sigsegv_backtraces() -> Result<(), anyhow::Error> {
    // This code is derived from the code in the backtrace-on-stack-overflow
    // crate, which is freely available under the terms of the Apache 2.0
    // license. The modifications here provide better error messages if any of
    // the various system calls fail.
    //
    // See: https://github.com/matklad/backtrace-on-stack-overflow
    // NOTE(benesch): The stack size was chosen to match the default Rust thread
    // stack size of 2MiB. Probably overkill, but we'd much rather have
    // backtraces on stack overflow than squabble over a few megabytes. Using
    // libc::SIGSTKSZ is tempting, but its default of 8KiB on my system makes me
    // nervous. Rust code isn't used to running with a stack that small.
    const STACK_SIZE: usize = 2 << 20;
    // x86_64 and aarch64 require 16-byte alignment. Its hard to imagine other
    // platforms that would have more stringent requirements.
    const STACK_ALIGN: usize = 16;
    // Allocate a stack.
    let buf_layout =
        Layout::from_size_align(STACK_SIZE, STACK_ALIGN).expect("layout known to be valid");
    // SAFETY: layout has non-zero size and the uninitialized memory that is
    // returned is never read (at least, not by Rust).
    let buf = unsafe { alloc::alloc(buf_layout) };
    // Request that signals be delivered to this alternate stack.
    let stack = libc::stack_t {
        ss_sp: buf as *mut libc::c_void,
        ss_flags: 0,
        ss_size: STACK_SIZE,
    };
    // SAFETY: `stack` is a valid pointer to a `stack_t` object and the second
    // parameter, `old_ss`, is permitted to be `NULL` according to POSIX.
    let ret = unsafe { libc::sigaltstack(&stack, ptr::null_mut()) };
    if ret == -1 {
        let errno = errno::from_i32(errno::errno());
        bail!("failed to configure alternate signal stack: {}", errno);
    }
    // Install a handler for SIGSEGV.
    let action = signal::SigAction::new(
        signal::SigHandler::Handler(handle_sigbus_sigsegv),
        signal::SaFlags::SA_NODEFER | signal::SaFlags::SA_ONSTACK,
        signal::SigSet::empty(),
    );
    // SAFETY: see `handle_sigbus_sigsegv`.
    unsafe { signal::sigaction(signal::SIGBUS, &action) }
        .context("failed to install SIGBUS handler")?;
    unsafe { signal::sigaction(signal::SIGSEGV, &action) }
        .context("failed to install SIGSEGV handler")?;
    Ok(())
}
pub fn enable_sigbus_sigsegv_backtraces ( ) -> Result < ( ) , anyhow :: Error > { // This code is derived from the code in the backtrace-on-stack-overflow // crate, which is freely available under the terms of the Apache 2.0 // license. The modifications here provide better error messages if any of // the various system calls fail. // // See: https://github.com/matklad/backtrace-on-stack-overflow // NOTE(benesch): The stack size was chosen to match the default Rust thread // stack size of 2MiB. Probably overkill, but we'd much rather have // backtraces on stack overflow than squabble over a few megabytes. Using // libc::SIGSTKSZ is tempting, but its default of 8KiB on my system makes me // nervous. Rust code isn't used to running with a stack that small. const STACK_SIZE : usize = 2 << 20 ; // x86_64 and aarch64 require 16-byte alignment. Its hard to imagine other // platforms that would have more stringent requirements. const STACK_ALIGN : usize = 16 ; // Allocate a stack. let buf_layout = Layout :: from_size_align ( STACK_SIZE , STACK_ALIGN ) . expect ( " " ) ; // SAFETY: layout has non-zero size and the uninitialized memory that is // returned is never read (at least, not by Rust). let buf = unsafe { alloc :: alloc ( buf_layout ) } ; // Request that signals be delivered to this alternate stack. let stack = libc :: stack_t { ss_sp : buf as * mut libc :: c_void , ss_flags : 0 , ss_size : STACK_SIZE , } ; // SAFETY: `stack` is a valid pointer to a `stack_t` object and the second // parameter, `old_ss`, is permitted to be `NULL` according to POSIX. let ret = unsafe { libc :: sigaltstack ( & stack , ptr :: null_mut ( ) ) } ; if ret == - 1 { let errno = errno :: from_i32 ( errno :: errno ( ) ) ; bail ! ( " " errno ) ; } // Install a handler for SIGSEGV. let action = signal :: SigAction :: new ( signal :: SigHandler :: Handler ( handle_sigbus_sigsegv ) , signal :: SaFlags :: SA_NODEFER | signal :: SaFlags :: SA_ONSTACK , signal :: SigSet :: empty ( ) , ) ; // SAFETY: see `handle_sigbus_sigsegv`. unsafe { signal :: sigaction ( signal :: SIGBUS , & action ) } . context ( " " ) ? ; unsafe { signal :: sigaction ( signal :: SIGSEGV , & action ) } . context ( " " ) ? ; Ok ( ( ) ) }
Attempts to enable backtraces when SIGBUS or SIGSEGV occurs.
Attempts to enable backtraces when SIGBUS or SIGSEGV occurs .