无法再使用静态TLS加载任何对象
Cannot load any more object with static TLS
我有一个使用dlopen()
加载附加模块的应用程序。该应用程序和模块是在Ubuntu 12.04 x86_64上使用gcc 4.6构建的,但适用于i386 arch。然后,二进制文件被复制到另一台操作系统完全相同的机器上,并正常工作。
然而,如果它们被复制到Ubuntu 12.04 i386,那么一些(但不是所有)模块将无法加载,并显示以下消息:
dlopen: cannot load any more object with static TLS
我怀疑这是由__thread
变量的使用引起的。然而,这样的变量不会在加载的模块中使用,只会在加载程序模块本身中使用。
有人能提供任何额外的信息吗?原因是什么?
我正在减少__thread
变量的数量并优化它们(使用-ftls-model
等),我只是好奇为什么它在几乎相同的系统上不起作用。
我怀疑这是由__thread变量的使用引起的。
正确。
然而,这样的变量不会在加载的模块中使用,只会在加载程序模块本身中使用。
不正确。您自己可能没有使用__thread
,但您静态链接到模块中的某些库正在使用它们。您可以通过以下方式确认:
readelf -l /path/to/foo.so | grep TLS
原因是什么?
模块正在使用-ftls-model=initial-exec
,但应该使用-ftls-model=global-dynamic
。当链接到foo.so
中的(一些)代码在没有-fPIC
的情况下构建时,最常发生这种情况。
将非-fPIC
代码链接到共享库在x86_64
上是不可能的,但在ix86
上是允许的(这会导致许多微妙的问题,比如这个问题)。
更新:
我有一个没有-fPIC编译的模块,但我根本没有设置tls模型,据我所知,默认值不是初始exec
- 每个ELF映像(可执行或共享库)只能有一个tls模型
- 对于非
-fPIC
代码,TLS模型默认为initial-exec
因此,如果您甚至将一个使用__thread
的非-fPIC
对象链接到foo.so
,则foo.so
将为其TLS的所有获取initial-exec
。
那么,为什么它会引起问题呢?因为如果使用初始exec,那么tls变量的数量就会受到限制(因为它们不是动态分配的)?
正确。
- std::原子加载和存储都需要吗
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 为什么加载SDF会导致Mobilizer创建闭环错误
- C++atioglxx.pdb未加载错误glBufferData OpenGL
- 如何使用tinyxml2从XML加载父实体和子实体
- 如何在C++中使用pybind11加载一个pickle python列表
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 当我尝试加载内核模块时,如何修复C++中的这个 malloc() 错误?
- 树莓上的 Libtorch 无法加载 pt 文件,但在 ubuntu 上工作
- Python ctypes:不会按预期加载 dll
- 为什么会出现 gettnig 运行时错误:加载类型为"_Bit_type"(stl_bvector.h) 的空指针?
- 我的程序有一个保存配置文件的GUI,如何双击此配置文件以直接加载带有配置数据的GUI?
- 保存/加载大量短数组到二进制文件
- 使用 SDL2 和SDL_image C++加载图像
- 无法使用加载库卸载注入的 dll (C++)
- 是否有原子加载非原子值的函数?
- 将 bmp 文件加载到 TSpeedButton 中
- 如何使用Qt 3D库加载和显示搅拌机.obj源文件场景
- 无法再使用静态TLS加载任何对象