c – 在dlopen处检测重复的符号
在我的
Linux应用程序中,我通过dlopen使用插件架构.正在打开共享对象
dlopen(path,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可以做到这一点. 即使它可以,在运行时检测到这个问题可能为时已晚.您应该在构建时检测到该问题,并且作为构建后步骤这样做是微不足道的: nm -D your_plugin_dir/*.so | egrep ' [TD] ' | cut -d ' ' -f3 | sort | uniq -c | grep -v ' 1 ' 如果你得到任何输出,你有重复的符号(一些重复的符号可能实际上是好的;你将必须过滤掉“已知的好”重复). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |