Rollup merge of #76521 - tavianator:fix-pthread-getattr-destroy, r=Amanieu

Fix segfault if pthread_getattr_np fails

glibc [destroys][1] the passed pthread_attr_t if pthread_getattr_np()
fails.  Destroying it again leads to a segfault.  Fix it by only
destroying it on success for glibc.

[1]: https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/pthread_getattr_np.c;h=ce437205e41dc05653e435f6188768cccdd91c99;hb=HEAD#l205
This commit is contained in:
Ralf Jung 2020-09-21 15:30:37 +02:00 committed by GitHub
commit ae4b677aa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -294,6 +294,7 @@ pub mod guard {
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
let mut ret = None;
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
#[cfg(target_os = "freebsd")]
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
#[cfg(target_os = "freebsd")]
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
@ -305,7 +306,9 @@ pub mod guard {
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr, &mut stacksize), 0);
ret = Some(stackaddr);
}
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
if e == 0 || cfg!(target_os = "freebsd") {
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
}
ret
}
@ -403,6 +406,7 @@ pub mod guard {
pub unsafe fn current() -> Option<Guard> {
let mut ret = None;
let mut attr: libc::pthread_attr_t = crate::mem::zeroed();
#[cfg(target_os = "freebsd")]
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
#[cfg(target_os = "freebsd")]
let e = libc::pthread_attr_get_np(libc::pthread_self(), &mut attr);
@ -446,7 +450,9 @@ pub mod guard {
Some(stackaddr..stackaddr + guardsize)
};
}
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
if e == 0 || cfg!(target_os = "freebsd") {
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
}
ret
}
}