无法使用静态TLS加载更多对象 [英] Cannot load any more object with static TLS

查看:1189
本文介绍了无法使用静态TLS加载更多对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序使用 dlopen()来加载其他模块。应用程序和模块基于Ubuntu 12.04 x86_64,使用gcc 4.6而不是i386 arch。然后,将二进制文件复制到具有完全相同操作系统的另一台计算机上,并且工作正常。然而,如果将它们复制到Ubuntu 12.04 i386,则一些(但不是全部)模块无法加载以下消息:

  dlopen:无法使用静态TLS加载任何更多对象

我怀疑这是由 __ thread 变量的用法造成的。然而,这些变量并未在加载的模块中使用 - 仅在加载模块本身中。



有人可以提供任何其他信息,原因是什么?



我减少了 __ thread 变量的数量并优化它们(使用 -ftls-model etc),我只是好奇它为什么几乎不能在系统上工作。


我怀疑这是由__thread变量的使用引起的。


正确。


然而,这些变量并未在加载模块中使用 - 仅在加载模块本身中使用。


< blockquote>

不正确。你可能不会自己使用 __ thread ,但是静态链接到你的模块的一些库使用它们。您可以通过以下方式确认:

  readelf -l /path/to/foo.so | grep TLS 




可能是什么原因?


模块使用 -ftls-model = initial-exec ,但应该使用 -ftls模型=全局动态。当链接到 foo.so 的代码(的一部分)没有 -fPIC 时,通常会发生这种情况。 x86_64 -fPIC 代码链接到共享库是不可能的>

c>,但是允许在 ix86 (并导致许多微妙的问题,像这样)



更新:


我有1个模块编译时没有使用-fPIC,但我根本没有设置tls-model,据我所知,默认值不是initial-exec





  • 可能只有一个tls模型对于每个ELF映像(可执行文件或共享库)。
  • TLS模型默认为 initial-exec -fPIC 代码。



如果你链接了一个非 - 使用 __ thread 转换为 foo.so 的fPIC 对象,然后 foo.so 为其所有的TLS获取 initial-exec 。为什么它会导致问题 - 因为如果使用initial-exec,那么tls变量的数量是有限的(因为它们不是动态分配的)。


正确。

I have an application that use dlopen() to load additional modules. The application and modules are built on Ubuntu 12.04 x86_64 using gcc 4.6 but for i386 arch. The binaries are then copied to another machine with exactly same OS and work fine.

However if they are copied to Ubuntu 12.04 i386 then some (but not all) modules fail to load with the following message:

dlopen: cannot load any more object with static TLS

I would suspect that this is caused by the usage of __thread variables. However such variables are not used in the loaded modules - only in the loader module itself.

Can someone provide any additional info, what can be the reason?

I am reducing number of __thread variables and optimizing them (with -ftls-model etc), I'm just curious why it doesn't work on almost same system.

解决方案

I would suspect that this is caused by the usage of __thread variables.

Correct.

However such variables are not used in the loaded modules - only in the loader module itself.

Incorrect. You may not be using __thread yourself, but some library you statically link in into your module is using them. You can confirm this with:

readelf -l /path/to/foo.so | grep TLS

what can be the reason?

The module is using -ftls-model=initial-exec, but should be using -ftls-model=global-dynamic. This most often happens when (some of) the code linked into foo.so is built without -fPIC.

Linking non-fPIC code into a shared library is impossible on x86_64, but is allowed on ix86 (and leads to many subtle problems, like this one).

Update:

I have 1 module compiled without -fPIC, but I do not set tls-model at all, as far as I remember the default value is not initial-exec

  • There could only be one tls model for each ELF image (executable or shared library).
  • TLS model defaults to initial-exec for non-fPIC code.

It follows that if you link even one non-fPIC object that uses __thread into foo.so, then foo.so gets initial-exec for all of its TLS.

So why it causes problems - because if initial-exec is used then the number of tls variables is limited (because they are not dynamically allocated)?

Correct.

这篇关于无法使用静态TLS加载更多对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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