问题
- 项目启动QWebsocketServer时卡住
- 打印日志如下
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_num_locks
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_set_id_callback
qt.network.ssl: QSslSocket: cannot resolve CRYPTO_set_locking_callback
qt.network.ssl: QSslSocket: cannot resolve ERR_free_strings
qt.network.ssl: QSslSocket: cannot resolve sk_new_null
qt.network.ssl: QSslSocket: cannot resolve sk_push
qt.network.ssl: QSslSocket: cannot resolve sk_free
qt.network.ssl: QSslSocket: cannot resolve sk_num
qt.network.ssl: QSslSocket: cannot resolve sk_pop_free
qt.network.ssl: QSslSocket: cannot resolve sk_value
qt.network.ssl: QSslSocket: cannot resolve SSL_library_init
qt.network.ssl: QSslSocket: cannot resolve SSL_load_error_strings
qt.network.ssl: QSslSocket: cannot resolve SSL_get_ex_new_index
qt.network.ssl: QSslSocket: cannot resolve SSLv2_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv3_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv23_client_method
qt.network.ssl: QSslSocket: cannot resolve SSLv2_server_method
qt.network.ssl: QSslSocket: cannot resolve SSLv3_server_method
qt.network.ssl: QSslSocket: cannot resolve SSLv23_server_method
qt.network.ssl: QSslSocket: cannot resolve X509_STORE_CTX_get_chain
qt.network.ssl: QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf
qt.network.ssl: QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf
qt.network.ssl: QSslSocket: cannot resolve SSLeay
qt.network.ssl: QSslSocket: cannot resolve SSLeay_version
qt.network.ssl: QSslSocket: cannot call unresolved function SSLeay
qt.network.ssl: QSslSocket: cannot call unresolved function CRYPTO_num_locks
qt.network.ssl: QSslSocket: cannot call unresolved function CRYPTO_set_id_callback
qt.network.ssl: QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback
qt.network.ssl: QSslSocket: cannot call unresolved function SSL_library_init
qt.network.ssl: QSslSocket: cannot call unresolved function SSLv23_c
环境
- CentOS7, x64
- Qt 5.7.1
- 系统的 openssl 版本是1.1
原因
Qt 5.7 需要使用 1.0 版本的 openssl
解决方案
- 安装 openssl-1.0.2k
- 把 libssl.so.1.0.2k 和 libcrypto.so.1.0.2k 复制到项目库路径下,去掉后缀的版本号
处理过程
-
首先分析现象,程序卡在了创建一个启用了SecureMode的QWebSocketServer创建这里,跟代码看到openssl动态加载,再深入也看不出什么。结合项目是从CentOS6迁移到CentOS7的背景,按惯例推测是openssl版本差异导致。
-
查看日志,发现打印了一堆符号无法解析的错误,可以确定openssl没有正确加载。
-
在网络上搜索相关信息,发现是已经讨论过的问题:https://blog.csdn.net/u010168781/article/details/85632637,
文中提到Qt5.6需要使用openssl-1.0的版本,合理推测Qt5.7也有同样的限制。 -
首先在yum上搜索openssl的旧版本,没有找到,然后去rpm资源网上找了个1.0.2k的版本。安装后发现没有解决问题,不知道问题在哪里,决定自行编译。
-
从git上同步代码后进行编译,在编译到md2的时候报错了,说是要求禁用md2
#error MD2 is disabled
陆续加上许多no-选项,如no-md2、no-rc5、no-jpake和no-store,最后还是编译失败
undefined reference to
gcm_init_clmul
undefined reference togcm_gmult_clmul
undefined reference togcm_ghash_clmul
undefined reference togcm_gmult_4bit_x86
undefined reference togcm_ghash_4bit_x86
undefined reference togcm_gmult_4bit_mmx
undefined reference togcm_ghash_4bit_mmx
查看源代码,这些都未启用,可能是用perl生成的,perl不熟,无法继续。
在网络上搜索解决方案未果,推测是这个分支后来又被改过,导致无法编译。
于是下载tag包进行编译,编译顺利,config里只需要加一个share-enabled生成动态库就行了。
然后把这个放进项目库路径里,但还是报了相同的错误。 -
查看项目使用的cpu架构位数,是32位,与编译的不同。这个应该是第5步没有解决问题的原因。
-
整交叉编译链太麻烦,找到之前安装的rpm包的库位置,发现库是这样的
/usr/lib/libssl.a
/usr/lib/libssl.so -> libssl.so.1.1
/usr/lib/libssl.so.10 -> libssl.so.1.0.2k
/usr/lib/libssl.so.1.0.2k
/usr/lib/libssl.so.1.1这个libssl.so在安装完rpm后根本没有指向1.0.2k的版本,这是第4步没有解决问题的原因。
-
把 libssl.so.1.0.2k 和 libcrypto.so.1.0.2k 复制到项目库路径下,正常运行,问题解决。