dlopen on new binary with same name返回旧句柄

时间:2018-05-20 18:03:55

标签: c++ dlopen dynamic-library

我正在使用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中没有详细记录的内容?

1 个答案:

答案 0 :(得分:3)

最可能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