动态加载libssl.so触发段错误问题求助
问题排查与解决方案
1. 修复代码中的致命问题
1.1 补全变量声明
代码中ssl_library未声明类型,属于隐式声明,会导致未定义行为,需在main函数内添加:
void *ssl_library;
1.2 检查dlsym返回值
如果符号查找失败,直接调用空指针会触发段错误,必须添加检查逻辑,同时用dlerror()获取具体错误信息:
SSL_library_init = (SSL_library_init_t)dlsym(ssl_library, "SSL_library_init"); if (!SSL_library_init) { printf("Failed to get SSL_library_init: %s\n", dlerror()); dlclose(ssl_library); return 1; } SSL_load_error_strings = (SSL_load_error_strings_t)dlsym(ssl_library, "SSL_load_error_strings"); if (!SSL_load_error_strings) { printf("Failed to get SSL_load_error_strings: %s\n", dlerror()); dlclose(ssl_library); return 1; }
1.3 处理依赖库加载
libssl.so依赖libcrypto.so,动态加载时需确保依赖库被正确初始化,可修改dlopen参数为RTLD_NOW | RTLD_GLOBAL,或先显式加载libcrypto.so:
// 先加载libcrypto.so void *crypto_library = dlopen("libcrypto.so", RTLD_NOW | RTLD_GLOBAL); if (!crypto_library) { printf("Failed to load libcrypto: %s\n", dlerror()); return 1; } // 再加载libssl.so ssl_library = dlopen("libssl.so", RTLD_NOW | RTLD_GLOBAL); if (!ssl_library) { printf("Failed to load libssl: %s\n", dlerror()); dlclose(crypto_library); return 1; }
2. 修正编译命令
x64编译时未链接libdl库,dlopen/dlsym等动态加载函数属于该库,必须添加-ldl参数,修改Makefile的x64-build目标:
x64-build: gcc $(IN) -Wall -ggdb3 -Wno-unused-but-set-variable -ldl
3. 适配OpenSSL版本问题
Ubuntu amd64默认安装的OpenSSL版本多为1.1.0及以上,SSL_library_init和SSL_load_error_strings已被废弃,内部实现依赖新的初始化逻辑。如果上述修复后仍报错,可改用新版初始化方式:
// 定义新版初始化函数类型 typedef int (*OPENSSL_init_ssl_t)(unsigned long opts, const void *settings); int main() { void *crypto_library = dlopen("libcrypto.so", RTLD_NOW | RTLD_GLOBAL); if (!crypto_library) { printf("Failed to load libcrypto: %s\n", dlerror()); return 1; } void *ssl_library = dlopen("libssl.so", RTLD_NOW | RTLD_GLOBAL); if (!ssl_library) { printf("Failed to load libssl: %s\n", dlerror()); dlclose(crypto_library); return 1; } OPENSSL_init_ssl_t OPENSSL_init_ssl = (OPENSSL_init_ssl_t)dlsym(ssl_library, "OPENSSL_init_ssl"); if (!OPENSSL_init_ssl) { printf("Failed to get OPENSSL_init_ssl: %s\n", dlerror()); dlclose(ssl_library); dlclose(crypto_library); return 1; } // 替代原SSL_library_init和SSL_load_error_strings的功能 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); dlclose(ssl_library); dlclose(crypto_library); return 0; }
验证步骤
- 编译x64版本:
make x64-build - 运行程序:
./app - 若仍有问题,用gdb定位崩溃点:
gdb ./app,执行run后输入bt查看调用栈。
内容的提问来源于stack exchange,提问作者misha
相关产品推荐
相关产品推荐

