有没有一种方法可以确定Linux上的库使用的线程本地存储模型 [英] Is there a way to determine thread local storage model used by a library on Linux

查看:408
本文介绍了有没有一种方法可以确定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条目,大概是因为它没有设置任何标志.因此,使用readelfgrep创建脚本以查找受影响的库应该相当容易.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆