Sources Bugzilla – Bug 12453
Broken thread local storage (TLS) initialization
Last modified: 2011-05-15 01:33:07 UTC
Created attachment 5218 [details]
Script reproducing the issue
When dynamically loading a library along with several dependencies, calls to
_dl_add_to_slotinfo and _dl_update_slotinfo can become intermixed. As a
consequence, _dl_update_slotinfo will update the generation counter of the dtv
although not all of the slots belonging to that generation have been added.
Subsequent calls to _dl_add_to_slotinfo will add more slots to the same
generation, for which no storage will be allocated, as the dtv generation
checks will claim no work is necessary. This will lead to uninitialized dtv
entries and will likely cause a SIGSEGV when thread local variables are
The attached script, when executed in an empty directory on a GNU/Linux x86_64
system, and probably under other circumstances as well, will demonstrate the
problem. It will print
glibc-tls-bug.sh: line 75: 1752 Segmentation fault "$@"
where you see that the address of the thread local variable tbaz is NULL, and
the referencing that variable causes a segmentation fault.
Created attachment 5219 [details]
Do update_slotinfo after add_to_slotinfo
This patch fixes the issue for me. It should be reasonably safe to apply.
Cross references with further details:
I can't seem to run your test program, which I saved as "glibtest"
gcc -Wall -ggdb -O0 -Wl,-rpath,$ORIGIN -fPIC -shared -o ./libbar.so bar.c
gcc -Wall -ggdb -O0 -Wl,-rpath,$ORIGIN -fPIC -shared -o ./libbaz.so baz.c
gcc -Wall -ggdb -O0 -Wl,-rpath,$ORIGIN -fPIC -shared -o ./libfoo.so foo.c -L.
gcc -Wall -ggdb -O0 -Wl,-rpath,$ORIGIN -o demo demo.c -ldl
Error loading libfoo.so: ld.so.1: demo: fatal: libbar.so: open failed: No such
file or directory
the library files are created, as I see the following files in the directory
I've got no idea what this ORIGIN is - I myself write scripts as POSIX files,
not bash scripts, so perhaps this is something I don't even have in my version
drkirkby@hawk:~/glibc$ bash --version
GNU bash, version 4.0.28(1)-release (i386-pc-solaris2.11)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law
(In reply to comment #3)
> I can't seem to run your test program, which I saved as "glibtest"
> gcc -Wall -ggdb -O0 -Wl,-rpath,$ORIGIN -o demo demo.c -ldl
> Error loading libfoo.so: ld.so.1: demo:
> fatal: libbar.so: open failed: No such file or directory
OK, seems this relative path thingy doesn't work for you, for some reason.
Maybe try "LD_LIBRARY_PATH=$PWD ./demo"
> I've got no idea what this ORIGIN is - I myself write scripts as POSIX files,
> not bash scripts, so perhaps this is something I don't even have in my version
> of bash
This is nothing magic to the script, but instead some special value accepted by
ld.so. See your ld.so(8) man page, or find it online e.g. at
(In reply to comment #4)
Or not so strange, if you are on OpenSolaris, as your recent activity on
related bugs and the bash version message indicates. I guess -rpath=$ORIGIN is
probably specific to the GNU/Linux dynamic linker.
I've applied a slightly modified version of the patch.
*** Bug 11952 has been marked as a duplicate of this bug. ***