Linux动态库dlopen时带RTLD_DEEPBIND导致崩溃问题
问题描述
当调用Linux动态库so时,偶然发现dlopen带参数RTLD_DEEPBIND会报错:Segmentation fault
去掉该参数则无问题。
如下
//test.cc
#include <iostream>
#define TEST_API __attribute((visibility("default"))) // 明确指示,这个函数在动态库中可见
extern "C" TEST_API void sayHello()
{
std::cout << "hello!!!" << std::endl;
printf("hello!!!\n");
}
//main.cc
#include <dlfcn.h>
#include <iostream>
typedef void (*FUNC_test)();
int main()
{
void *handle = dlopen("./test.so", RTLD_NOW | RTLD_DEEPBIND);
if (!handle)
{
std::cout << "dlopen error" << std::endl;
return -1;
}
FUNC_test test_func = (FUNC_test)dlsym(handle, "sayHello");
if (!test_func)
{
std::cout << "dlsym error" << std::endl;
dlclose(handle);
return -1;
}
test_func();
dlclose(handle);
return 0;
}
执行命令编译生成动态库及main测试程序
g++ -fPIC -shared -o test.so test.cc
g++ -o main main.cc -ldl
可以看到,运行测试程序时报错Segmentation fault
通过一番查找,发现是gcc的一个bug,当导出方法中使用了std相关,则会导致该错误。
注释之后发现正常运行
当然,如果dlopen时不加RTLD_DEEPBIND参数,则不会出现该问题,一般不加。