dlopen 在具有相同名称 returns 旧句柄的新二进制文件上
dlopen on new binary with same name returns old handle
我正在使用 dlopen 加载动态生成的代码。程序在代码上调用编译器并生成.so文件,然后由程序加载以扩展自身。
问题是,如果我对生成的代码使用相同的名称,dlopen returns 是旧对象的句柄,而不是新对象的句柄。
代码如下:
…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++ link,它往往会潜入)。这可以通过
验证
$ 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)
我正在使用 dlopen 加载动态生成的代码。程序在代码上调用编译器并生成.so文件,然后由程序加载以扩展自身。
问题是,如果我对生成的代码使用相同的名称,dlopen returns 是旧对象的句柄,而不是新对象的句柄。
代码如下:
…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++ link,它往往会潜入)。这可以通过
$ 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)