Skip to content

Commit

Permalink
Fix stack overflow detection on FreeBSD
Browse files Browse the repository at this point in the history
src/libstd/sys/unix/thread.rs
	Implement several stack-related functions on FreeBSD

src/libstd/sys/unix/stack_overflow.rs
	Fix a comment
  • Loading branch information
asomers committed Apr 4, 2016
1 parent bbe8e35 commit abc3777
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/libstd/sys/unix/stack_overflow.rs
Expand Up @@ -64,7 +64,7 @@ mod imp {
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
#[repr(C)]
struct siginfo_t {
a: [libc::c_int; 3], // si_signo, si_code, si_errno,
a: [libc::c_int; 3], // si_signo, si_errno, si_code
si_addr: *mut libc::c_void,
}

Expand Down
45 changes: 44 additions & 1 deletion src/libstd/sys/unix/thread.rs
Expand Up @@ -164,6 +164,7 @@ impl Drop for Thread {
}

#[cfg(all(not(all(target_os = "linux", not(target_env = "musl"))),
not(target_os = "freebsd"),
not(target_os = "macos"),
not(target_os = "bitrig"),
not(all(target_os = "netbsd", not(target_vendor = "rumprun"))),
Expand All @@ -177,6 +178,7 @@ pub mod guard {


#[cfg(any(all(target_os = "linux", not(target_env = "musl")),
target_os = "freebsd",
target_os = "macos",
target_os = "bitrig",
all(target_os = "netbsd", not(target_vendor = "rumprun")),
Expand All @@ -199,6 +201,22 @@ pub mod guard {
current().map(|s| s as *mut libc::c_void)
}

#[cfg(target_os = "freebsd")]
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
let mut ret = None;
let mut attr: libc::pthread_attr_t = ::mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
if libc::pthread_attr_get_np(libc::pthread_self(), &mut attr) == 0 {
let mut stackaddr = ::ptr::null_mut();
let mut stacksize = 0;
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
&mut stacksize), 0);
ret = Some(stackaddr);
}
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
ret
}

#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
let mut ret = None;
Expand Down Expand Up @@ -248,7 +266,11 @@ pub mod guard {
panic!("failed to allocate a guard page");
}

let offset = if cfg!(target_os = "linux") {2} else {1};
let offset = if cfg!(any(target_os = "linux", target_os = "freebsd")) {
2
} else {
1
};

Some(stackaddr as usize + offset * psize)
}
Expand Down Expand Up @@ -282,6 +304,27 @@ pub mod guard {
})
}

#[cfg(target_os = "freebsd")]
pub unsafe fn current() -> Option<usize> {
let mut ret = None;
let mut attr: libc::pthread_attr_t = ::mem::zeroed();
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
if libc::pthread_attr_get_np(libc::pthread_self(), &mut attr) == 0 {
let mut guardsize = 0;
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
if guardsize == 0 {
panic!("there is no guard page");
}
let mut stackaddr = ::ptr::null_mut();
let mut size = 0;
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
&mut size), 0);
ret = Some(stackaddr as usize - guardsize as usize);
}
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
ret
}

#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
pub unsafe fn current() -> Option<usize> {
let mut ret = None;
Expand Down

0 comments on commit abc3777

Please sign in to comment.