我有一个共享库(libtest.cpp)和一个简单程序(test.cpp)。我希望他们共享线程局部变量 gVar 。共享库通过LD_PRELOAD链接。

这是我的共享库libtest.cpp的代码:

#include<stdio.h>

__thread int gVar;

void print_gVar(){
  printf("%d\n", gVar);
}

下面是test.cpp的代码。

#include<stdio.h>

__thread int gVar;

void __attribute__((weak)) print_gVar();

int main(){
  gVar = 10;
  print_gVar();
  return 0;
}

我使用以下脚本来编译和运行它们。
g++ -g -shared -fPIC -olibtest.so libtest.cpp
g++ -g -fPIC -o test test.cpp
LD_PRELOAD=./libtest.so ./test

预期结果为10,因为test.cpp中的分配将影响libtest.cpp中的gVar。但是,我只有0。似乎libtest.cpp中的gVar和test.cpp中的gVar没有链接。

我做了一些其他测试:

如果我在任何文件的__attribute__((weak))声明中添加gVar,则输出仍为0。

如果我从两个文件中删除__thread,则结果为10(成功)。

如果我在libtest.cpp中的extern声明中添加__attribute__((weak))gVar,将出现段错误。

我猜LD_PRELOAD__thread一定有问题。但我不知道。

谁能告诉我如何使它起作用?非常感谢你!

最佳答案

这是不可能的,因为线程本地存储需要按线程初始化。
LD_PRELOAD甚至会在加载标准库之前加载该库,这会破坏TLS初始化。

更新:

请阅读ELF Handling For Thread-Local Storage的第2节和第3节

关于c++ - LD_PRELOAD和线程局部变量,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21321626/

10-11 22:05
查看更多