Skip to content

Rust builds an unloadable shared library: No space available for static Thread Local Storage #140092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
yurivict opened this issue Apr 20, 2025 · 6 comments
Labels
A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. O-freebsd Operating system: FreeBSD

Comments

@yurivict
Copy link

yurivict commented Apr 20, 2025

The Polars project builds the shared library that can't be loaded. dlopen fails with the error:

No space available for static Thread Local Storage

The binary is /usr/local/lib/python3.11/site-packages/polars/polars.abi3.so

Meta

rustc --version --verbose:

$ rustc --version --verbose
rustc 1.88.0-nightly (e2014e876 2025-04-01) (built from a source tarball)
binary: rustc
commit-hash: e2014e876e3efaa69bf51c19579adb16c3df5f81
commit-date: 2025-04-01
host: x86_64-unknown-freebsd
release: 1.88.0-nightly
LLVM version: 20.1.1

FreeBSD 14.2 amd64

Description

One possible reason is that wrong tls-model is used. It probably uses the tls-model initial-exec intended for non-PIC binaries instead of the tls-model global-dynamic intended for PIC binaries.

The tls-model choice is buried in Rust and Maturin code and it is unclear where the problem lies.

Additional details are in this downstream bug report.

How to reproduce:

1. Install the [FreeBSD VM image](https://download.freebsd.org/ftp/releases/VM-IMAGES/14.2-RELEASE/amd64/Latest/) into VirtualBox.
2. Boot FreeBSD
3. Install git: pkg install git
4. Check out the ports tree: git clone https://git.FreeBSD.org/ports.git /usr/ports
5. cd /usr/ports
6. Apply this patch: https://freebsd.org/~yuri/py-polars.patch
7. cd misc/py-polars
8. Install dependencies: pkg install -A `make missing`
9. Build: make
10. Install: make install```


Please help.
@yurivict yurivict added the C-bug Category: This is a bug. label Apr 20, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 20, 2025
@Urgau
Copy link
Member

Urgau commented Apr 20, 2025

Th default tls-model is general-dynamic, and I'm not seeing it being overridden by the base target (freebsd) or the target (x86_64_unknown_freebsd).

tls_model: TlsModel::GeneralDynamic,


What happens if you set (or export) LD_STATIC_TLS_EXTRA=20481? If it works that would confirm you suspicion of initial-exec being used.

cc @asomers @MikaelUrankar (our FreeBSD target maintainers)

Footnotes

  1. https://man.freebsd.org/cgi/man.cgi?rtld(1)

@Urgau Urgau added O-freebsd Operating system: FreeBSD A-thread-locals Area: Thread local storage (TLS) labels Apr 20, 2025
@markmi
Copy link

markmi commented Apr 20, 2025

# fetch https://freebsd.org/~yuri/polars.abi3.so
polars.abi3.so                                         123 MB 1773 kBps 01m12s

# file polars.abi3.so
polars.abi3.so: ELF 64-bit LSB shared object, x86-64, version 1 (FreeBSD), dynamically linked, for FreeBSD 14.2 (1402504), stripped

# readelf -d polars.abi3.so 

Dynamic section at offset 0x7bc6c28 contains 32 entries:
  Tag                Type                  Name/Value
 0x0000000000000001 NEEDED               Shared library: [libc.so.7]
 0x0000000000000001 NEEDED               Shared library: [libkvm.so.7]
 0x0000000000000001 NEEDED               Shared library: [libprocstat.so.1]
 0x0000000000000001 NEEDED               Shared library: [libthr.so.3]
 0x0000000000000001 NEEDED               Shared library: [libgcc_s.so.1]
 0x0000000000000001 NEEDED               Shared library: [libm.so.5]
 0x000000000000001e FLAGS                BIND_NOW STATIC_TLS
 0x000000006ffffffb FLAGS_1              NOW

# readelf -r polars.abi3.so | grep TPOFF
000007bdaa38 000000000012 R_X86_64_TPOFF64    0000000000000000  + b8
000007bdaa98 000000000012 R_X86_64_TPOFF64    0000000000000000  + 3b8

# readelf -r polars.abi3.so | grep TLS
#

@yurivict
Copy link
Author

Yes, I forgot to mention:
LD_STATIC_TLS_EXTRA=1024 is a workaround for the binary to become loadable.

@yurivict
Copy link
Author

The bug might as well be in Maturin. I am not familiar how Maturin interacts with Rust.

@Mark-Simulacrum
Copy link
Member

Polars looks to pull in mimalloc and that has a TLS model override by default for the C code it compiles (I'm not sure why): https://github.com/purpleprotocol/mimalloc_rust/blob/59d7ee3ba7aa030b46a7cf721720f63a579b7fdb/libmimalloc-sys/build.rs#L28-L34

I'd recommend filing upstream bug report (with mimalloc and/or polars) to change that. I don't think there's any particular bug in Rust here, indeed the rustc TLS model might be global dynamic for the whole build.

@yurivict
Copy link
Author

I created the mimalloc bug report:
purpleprotocol/mimalloc_rust#138

Thank you for your help!

Yuri

@jieyouxu jieyouxu removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Apr 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. O-freebsd Operating system: FreeBSD
Projects
None yet
Development

No branches or pull requests

6 participants