Skip to content

Commit 0090e01

Browse files
committed
Get __pthread_get_minstack at runtime with dlsym
Linking __pthread_get_minstack, even weakly, was causing Debian’s dpkg-shlibdeps to detect an unnecessarily strict versioned dependency on libc6. Closes #23628. Signed-off-by: Anders Kaseorg <[email protected]>
1 parent b0aad7d commit 0090e01

File tree

1 file changed

+23
-12
lines changed

1 file changed

+23
-12
lines changed

src/libstd/sys/unix/thread.rs

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
use core::prelude::*;
1414

1515
use cmp;
16+
use dynamic_lib::DynamicLibrary;
1617
use ffi::CString;
1718
use io;
1819
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
1920
use libc;
2021
use mem;
2122
use ptr;
23+
use sync::{Once, ONCE_INIT};
2224
use sys::os;
2325
use thunk::Thunk;
2426
use time::Duration;
@@ -314,21 +316,30 @@ pub fn sleep(dur: Duration) {
314316
// is created in an application with big thread-local storage requirements.
315317
// See #6233 for rationale and details.
316318
//
317-
// Link weakly to the symbol for compatibility with older versions of glibc.
318-
// Assumes that we've been dynamically linked to libpthread but that is
319-
// currently always the case. Note that you need to check that the symbol
320-
// is non-null before calling it!
319+
// Use dlsym to get the symbol value at runtime, for compatibility
320+
// with older versions of glibc. Assumes that we've been dynamically
321+
// linked to libpthread but that is currently always the case. We
322+
// previously used weak linkage (under the same assumption), but that
323+
// caused Debian to detect an unnecessarily strict versioned
324+
// dependency on libc6 (#23628).
321325
#[cfg(target_os = "linux")]
322326
fn min_stack_size(attr: *const libc::pthread_attr_t) -> libc::size_t {
323327
type F = unsafe extern "C" fn(*const libc::pthread_attr_t) -> libc::size_t;
324-
extern {
325-
#[linkage = "extern_weak"]
326-
static __pthread_get_minstack: *const ();
327-
}
328-
if __pthread_get_minstack.is_null() {
329-
PTHREAD_STACK_MIN
330-
} else {
331-
unsafe { mem::transmute::<*const (), F>(__pthread_get_minstack)(attr) }
328+
static INIT: Once = ONCE_INIT;
329+
static mut __pthread_get_minstack: Option<F> = None;
330+
331+
INIT.call_once(|| {
332+
let lib = DynamicLibrary::open(None).unwrap();
333+
unsafe {
334+
if let Ok(f) = lib.symbol("__pthread_get_minstack") {
335+
__pthread_get_minstack = Some(mem::transmute::<*const (), F>(f));
336+
}
337+
}
338+
});
339+
340+
match unsafe { __pthread_get_minstack } {
341+
None => PTHREAD_STACK_MIN,
342+
Some(f) => unsafe { f(attr) },
332343
}
333344
}
334345

0 commit comments

Comments
 (0)