Comment 22 for bug 1375555

Revision history for this message
In , Mikko (mikko-redhat-bugs) wrote :

cat readelf.txt | egrep 'readelf| TLS ' | grep -v ' 0 TLS ' | grep TLS -B1

384 /lib64/libpixman-1.so.0
272 /lib64/libc.so.6
224 /lib64/libselinux.so.1
108 /lib64/libgomp.so.1
78 /lib64/libuuid.so.1
56 /lib64/libsystemd.so.0
48 /lib64/libstdc++.so.6
32 /lib64/libglapi.so.0
25 /lib64/libcom_err.so.2
8 /lib64/libasound.so.2
8 /lib64/libdw.so.1
8 /lib64/libEGL.so.1
8 /lib64/libGL.so.1
8 /lib64/libQtCore.so.4
4 /lib64/libelf.so.1

= 1271 bytes (is there some additional rounding done by linker?)

After some googling I found out that we need -d flag to readelf to find which modules have static tls. Results are:

cat readelf.txt | egrep 'readelf|STATIC_TLS' | grep TLS -B1 | grep readelf | cut -d/ -f2-
272 /lib64/libc.so.6
108 /lib64/libgomp.so.1
32 /lib64/libglapi.so.0
8 /lib64/libEGL.so.1
8 /lib64/libGL.so.1
0 /lib64/libcrypt.so.1
0 /lib64/libm.so.6
0 /lib64/libnsl.so.1
0 /lib64/libnss_files.so.2
0 /lib64/libpthread.so.0
0 /lib64/libresolv.so.2
0 /lib64/librt.so.1
0 /lib64/libutil.so.1

The 0 byte STATIC_TLS usage .so files have references to glibc variables such as so I did not count them.
0 TLS GLOBAL DEFAULT UND errno@GLIBC_PRIVATE (4)

If I googled right the .so libraries tagged STATIC_TLS fail to load if their TLS section does not fit into the static section. Others prefer static TLS (and thus use it even if not tagged static).

The actual .so load order (for libraries with TLS section) is:
/lib64/libc.so.6
/lib64/libcom_err.so.2
/lib64/libselinux.so.1
/lib64/libstdc++.so.6
/lib64/libQtCore.so.4
/lib64/libuuid.so.1
/lib64/libasound.so.2
/lib64/libGL.so.1
/lib64/libglapi.so.0
/lib64/libsystemd.so.0
/lib64/libdw.so.1
/lib64/libelf.so.1
/lib64/libpixman-1.so.0
/lib64/libEGL.so.1
/lib64/libgomp.so.1

Looking at the above lists my conclusion is that libgomp.so is the library that fails to load (the python tries to load libMagickCore-6.Q16.so.2, which depends on libgomp). But the libselinux and libpixman have already managed to store their large TLS sections into the static block.

Possible solutions:
1) make the calibre python somehow not load libselinux (could such switch be added to python?)
2) make the calibre load the libgomp/libMagicCore earlier, before libpixman (most likely libselinux is loaded so early that it cannot be avoided)
3) add a new flag RTLD_NO_AUTOMATIC_STATIC_TLS for dlopen function to _not_ use static TLS for libraries unless they request it with STATIC_TLS. And then make python load libraries with the new flag
4) recompile the fedora to have larger static TLS section (the glibc seems to define TLS_STATIC_SURPLUS as 64+DL_NNS*100, where DL_NNS is either 1 or 16)