显式调用C++动态库random.so触发SIGSEGV错误求助
问题原因与解决方案
问题原因分析
- 命令行参数缺失:运行
./example时未传入函数名参数,argv[1]为空指针,导致dlsym尝试查找空字符串对应的符号,必然失败,rand指针未被正确初始化,调用时触发段错误。 - C++名字修饰问题:C++编译器会对函数名进行名字修饰(Name Mangling),动态库中的
rand_int实际符号名并非原始的rand_int,而是经过编译器编码后的字符串,直接用dlsym查找rand_int会找不到目标符号,rand成为无效指针。 - 未检查
dlsym返回值:即使传入参数,代码也没有验证dlsym是否成功获取符号,一旦查找失败,调用无效指针会直接触发段错误。
解决方案
1. 修复命令行参数问题
运行程序时必须传入目标函数名参数,例如:
./example rand_int
同时在代码中增加参数合法性检查,避免空指针访问:
if (argc < 2) { fprintf(stderr, "Usage: %s <function_name>\n", argv[0]); return 1; }
2. 解决C++名字修饰问题
推荐采用以下两种方式之一:
- 方式一:用
extern "C"导出函数
修改头文件和库代码,让函数以C语言的规则导出,避免名字修饰:
// random.h #ifdef __cplusplus extern "C" { #endif int rand_int(int min, int max); #ifdef __cplusplus } #endif
// random.cpp #include <random> extern "C" { int rand_int(int min, int max) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<int> dist(min, max); return dist(gen); } }
重新编译动态库后,rand_int会以原始名字存在于库中,dlsym可以直接找到。
- 方式二:使用修饰后的符号名(不推荐)
先通过nm命令查看库中实际的符号名:
nm -D /home/nikita/Libraries/shared/librandom.so | grep rand_int
输出会是类似_Z8rand_intii的修饰名,运行程序时传入该名字即可:
./example _Z8rand_intii
该方式移植性差,不同编译器的修饰规则可能不同,仅作临时调试使用。
3. 增加dlsym错误检查
在调用dlsym后必须检查是否成功获取符号:
rand = (int (*)(int, int))dlsym(ext_library, argv[1]); char *err = dlerror(); if (err != nullptr) { fprintf(stderr, "dlsym() error: %s\n", err); dlclose(ext_library); return 1; }
4. 完整修复后的example.cpp代码
#include <cstdio> #include <dlfcn.h> int main(int argc, char *argv[]) { void *ext_library; int (*rand)(int, int); // 检查命令行参数 if (argc < 2) { fprintf(stderr, "Usage: %s <function_name>\n", argv[0]); return 1; } ext_library = dlopen("/home/nikita/Libraries/shared/librandom.so", RTLD_LAZY); if (!ext_library) { fprintf(stderr, "dlopen() error: %s\n", dlerror()); return 1; } // 获取函数符号并检查错误 rand = (int (*)(int, int))dlsym(ext_library, argv[1]); char *err = dlerror(); if (err != nullptr) { fprintf(stderr, "dlsym() error: %s\n", err); dlclose(ext_library); return 1; } printf("%d\n", (*rand)(0, 10)); dlclose(ext_library); return 0; }
内容的提问来源于stack exchange,提问作者user23561003
相关产品推荐
相关产品推荐

