Opened 2 years ago
Last modified 21 months ago
#17896 new bug
static (hidden) thread_local values do not work in some cases — at Version 12
Reported by: | waddlesplash | Owned by: | nobody |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | System/runtime_loader | Version: | R1/beta3 |
Keywords: | Cc: | korli | |
Blocked By: | Blocking: | ||
Platform: | All |
Description (last modified by )
gnutls makes use of this, and it had to be disabled to fix crashes: https://github.com/haikuports/haikuports/commit/cda76a62712b91647892ba01f1a5d0dcb38cadc5
Change History (13)
comment:1 by , 2 years ago
Cc: | added |
---|
comment:2 by , 2 years ago
Hmm, I guess this counts as "static TLS", which would be #13294. But we should get an error and the program shouldn't load at all in that case...
comment:3 by , 2 years ago
Ah, right, since this is a shared object, it does not count as "static TLS", I don't think, so this should in theory work. But it appears at least in this test application that putting the "_Thread_local" variable outside the function and deleting the "static" doesn't make it work either, in fact in that case I get all 5 having the same pointer value!
comment:4 by , 2 years ago
A bit more testing shows that __tls_get_addr
in libroot is indeed returning bad values:
__tls_get_addr: thread 2224, module 0, offset (nil) -> 0x48bc539990 __tls_get_addr: thread 2221, module 0, offset (nil) -> 0x48bc5398f0 __tls_get_addr: thread 2225, module 0, offset (nil) -> 0x48bc5398f0 __tls_get_addr: thread 2222, module 0, offset (nil) -> 0x48bc5398f0 __tls_get_addr: thread 2223, module 0, offset (nil) -> 0x48bc5398f0
That pushes the problem up into runtime_loader indeed.
comment:5 by , 2 years ago
This does not seem to be a race condition. Adding snooze(100000)
into both for
loops actually has the effect that we always seem to get the same pointer for all threads!
comment:6 by , 2 years ago
Got it: the TLS_DYNAMIC_THREAD_VECTOR has different pointers for each thread (good, that would mean base TLS is broken otherwise) but they all point to the same place. Now how did that happen...
comment:7 by , 2 years ago
Ah, so what is happening is that the threads are all exiting before the next one even starts, and so the TLS memory gets freed when the thread exits and then reused when the next thread starts. Adding snooze(10000);
to the end of the thread function and removing the snoozes from elsewhere shows all variables have different values indeed.
I then readded the static
and things still worked just fine. So I guess I am not sure what the problem with gnutls is that it works when the thread-local variables are non-static...
comment:8 by , 2 years ago
<X512> I found that after writing to TLS variable it read as zero. <X512> Removing static fixed that. <X512> I tried to make mores simple case, but it worked fine... <X512> Write value to static TLS variable and immediately after read it. It will become zero. <X512> I suspect that GCC use some optimization for static TLS variable that may use TLS model unsupported in Haiku.
comment:9 by , 2 years ago
More likely it seems to me is that somehow the generation-accounting logic in runtime_loader's elf_tls.cpp is not correct, and blocks are getting spuriously deleted and recreated. Comparing it to FreeBSD I note a bunch of differences, but based on commit messages some of these may be intentional.
by , 2 years ago
Attachment: | static-vs-non.diff added |
---|
comment:10 by , 2 years ago
Here's a difference of the gcc -S output when compiling random.c from GNUTLS with static
vs no static
on the variable declarations. Note the .value 0x6666
: what's that about?
comment:11 by , 2 years ago
I also did find what I am pretty sure is an issue in the TLS DTV handling, but I think it's not necessarily related to this: https://review.haiku-os.org/c/haiku/+/5604
comment:12 by , 2 years ago
Description: | modified (diff) |
---|---|
Summary: | static (hidden) thread_local values do not actually get unique pointers → static (hidden) thread_local values do not work in some cases |
CC korli, perhaps you have some idea about what to do here?