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

标签 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 中没有详细记录的缺陷?

最佳答案

很可能 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)

关于c++ - dlopen 在具有相同名称的新二进制文件上返回旧句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50437892/

相关文章:

c++ - rand 的 dlsym() 使用失败

c++ - 在 Box2D 中找到夹具的中心

c++ - dlopen 从静态库中打开动态库,当动态库使用静态库的符号时

dll - 如何在 D 中创建动态库?

linux - 在符号和共享库之间强制映射

c - 带有运行时参数的 dlsym/dlopen

c - 动态库实际上在内存中的什么位置?

c++ - 双模板函数重载失败

c++ - 在另一个类中创建线程

c++ - Mac 上的 ASCII 字符问题。无法打印黑色方 block (即 char(219))