项目中需要使用到rabbitmq-c作为客户端生产数据,rabbitmq-c下载0.11.0版本,自己编译环境默认安装了openssl1.0.0
rabbitmq-c版本:0.11.0
openssl版本:1.0.0
编译后使用ssl相关代码会发生如下错误:
#4 0x00007fe50e440ce9 in __run_exit_handlers () from /lib64/libc.so.6
#5 0x00007fe50e440d37 in exit () from /lib64/libc.so.6
#6 0x00000000004119e5 in OutputBacktrace (sig=11) at /data1/wanglei88/projectCode/msgHandler/keliuliang122/app/crashcore/crashcore.c:121
#7 <signal handler called>
#8 0x00007fe50e7e036b in pthread_rwlock_wrlock () from /lib64/libpthread.so.0
#9 0x00007fe50d7428b0 in CRYPTO_THREAD_write_lock (lock=0x0) at crypto/threads_pthread.c:78
#10 0x00007fe50d742a62 in CRYPTO_atomic_add (val=0x7fe4b802a860, amount=-1, ret=0x7fe50a22e77c, lock=0x0) at crypto/threads_pthread.c:171
#11 0x00007fe50d5c3b8f in BIO_free (a=0x7fe4b802a810) at crypto/bio/bio_lib.c:117
#12 0x00007fe50d5c4db7 in BIO_free_all (bio=0x0) at crypto/bio/bio_lib.c:691
#13 0x00007fe50d0d63db in SSL_free () from ./libssl.so.1.0.0
#14 0x00007fe510750a88 in amqp_ssl_socket_open () from ./librabbitmq.so.4
1. 排查源码发现是: 接口中下发BIO_new的接口实现有问题,导致free的时候崩溃,故需要使用官网说的openssl1.1.1版本以上的库进行编译:
static int amqp_ssl_socket_open(void *base, const char *host, int port,
const struct timeval *timeout)
bio = BIO_new(amqp_openssl_bio());
if (!bio) {
status = AMQP_STATUS_NO_MEMORY;
goto error_out2;
}
编译流程及问题处理:
1.编译openssl 1.1.1m
1)./config --prefix=/home/soft/myself
2)make
3)make install
2.编译rabbitmq-c(0.11.0)
1)mkdir build
2)cd build
3)cmake ..
-- The C compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMAKE_BUILD_TYPE not specified. Creating Release build
-- Found C inline keyword: inline
-- Looking for getaddrinfo
-- Looking for getaddrinfo - found
-- Looking for socket
-- Looking for socket - found
-- Looking for poll
-- Looking for poll - found
-- Looking for clock_gettime in rt
-- Looking for clock_gettime in rt - found
-- Looking for posix_spawnp in rt
-- Looking for posix_spawnp in rt - found
-- Found OpenSSL: /usr/lib/x86_64-linux-gnu/libcrypto.so (found suitable version "1.0.1f", minimum required is "0.9.8")
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Check if compiler accepts -pthread
-- Check if compiler accepts -pthread - yes
-- Found Threads: TRUE
-- Performing Test HAVE_GNU90
-- Performing Test HAVE_GNU90 - Success
-- Could NOT find POPT (missing: POPT_INCLUDE_DIR POPT_LIBRARY) (found version "")
CMake Warning (dev) at /opt/cmake/cmake-3.17.2-Linux-x86_64/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:272 (message):
The package name passed to `find_package_handle_standard_args` (XMLTO) does
not match the name of the calling package (XmlTo). This can lead to
problems in calling code that expects `find_package` result variables
(e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
cmake/FindXmlTo.cmake:13 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:253 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
-- Could NOT find XMLTO (missing: XMLTO_EXECUTABLE)
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Building rabbitmq as a shared library - yes
-- Building rabbitmq as a static library - yes
-- Configuring done
-- Generating done
-- Build files have been written to:
从cmake结果看引用的openssl库是原/usr/lib/x86_64-linux-gnu/路径下库,故需要指定是编译过的openssl1.1.1m的库
2. 将CMakeList.txt中比对OPENSSL的版本修改为1.1.1
if (ENABLE_SSL_SUPPORT)
find_package(OpenSSL 0.9.8 REQUIRED) //此处修改为比较1.1.1版本
cmake_push_check_state()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
cmake_pop_check_state()
endif()
重新cmake(删除之前编译出的成果物):
cmake ..
-- The C compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- CMAKE_BUILD_TYPE not specified. Creating Release build
-- Found C inline keyword: inline
-- Looking for getaddrinfo
-- Looking for getaddrinfo - found
-- Looking for socket
-- Looking for socket - found
-- Looking for poll
-- Looking for poll - found
-- Looking for clock_gettime in rt
-- Looking for clock_gettime in rt - found
-- Looking for posix_spawnp in rt
-- Looking for posix_spawnp in rt - found
CMake Error at /opt/cmake/cmake-3.17.2-Linux-x86_64/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR: Found unsuitable version "1.0.1f", but
required is at least "1.1.1" (found /usr/lib/x86_64-linux-gnu/libcrypto.so)
Call Stack (most recent call first):
/opt/cmake/cmake-3.17.2-Linux-x86_64/share/cmake-3.17/Modules/FindPackageHandleStandardArgs.cmake:443 (_FPHSA_FAILURE_MESSAGE)
/opt/cmake/cmake-3.17.2-Linux-x86_64/share/cmake-3.17/Modules/FindOpenSSL.cmake:450 (find_package_handle_standard_args)
CMakeLists.txt:122 (find_package)
-- Configuring incomplete, errors occurred!
编译报错,需要指定OPENSSL_ROOT_DIR
3. 指定OPENSSL_ROOT_DIR为之前编译的openssl库的位置,指定后需要还原CMakeList.txt
export OPENSSL_ROOT_DIR=/home/soft/myself/lib
重新cmake (删除之前编译出的成果物)
cmake ..
cmake --build .
编译报错:
Scanning dependencies of target amqp_ssl_connect
[ 34%] Building C object examples/CMakeFiles/amqp_ssl_connect.dir/amqp_ssl_connect.c.o
[ 35%] Building C object examples/CMakeFiles/amqp_ssl_connect.dir/utils.c.o
[ 37%] Building C object examples/CMakeFiles/amqp_ssl_connect.dir/unix/platform_utils.c.o
[ 38%] Linking C executable amqp_ssl_connect
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `sk_pop_free'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `CRYPTO_set_locking_callback'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `sk_value'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `SSL_load_error_strings'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `CONF_modules_free'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `ENGINE_cleanup'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `ERR_free_strings'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `EVP_cleanup'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `CRYPTO_num_locks'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `SSLv23_client_method'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `sk_num'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `SSL_library_init'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `CRYPTO_set_id_callback'
../librabbitmq/librabbitmq.so.4.5.0: undefined reference to `CRYPTO_cleanup_all_ex_data'
collect2: error: ld returned 1 exit status
make[2]: *** [examples/amqp_ssl_connect] Error 1
4.需要指定头文件:
重新cmake (删除之前编译出的成果物)
1) cmake -DOPENSSL_CRYPTO_LIBRARIES=/home/soft/myself/lib/ -DOPENSSL_INCLUDE_DIR==/home/soft/myself/include/ -DOPENSSL_SSL_LIBRARIES==/home/soft/myself/lib ..
2) make
//成功
Scanning dependencies of target test_parse_url
[ 92%] Building C object tests/CMakeFiles/test_parse_url.dir/test_parse_url.c.o
[ 93%] Linking C executable test_parse_url
[ 93%] Built target test_parse_url
Scanning dependencies of target test_tables
[ 94%] Building C object tests/CMakeFiles/test_tables.dir/test_tables.c.o
[ 95%] Linking C executable test_tables
[ 95%] Built target test_tables
Scanning dependencies of target test_sasl_mechanism
[ 96%] Building C object tests/CMakeFiles/test_sasl_mechanism.dir/test_sasl_mechanism.c.o
[ 97%] Linking C executable test_sasl_mechanism
[ 97%] Built target test_sasl_mechanism
Scanning dependencies of target test_basic
[ 98%] Building C object tests/CMakeFiles/test_basic.dir/test_basic.c.o
[100%] Linking C executable test_basic
[100%] Built target test_basic
后使用重新生成的rabbitmq和opennssl1.1.1m,程序运行正常
注:文中描述有错误的地方请各位看官及时指正