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
cmd/link: c-archive Output Mode Forces Initial-Exec
TLS model
#48596
Comments
@ianlancetaylor |
Initial-Exec
TLS modelInitial-Exec
TLS model
Offhand I don't know why this would be different for c-archive and c-shared. In both cases we pass Perhaps the difference is in cmd/link. I'm not sure. In general for c-archive the linker should produce an object that can be linked into a shared library, including using local-dynamic rather than initial-exec for the single TLS variable CC @cherrymui |
Both с-archive and c-shared include same STATIC_TLS flag and IE TLS model. So in a sense they work same. But that leads to different effects when c-archive is being combined with other user code. Because c-archive propagates STATIC_TLS flag to entire user codebase (including user-defined code), and that combination fails. c-shared does not fail only because it's isolated from the other user code. If it's still confusing, I'll try to think how to better illustrate... Or maybe attached gist could help. In attached gist: |
Current glibc no longer uses all static TLS for optimizations:
The TLS surplus can also be tuned at run time, somewhat indirectly, using the |
Oh, that sounds even worse. If I understood correctly default glibc setting wouldn't be able to glibc tuneables are out of any stability contract and not always enabled even.
|
No, newer glibc versions have larger TLS surplus space by default, and dedicate some of this space to use in future |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Full Gist is available here - https://gist.github.com/auzhva/6e3660c2433f7ead765d4d09e645013b
In provided example there are 3 files:
If built in below fashion it works:
Then when running
./app
it's fine.While if I do below it fails with
cannot allocate memory in static TLS block
error.More investigation on STATIC_TLS flag
It appears that Go always builds with
Initial-Exec
TLS model, which appears to lead toSTATIC_TLS
flag being set to produced ELF binaries.This is easily visible with below:
This is a case with
c-shared
library itself. But whenc-archive
is produced then whatever upper code will use it - it inherits STATIC_TLS flag.So in second (faulty) example above the entire
libClibShared.so
inherits STATIC_TLS flag as well. At least on x86_64 arch (in theory this can be arch-dependent).Ok, there is STATIC_TLS flag. So what?
Loading STATIC_TLS images is a complicated thing.
In linux version glibc it allocates pre-populated constant
surplus
of 512 bytes in TLS block for further unspecified use. It's defined here - https://sourceware.org/git/?p=glibc.git;a=blob;f=elf/dl-tls.c;h=d554ae44976bc494da4e41aaa4f6ecb5ca2ca4be;hb=HEADIf I'm checking sizes of
.tbss/.tdata
sections viareadelf -S
then I see that go uses only 0x10 bytes of TLS. Which is lower then glibc surplus. And theoretically glibc is able todlopen()
up to 32 go libs until it will run out of the buffer.But it doesn't work with
c-archive
. Go lib inc-archive
mode requires same 16 bytes of TLS stack, but other code may have additional TLS requirements. So if additional code needs more TLS then c-archive plus that code runs out of glibc boundaries and entire thing fails.That wouldn't have been happening if
c-shared
andc-archive
would've not been forcing Initial-TLS TLS models. As this 512-byte glibc limit applies only to that model. And any of the other 3 models (General Dynamic, Local Dynamic, Local Executable) do not have this limit.What did you expect to see?
Both c-shared and c-archive cases working.
What did you see instead?
C-archive case failing.
The text was updated successfully, but these errors were encountered: