gpt4 book ai didi

c++ - libgcc_s.so 在同一进程中静态和动态链接是否正常?

转载 作者:IT王子 更新时间:2023-10-29 00:41:22 24 4
gpt4 key购买 nike

我的应用引入了许多共享库。有些是用 C++ 编写的,它会引入 libstdc++.so,而后者会引入 libgcc_s.so。还有一些是用纯 C 语言编写的,并与 -static-libgcc 链接。

所以现在我有一些 libgcc 静态链接在多个共享库中,而 libstdc++ 在运行时动态加载其他 libgcc。

Q1:这个设置会给我带来什么麻烦吗? libgcc 是否具有会使这种混合链接出现问题的内部状态,或者它只是内联函数?

问题 2:为了让我的应用程序在旧版 Linux 上运行,我应该发布 libstdc++.so 和 libgcc_s.so 并在主 exe 上使用 rpath 来加载它。这是正确的做法吗?

最佳答案

Would this setup give me any trouble? Does libgcc have internal state that would make this mixed linkage problematic, or is it just inlined functions?

绝对是的。我刚刚花了大约一个星期的全天调试时间来找出导致我的程序在 Windows/MinGW 上调用 std::call_once 时崩溃的原因。这是一个简化的测试用例:

mybin.cpp:

#include <pthread.h>
#include <mutex>
#include <iostream>

extern "C" int* getVar();

void print()
{
std::cout << "Hello, var=" << *getVar() << "\n";
}

int main()
{
pthread_key_t key;
// Create first key, which will occupy the zero value, so that
// __emutls_get_address will get a nonzero one when initializing emutls_key
// (otherwise due to some C+pthread symmetries we'll not get the crash).
pthread_key_create(&key, nullptr);

std::once_flag f;
// Crash
std::call_once(f, print);
}

mylib.c:

// Make gcc emit some calls to __emutls_get_address to import
// libgcc implementing this function
static __thread int someVar;
int* getVar(void)
{
if(!someVar)
someVar=5;
return &someVar;
}

生成文件:

test: libmylib.dll mybin.o
g++ mybin.o -o test -pthread -static-libgcc -L. -lmylib

libmylib.dll: mylib.c Makefile
gcc -fPIC -shared mylib.c -o libmylib.dll

mybin.o: mybin.cpp Makefile
g++ -c mybin.cpp -o mybin.o

这里的崩溃是由于以下原因造成的。 std::call_once 将被调用者的地址(此处为 print)写入线程局部指针 __once_call,其地址可通过调用 __emutls_get_address。此调用直接从 .exe 发生,因此它由 static libgcc 解析(请参阅上面的 Makefile)。接下来发生的是 libstdc++ 调用它的 __once_proxy,然后它试图通过 __emutls_get_address 找到 __once_call 的地址,它是从 dynamic libgcc,因为 libstdc++ 是动态库。

结果是 emutls_key 是 libgcc 的静态全局变量,每个 libgcc 拷贝被初始化两次(前提是预先调用了 pthread_key_create),并且 __once_call 被写入一个 TLS 中的拷贝,并从另一个 TLS 中的拷贝中读取。随后尝试调用 __once_call 导致空指针取消引用。

以上只是我调试调查的结果,并非我故意制作的。你的经历可能更容易或更难。因此,总而言之,,静态和动态链接 libgcc 绝对会造成麻烦。

关于c++ - libgcc_s.so 在同一进程中静态和动态链接是否正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29283116/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com