diff options
Diffstat (limited to 'src/libstd/sys/unix/stack_overflow.rs')
| -rw-r--r-- | src/libstd/sys/unix/stack_overflow.rs | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 441313bc639..776acd20b06 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -7,11 +7,13 @@ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your // option. This file may not be copied, modified, or distributed // except according to those terms. +#![cfg_attr(test, allow(dead_code))] use libc; use self::imp::{make_handler, drop_handler}; -pub use self::imp::{init, cleanup}; +pub use self::imp::cleanup; +pub use self::imp::init; pub struct Handler { _data: *mut libc::c_void @@ -34,18 +36,19 @@ impl Drop for Handler { #[cfg(any(target_os = "linux", target_os = "macos", target_os = "bitrig", - target_os = "netbsd", + target_os = "dragonfly", + target_os = "freebsd", + all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd"))] mod imp { use super::Handler; - use sys_common::util::report_overflow; use mem; use ptr; - use sys::c::{siginfo, sigaction, SIGBUS, SIG_DFL, - SA_SIGINFO, SA_ONSTACK, sigaltstack, - SIGSTKSZ, sighandler_t}; + use libc::{sigaltstack, SIGSTKSZ}; + use libc::{sigaction, SIGBUS, SIG_DFL, + SA_SIGINFO, SA_ONSTACK, sighandler_t}; use libc; - use libc::funcs::posix88::mman::{mmap, munmap}; + use libc::{mmap, munmap}; use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON}; use libc::MAP_FAILED; @@ -55,6 +58,22 @@ mod imp { // This is initialized in init() and only read from after static mut PAGE_SIZE: usize = 0; + #[cfg(any(target_os = "linux", target_os = "android"))] + unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void { + #[repr(C)] + struct siginfo_t { + a: [libc::c_int; 3], // si_signo, si_code, si_errno, + si_addr: *mut libc::c_void, + } + + (*(info as *const siginfo_t)).si_addr + } + + #[cfg(not(any(target_os = "linux", target_os = "android")))] + unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void { + (*info).si_addr + } + // Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages // (unmapped pages) at the end of every thread's stack, so if a thread ends // up running into the guard page it'll trigger this handler. We want to @@ -74,10 +93,12 @@ mod imp { // handler to work. For a more detailed explanation see the comments on // #26458. unsafe extern fn signal_handler(signum: libc::c_int, - info: *mut siginfo, + info: *mut libc::siginfo_t, _data: *mut libc::c_void) { + use sys_common::util::report_overflow; + let guard = thread_info::stack_guard().unwrap_or(0); - let addr = (*info).si_addr as usize; + let addr = siginfo_si_addr(info) as usize; // If the faulting address is within the guard page, then we print a // message saying so. @@ -124,7 +145,7 @@ mod imp { panic!("failed to allocate an alternative stack"); } - let mut stack: sigaltstack = mem::zeroed(); + let mut stack: libc::stack_t = mem::zeroed(); stack.ss_sp = alt_stack; stack.ss_flags = 0; @@ -143,7 +164,9 @@ mod imp { #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "bitrig", - target_os = "netbsd", + target_os = "dragonfly", + target_os = "freebsd", + all(target_os = "netbsd", not(target_vendor = "rumprun")), target_os = "openbsd")))] mod imp { use ptr; |
