在 dlopen 上检测重复的符号
Detect duplicate symbols at dlopen
在我的 Linux 应用程序中,我通过 dlopen
使用插件架构。正在用 打开共享对象
DLOPEN(路径, RTLD_GLOBAL |RTLD_LAZY('
选项RTLD_GLOBAL
是必需的,因为插件需要访问常见的 RTTI 信息。偶尔会发生某些插件导出相同的符号。这通常不应该发生,但是当它发生时,它会导致随机段错误,并且很难调试。所以我想在 dlopen 上检测重复的符号并警告它们。
有没有办法做到这一点?
这里有一个简单的例子来说明这一点。主可执行文件的代码是
#include <string>
#include <dlfcn.h>
#include <iostream>
#include <cassert>
typedef void (*Function)();
void open(const std::string& soname)
{
void* so = dlopen(soname.c_str(), RTLD_LAZY | RTLD_GLOBAL);
if (!so) {
std::cout << dlerror() << std::endl;
} else {
Function function = reinterpret_cast<Function>(dlsym(so, "f"));
assert(function);
function();
}
}
int main()
{
open("./a.so");
open("./b.so");
return 0;
}
它是由指挥部建造的g++ main.cpp -o main -ldl
a.so
和b.so
正在建造
#include <iostream>
void g()
{
std::cout << "a.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
和
#include <iostream>
void g()
{
std::cout << "b.cpp" << std::endl;
}
extern "C" {
void f()
{
g();
}
}
分别通过命令g++ -fPIC a.cpp -share -o a.so
和g++ -fPIC b.cpp -share -o b.so
。现在,如果我执行./main
我会得到
a.cpp
a.cpp
有了RTLD_LOCAL
我得到
a.cpp
b.cpp
但正如我所解释的,我不会RTLD_LOCAL
.
我想在 dlopen 检测重复的符号并警告它们。
我认为dlopen
做不到。
即使可以,在运行时检测到该问题也可能为时已晚。您应该在构建时检测到该问题,并且作为构建后步骤这样做是微不足道的:
nm -D your_plugin_dir/*.so | egrep ' [TD] ' | cut -d ' ' -f3 |
sort | uniq -c | grep -v ' 1 '
如果你得到任何输出,你有重复的符号(一些重复的符号实际上可能没问题;你必须过滤掉"已知良好"的重复
相关文章:
- 使用CMake检测支持的C++标准
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 将无符号char*转换为std::istream*C++
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 当套接字连接断开时检测C/C++Unix
- vscode g++链路故障:体系结构x86_64的未定义符号
- 检测 COFF 对象文件中C++内联符号
- 检测键按事件 - Qt C++上的插入符号 (^) 键
- "signbit"与乘法检测到的符号变化,并将其与零进行比较
- C++大量(无符号长长)的溢出检测
- 如何检测多重定义的符号
- Sobel 边缘检测错误(OpenCV 错误:断言失败 (DIMS<=2&&Data&&(无符号)i0)
- Visual Studio 2008,检测内存泄漏,符号"__FILE__"未定义
- c++类不检测符号链接
- 由于忘记了源文件,在链接我自己的静态库时检测未解析的符号
- 在 dlopen 上检测重复的符号
- 检测无意的弱链接符号
- 检测圆括号,括号和大括号是否平衡的c++程序-需要在错误下输出插入符号
- 如何检测无符号整数溢出