静态链接OpenSSL导致Qt应用程序出现段错误
我之前碰到过一模一样的坑,这问题本质上是静态链接的OpenSSL 1.1.0h和Qt动态依赖的系统OpenSSL库之间的符号冲突导致的。Qt的QNetworkAccessManager底层默认会调用系统安装的OpenSSL库(如果你的Qt是基于系统OpenSSL编译的),而你把另一版本的OpenSSL静态链接到了程序里——运行时两个版本的OpenSSL符号被同时加载,就会出现内存访问混乱,最终触发段错误。
下面是几个经过验证的解决方案,你可以根据自己的需求选择:
方案一:让Qt和libcurl共用同一版本的静态OpenSSL
重新编译Qt 4.8,指定使用你自己编译的OpenSSL 1.1.0h库。编译Qt时可以用这些配置参数(替换成你实际的路径):./configure -openssl -I/your/openssl/include/path -L/your/openssl/lib/path -static编译完成后用这个定制版Qt重新构建你的应用,这样Qt和libcurl就会使用完全相同的OpenSSL版本,从根源上消除符号冲突。
方案二:改用动态链接的libcurl
如果静态链接不是硬性要求,直接换成动态链接的libcurl会省心很多。只要确保系统的OpenSSL版本和libcurl依赖的版本兼容,程序就会统一调用系统的OpenSSL库,不会出现版本冲突的问题。方案三:用链接器参数隔离静态OpenSSL的符号
要是必须保留静态链接的方式,可以通过GCC链接器的符号隐藏参数,把静态OpenSSL的符号限制在libcurl内部可见,不让它们暴露给Qt的代码。在你的链接命令里加上:-Wl,--exclude-libs=libcrypto.a -Wl,--exclude-libs=libssl.a这样静态链接的OpenSSL符号只会被libcurl调用,不会和Qt依赖的系统OpenSSL符号产生冲突。
额外排查小技巧
你可以用nm命令检查可执行文件里的OpenSSL符号,确认是不是真的存在重复定义:nm -D your_app_executable | grep -i ssl_如果输出里同时出现了不同版本的SSL相关符号,那就实锤是符号冲突的问题了。
内容的提问来源于stack exchange,提问作者adnan kamili

