我有一个与 gcc 链接的 exe -static
,用于dlopen
加载共享库。该库尝试访问线程本地存储 (TLS) 中的变量。当我们尝试访问 TLS 变量时,运行应用程序会出现段错误。删除该-static
标志可避免段错误。
虽然这种用法不常见,但实际上有什么不对吗?
这样做的目的是允许静态链接的 exe 在运行时选择性地加载插件(当其依赖项存在时),但默认情况下无需依赖这些依赖项即可运行。对 TLS 的需求源于它在 C++ 异常处理中的使用(因此我通常无法通过修改共享库本身的编译方式来解决这个问题)。
==> main.c <==
#include <dlfcn.h>
int main()
{
void* lib = dlopen("./libusetls.so", RTLD_NOW);
typedef int func_t();
func_t* function = dlsym(lib, "function");
return function();
}
==> usetls.c <==
#include <stdio.h>
int function()
{
static __thread int value = 0;
return value;
}
==> makefile <==
gcc -o main main.c -ldl -g -static
usetls.o: usetls.c makefile
gcc -c -fPIC -o usetls.o usetls.c -g
libusetls.so: usetls.o makefile
gcc -shared -fPIC -Wl,-soname,libusetls.so -o libusetls.so usetls.o -lc
clean:
rm main usetls.o libusetls.so