有没有一种方法可以确定Linux上的库使用的线程本地存储模型 [英] Is there a way to determine thread local storage model used by a library on Linux
问题描述
在Linux上是否可以查询共享库的TLS模型? (例如,使用ldd或其他工具).
Is there a way to query the TLS model of a shared library on Linux? (eg using ldd or some other tool).
我在使用"initial-exec"模型加载太多库时遇到麻烦,并且想确定哪些第三方库使用此模型(因此我可以释放一些插槽,例如通过静态链接)
I am having a trouble with loading too many libraries with the "initial-exec" model and would like to determine for sure which of the third party libs use this model (so I can free up some slots eg by linking statically).
这会导致错误:
dlopen: cannot load any more object with static TLS
请参见此问题.
推荐答案
I ran into this error myself, and while investigating it, I came on a mailing list post with this info:
如果链接包含IE模型访问重定位的共享对象,则该对象 将设置DF_STATIC_TLS标志.根据规范,这意味着dlopen 可能会拒绝加载它.
If you link a shared object containing IE-model access relocs, the object will have the DF_STATIC_TLS flag set. By the spec, this means that dlopen might refuse to load it.
看看/usr/include/elf.h
,我们有:
/* Values of `d_un.d_val' in the DT_FLAGS entry. */
...
#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
因此,您需要测试是否在共享库的DT_FLAGS
条目中设置了DF_STATIC_TLS
.
So you need to test if DF_STATIC_TLS
is set in the DT_FLAGS
entry of the shared library.
为了测试,我使用线程本地存储创建了一段简单的代码:
To test things, I created a simple piece of code using thread local storage:
static __thread int foo;
void set_foo(int new) {
foo = new;
}
然后我使用两种不同的线程本地存储模型对其进行了两次编译:
I then compiled it twice with the two different thread local storage models:
gcc -ftls-model=initial-exec -fPIC -c tls.c -o tls-initial-exec.o
gcc -shared tls-initial-exec.o -o tls-initial-exec.so
gcc -ftls-model=global-dynamic -fPIC -c tls.c -o tls-global-dynamic.o
gcc -shared tls-global-dynamic.o -o tls-global-dynamic.so
当然,我可以使用readelf
看到两个库之间的区别:
And sure enough, I can see a difference between the two libraries using readelf
:
$ readelf --dynamic tls-initial-exec.so
Dynamic section at offset 0xe00 contains 25 entries:
Tag Type Name/Value
...
0x000000000000001e (FLAGS) STATIC_TLS
tls-global-dynamic.so
版本没有DT_FLAGS
条目,大概是因为它没有设置任何标志.因此,使用readelf
和grep
创建脚本以查找受影响的库应该相当容易.
The tls-global-dynamic.so
version did not have a DT_FLAGS
entry, presumably because it didn't have any flags set. So it should be fairly easy to create a script using readelf
and grep
to find affected libraries.
这篇关于有没有一种方法可以确定Linux上的库使用的线程本地存储模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!