que*_*en3 11 c++ linux ubuntu gcc dlopen
我有一个dlopen()
用于加载其他模块的应用程序.应用程序和模块使用gcc 4.6构建在Ubuntu 12.04 x86_64上,但是用于i386 arch.然后将二进制文件复制到具有完全相同操作系统的另一台计算机并正常工作.
但是,如果将它们复制到Ubuntu 12.04 i386,则某些(但不是全部)模块无法加载以下消息:
dlopen: cannot load any more object with static TLS
Run Code Online (Sandbox Code Playgroud)
我怀疑这是由__thread
变量的使用引起的.但是,这些变量不会在加载的模块中使用 - 仅在加载器模块本身中使用.
有人可以提供任何其他信息,可能是什么原因?
我正在减少__thread
变量的数量并优化它们(-ftls-model
等等),我只是好奇为什么它不能在几乎相同的系统上工作.
Emp*_*ian 13
我怀疑这是由__thread变量的使用引起的.
正确.
但是,这些变量不会在加载的模块中使用 - 仅在加载器模块本身中使用.
不正确.您可能没有使用__thread
自己,但是您静态链接到模块中的某些库正在使用它们.您可以通过以下方式确认:
readelf -l /path/to/foo.so | grep TLS
Run Code Online (Sandbox Code Playgroud)
可能是什么原因?
该模块正在使用-ftls-model=initial-exec
,但应该使用-ftls-model=global-dynamic
.当链接到的代码(某些)foo.so
没有构建时,通常会发生这种情况-fPIC
.
将非-fPIC
代码链接到共享库是不可能的x86_64
,但是被允许ix86
(并导致许多微妙的问题,比如这个).
更新:
我有1个模块没有-fPIC编译,但我根本没有设置tls-model,据我记得默认值不是initial-exec
initial-exec
为非-fPIC
代码.因此,如果您链接甚至一个非-fPIC
使用对象__thread
为foo.so
,然后foo.so
获得initial-exec
了所有的TLS的.
那么为什么它会导致问题 - 因为如果使用initial-exec那么tls变量的数量是有限的(因为它们不是动态分配的)?
正确.
归档时间: |
|
查看次数: |
9796 次 |
最近记录: |