Change:
Linking with certain external libraries can inflate the required amount of thread local storage to astronomical proportions. When the Rust runtime tries to create its threads, it requests a stack size independent of the TLS size, which can lead to pthreadcreate() failing with EINVAL when the stack size is smaller than the TLS size. This was apparently an issue for the Go runtime as well (). A potential workaround is to add statictls_size (+ possibly a guard page) to the requested stack size, but it's arguably a bug in glibc that TLS comes out of the requested stack, instead of being to it. This solution is also admittedly not very pleasing...
I made a mistake. The workaround should actually be to add _pthreadgetminstack(&attr) to the requested size in It's still not very pleasing.
This is the bug in glibc
Still relevant, but it's an upstream bug. Removing E-easy
Triage: we still call without adjusting for so I assume that the work-around hasn't been implemented, and the upstream bug is still open (and without activity for more than 3 months).
Triage: still a bug even with the pure Rust runtime. With it crashes with: and without that it runs fine. I'll attempt to fix it now.
(The above crash appears to not happen on Mac OSX; I'm on Linux.) I opened ; but I don't think that work-around is complete enough to close this.
My patch caused people linking errors ( is apparently not in all versions of glibc (works in 2.17, fails with 2.13), being a private function), so I'm reverting it in .

Discussion:
let mut native: libc::pthread_t = intrinsics::uninit(); let mut attr: libc::pthread_attr_t = intrinsics::uninit(); assert_eq!(pthread_attr_init(&mut attr), 0); <ins> let min_stack = get_min_stack(&attr); </ins> assert_eq!(pthread_attr_setstacksize(&mut attr, <del> stack as libc::size_t), 0); </del> <ins> min_stack + stack as libc::size_t), 0); </ins> assert_eq!(pthread_attr_setdetachstate(&mut attr, PTHREAD_CREATE_JOINABLE), 0);

#[cfg(not(target_os = "macos"), not(target_os = "android"))] pub unsafe fn yield_now() { assert_eq!(pthread_yield(), 0); } <ins> // Issue #6233. On some platforms, putting a lot of data in // thread-local storage means we need to set the stack-size to be // larger. #[cfg(target_os = "linux")] unsafe fn get_min_stack(attr: &libc::pthread_attr_t) -> libc::size_t { __pthread_get_minstack(attr) } #[cfg(not(target_os = "linux"))] unsafe fn get_min_stack(_: &libc::pthread_attr_t) -> libc::size_t { 0 } </ins> extern { fn pthread_create(native: *mut libc::pthread_t, attr: *libc::pthread_attr_t,

fn sched_yield() -> libc::c_int; #[cfg(not(target_os = "macos"), not(target_os = "android"))] fn pthread_yield() -> libc::c_int; <ins> // This appears to be glibc specific #[cfg(target_os = "linux")] fn __pthread_get_minstack(attr: *libc::pthread_attr_t) -> libc::size_t; </ins> } }

<ins> // Copyright 2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license // <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. // Issue #6233 // xfail-fast feature doesn't work #[feature(thread_local)]; #[allow(dead_code)]; static SIZE: uint = 1 << 23; #[thread_local] static FOO: [u8, .. SIZE] = [0, .. SIZE]; fn main() {} </ins>