c-具有相同名称的新二进制文件上的dlopen返回旧句柄

我正在使用dlopen加载动态生成的代码.该程序在代码上调用编译器,并生成一个.so文件,然后由程序加载以扩展自身.

问题是,如果我对生成的代码使用相同的名称,则dlopen将返回旧对象的句柄,而不是新对象的句柄.

代码如下:

…generate code into test.cpp
system("gcc <args> test.cpp -o test.so");
void *handle = dlopen("test.so");
void *sym = dlsym(handle, "run");
(*sym)();
dlclose(handle);
…Do other work
…generate different code to test.cpp
system("gcc <args> test.cpp -o test.so");
void *handle = dlopen("test.so");
void *sym = dlsym(handle, "run");
(*sym)();
<crash here because the code isn't what was expected>

这是dlopen缓存代码中的基本缺陷还是在dlopen中众所周知但未充分记录?

解决方法:

最有可能的dlclose未能卸载该库.当它包含GNU_UNIQUE symbols时通常会发生这种情况(如果与静态libstdc链接,它通常会潜入).可以通过以下方式验证

$readelf -sW --dyn-syms path/to/libxyz.so | grep '\bUNIQUE\b'
...
3808: 0000000000302e78     8 OBJECT  UNIQUE DEFAULT   27 _ZNSt8messagesIcE2idE@@GLIBCXX_3.4

要解决此问题,您可以尝试以下方法之一:

>使用-fvisibility = hidden和__attribute __((visibility(“ default”))))构建库以隐藏唯一的符号
>使用-Wl,-version-script构建以达到相同的效果
>使用配置了–disable-gnu-unique-object的工具链构建shlib(请参见discussion in GCC list)

上一篇:在Linux上,什么会导致dlopen发出SIGFPE?


下一篇:c – Static Vs动态库