Description
On Linux (RH6, CppRest 2.10.16, Azure Storage SDK 7.3.1, Gcc 8.3.1) application is crashed with segmentation fault
Code snippet looks like:
//main.c
int main() {
foo_init();
foo_do();
foo_close();
}
//foo.c
foo_init() {
crossplat::threadpool::initialize_with_threads(40);
}
foo_do() {
//do something
}
foo_close() {
crossplat::threadpool::shared_instance().stop();
}
Backtrace looks like this:
#0 0x0000003557c75f8b in malloc_consolidate () from /lib64/libc.so.6
#1 0x0000003557c78c88 in _int_free () from /lib64/libc.so.6
#2 0x00007f491fafbc73 in bio_free () from libcrypto.so.1.1
#3 0x00007f491faf96aa in BIO_free () from libcrypto.so.1.1
#4 0x00007f491fafa9f4 in BIO_free_all () from libcrypto.so.1.1
#5 0x00007f491f7efa7f in SSL_free () from libssl.so.1.1
#6 0x0000000000e2d1e4 in std::_Sp_counted_ptr_inplace<web::http::client::details::asio_connection, std::allocatorweb::http::client::details::asio_connection, (__gnu_cxx::_Lock_policy)2>::_M_dispose() ()
#7 0x0000000000e2b9b3 in std::_Rb_tree<std::basic_string<char, std::char_traits, std::allocator >, std::pair<std::basic_string<char, std::char_traits, std::allocator > const, web::http::client::details::connection_pool_stackweb::http::client::details::asio_connection >, std::_Select1st<std::pair<std::basic_string<char, std::char_traits, std::allocator > const, web::http::client::details::connection_pool_stackweb::http::client::details::asio_connection > >, std::less<std::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::pair<std::basic_string<char, std::char_traits, std::allocator > const, web::http::client::details::connection_pool_stackweb::http::client::details::asio_connection > > >::_M_erase(std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits, std::allocator > const, web::http::client::details::connection_pool_stackweb::http::client::details::asio_connection > >*) ()
#8 0x0000000000e2d10a in std::_Sp_counted_ptr_inplace<web::http::client::details::asio_connection_pool, std::allocatorweb::http::client::details::asio_connection_pool, (__gnu_cxx::_Lock_policy)2>::_M_dispose() ()
#9 0x0000000000a4d358 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x2a10d50) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:155
#10 0x0000000000e2a17a in std::_Sp_counted_ptr_inplace<web::http::client::details::asio_client, std::allocatorweb::http::client::details::asio_client, (__gnu_cxx::_Lock_policy)2>::_M_dispose() ()
#11 0x0000000000deeab7 in std::_Sp_counted_ptr_inplace<web::http::client::http_pipeline, std::allocatorweb::http::client::http_pipeline, (__gnu_cxx::_Lock_policy)2>::_M_dispose() ()
#12 0x0000000000a4d358 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x2a0fd00) at /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/shared_ptr_base.h:155
#13 0x0000000000d2c747 in std::map<std::basic_string<char, std::char_traits, std::allocator >, std::shared_ptrweb::http::client::http_client, std::less<std::basic_string<char, std::char_traits, std::allocator > >, std::allocator<std::pair<std::basic_string<char, std::char_traits, std::allocator > const, std::shared_ptrweb::http::client::http_client > > >::~map() ()
#14 0x0000003557c35a02 in exit () from /lib64/libc.so.6
#15 0x0000003557c1ed27 in __libc_start_main () from /lib64/libc.so.6
#16 0x000000000047dcd1 in _start ()
The problem is raised in such conditions:
- Azure Storage SDK opens more than 1 connection to Azure
- Static variable boost::asio::io_service& s_service is deleted from http_client_reusable class. So, any indirect initialization
It looks that SSL_free() is called on structure while socket still is listen state
Workaround to fix the problem:
Either:
return back initialization of s_service or implement own global static variable with the same initialization:
boost::asio::io_service& g_service = crossplat::threadpool::shared_instance().service();
Or
put sleep() call before closing application
Or
call manually destructor of threadpool: crossplat::threadpool::shared_instance().~threadpool()