-
Notifications
You must be signed in to change notification settings - Fork 230
Description
Describe the bug
When using ccapi WebSocket (WS/WSS) connections, the application may abort at runtime with a Boost.Beast assertion failure:
Assertion `!impl_->read.pending || !impl_->write.pending' failed
This crash is triggered by calling boost::beast::basic_stream::expires_after() while there are pending asynchronous read/write operations on the stream. This situation can occur during WebSocket connection establishment or automatic reconnection.
The issue originates from startConnectWs() in ccapi_service.h, where expires_after() is unconditionally called on the lowest-layer stream before async_connect().
To Reproduce
Steps to reproduce the behavior:
- Use ccapi with WebSocket (especially WSS) enabled
- Enable automatic reconnect or run under conditions with frequent reconnects / concurrent read-write activity
- Let the application run for some time (the crash is timing-dependent)
- Observe that the process aborts with a Boost.Beast assertion failure
Typical stack trace points to:
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007aca83e4527e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007aca83e288ff in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007aca83e2881b in __assert_fail_base (fmt=0x7aca83fd01e8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x7aca82e02d88 "! impl_->read.pending || ! impl_->write.pending",
file=file@entry=0x7aca82e02d48 "/home/mydeps/include/boost/beast/core/impl/basic_stream.hpp", line=line@entry=711,
function=function@entry=0x7aca82e02bd8 "void boost::beast::basic_stream< <template-parameter-1-1>, <template-parameter-1-2>, <template-parameter-1-3> >::expires_after(std::chrono::nanoseconds) [with Protocol = boost::asio::ip::tcp; Executor"...) at ./assert/assert.c:96
#6 0x00007aca83e3b517 in __assert_fail (assertion=0x7aca82e02d88 "! impl_->read.pending || ! impl_->write.pending", file=0x7aca82e02d48 "/home/mydeps/include/boost/beast/core/impl/basic_stream.hpp",
line=711,
function=0x7aca82e02bd8 "void boost::beast::basic_stream< <template-parameter-1-1>, <template-parameter-1-2>, <template-parameter-1-3> >::expires_after(std::chrono::nanoseconds) [with Protocol = boost::asio::ip::tcp; Executor"...) at ./assert/assert.c:105
#7 0x00007aca829b9b40 in boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>::expires_after (this=0x7ac9d40df0b0,
expiry_time=std::chrono::duration = { 10000000000ns }) at /home/mydeps/include/boost/beast/core/impl/basic_stream.hpp:711
#8 0x00007aca82947512 in ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}::operator()<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> > >(std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >&) const (__closure=0x7ac9a3ffa4b0,
streamPtr=std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true>> (use count 1, weak count 0) = {...}) at /data/XX/../API/ccapi_cpp/service/ccapi_service.h:1001
#9 0x00007aca82a1cc6a in std::__invoke_impl<void, ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}, std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >&>(std::__invoke_other, ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >&) (__f=...)
at /usr/include/c++/13/bits/invoke.h:61
#10 0x00007aca829ed8bb in std::__invoke<ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}, std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >&>(ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >&) (__fn=...) at /usr/include/c++/13/bits/invoke.h:96
#11 0x00007aca829bcb94 in std::__detail::__variant::__gen_vtable_impl<std::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<void> (*)(ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&)>, std::integer_sequence<unsigned long, 0ul> >::__visit_invoke(ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&) (__visitor=...,
__vars#0=std::variant [index 0] containing std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true>> (use count 1, weak count 0) = {...}) at /usr/include/c++/13/variant:1060
#12 0x00007aca829bccbe in std::__do_visit<std::__detail::__variant::__deduce_visit_result<void>, ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&>(ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&) (__visitor=...) at /usr/include/c++/13/variant:1815
#13 0x00007aca829bcd35 in std::visit<ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&>(ccapi::Service::startConnectWs(std::shared_ptr<ccapi::WsConnection>, long, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)::{lambda(auto:1&)#1}&&, std::variant<std::shared_ptr<boost::beast::websocket::stream<boost::beast::ssl_stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy> >, true> >, std::shared_ptr<boost::beast::websocket::stream<boost::beast::basic_stream<boost::asio::ip::tcp, boost::asio::executor, boost::beast::unlimited_rate_policy>, true> > >&) (__visitor=...) at /usr/include/c++/13/variant:1878
#14 0x00007aca82947a37 in ccapi::Service::startConnectWs (this=0x7ac9a17fb020, wsConnectionPtr=std::shared_ptr<ccapi::WsConnection> (use count 3, weak count 0) = {...}, timeoutMilliseconds=10000,
tcpResolverResults=...) at /data/XX/../API/ccapi_cpp/service/ccapi_service.h:996
#15 0x00007aca829473cc in ccapi::Service::onResolveWs (this=0x7ac9a17fb020, wsConnectionPtr=std::shared_ptr<ccapi::WsConnection> (use count 3, weak count 0) = {...},
newResolverPtr=std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor>> (use count 1, weak count 0) = {...}, ec=..., tcpNewResolverResultsWs=...)
at /data/XX/API/ccapi_cpp/service/ccapi_service.h:992
#16 0x00007aca82bc1906 in std::__invoke_impl<void, void (ccapi::Service::* const&)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::ba--Type <RET> for more, q to quit, c to continue without paging--
sic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code const&, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> const&> (
__f=@0x7ac9a3ffa700: (void (ccapi::Service::*)(class ccapi::Service * const, class std::shared_ptr<ccapi::WsConnection>, class std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, class boost::system::error_code, class boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)) 0x7aca829472f2 <ccapi::Service::onResolveWs(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)>, __t=...)
at /usr/include/c++/13/bits/invoke.h:74
#17 0x00007aca82bb4bdb in std::__invoke<void (ccapi::Service::* const&)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code const&, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> const&> (
__fn=@0x7ac9a3ffa700: (void (ccapi::Service::*)(class ccapi::Service * const, class std::shared_ptr<ccapi::WsConnection>, class std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, class boost::system::error_code, class boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)) 0x7aca829472f2 <ccapi::Service::onResolveWs(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>)>)
at /usr/include/c++/13/bits/invoke.h:96
#18 0x00007aca82ba2a58 in std::_Mem_fn_base<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), true>::operator()<std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code const&, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> const&> (this=0x7ac9a3ffa700)
at /usr/include/c++/13/functional:170
#19 0x00007aca82b9090d in boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >::invoke<0ul, 1ul, 2ul, boost::system::error_code const&, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> const&> (
this=0x7ac9a3ffaa90) at /home/mydeps/include/boost/beast/core/detail/bind_handler.hpp:235
#20 0x00007aca82b82cea in boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >::operator()<boost::system::error_code const&, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> const&> (
this=0x7ac9a3ffaa90) at /home/mydeps/include/boost/beast/core/detail/bind_handler.hpp:258
#21 0x00007aca82b74e2b in boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >::operator() (
this=0x7ac9a3ffaa90) at /home/mydeps/include/boost/asio/detail/bind_handler.hpp:164
#22 0x00007aca82b74da8 in boost::asio::asio_handler_invoke<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> > > (function=...) at /home/mydeps/include/boost/asio/handler_invoke_hook.hpp:69
#23 0x00007aca82b630fc in boost::beast::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >&> (f=..., op=0x7ac9a3ffaa90) at /home/mydeps/include/boost/beast/core/detail/bind_handler.hpp:272
#24 0x00007aca82b4bd39 in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >, boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > > > (function=..., context=...) at /home/mydeps/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#25 0x00007aca82b2d3b8 in boost::asio::detail::asio_handler_invoke<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >, boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> > (function=...,
this_handler=0x7ac9a3ffaa90) at /home/mydeps/include/boost/asio/detail/bind_handler.hpp:207
#26 0x00007aca82b12ad1 in boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >, boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> > > (
function=..., context=...) at /home/mydeps/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#27 0x00007aca82af7740 in boost::asio::detail::io_object_executor<boost::asio::executor>::dispatch<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_p--Type <RET> for more, q to quit, c to continue without paging--
tr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> >, std::allocator<void> > (this=0x7ac9a3ffaa80, f=..., a=...) at /home/mydeps/include/boost/asio/detail/io_object_executor.hpp:119
#28 0x00007aca82ad7343 in boost::asio::detail::handler_work<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::asio::detail::io_object_executor<boost::asio::executor>, boost::asio::detail::io_object_executor<boost::asio::executor> >::complete<boost::asio::detail::binder2<boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp> > >
(this=0x7ac9a3ffaa70, function=..., handler=...) at /home/mydeps/include/boost/asio/detail/handler_work.hpp:72
#29 0x00007aca82ab5255 in boost::asio::detail::resolve_query_op<boost::asio::ip::tcp, boost::beast::detail::bind_front_wrapper<void (ccapi::Service::*)(std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> >, boost::system::error_code, boost::asio::ip::basic_resolver_results<boost::asio::ip::tcp>), std::shared_ptr<ccapi::Service>, std::shared_ptr<ccapi::WsConnection>, std::shared_ptr<boost::asio::ip::basic_resolver<boost::asio::ip::tcp, boost::asio::executor> > >, boost::asio::detail::io_object_executor<boost::asio::executor> >::do_complete (owner=0x6294ddd2a230, base=0x7ac99d988210) at /home/mydeps/include/boost/asio/detail/resolve_query_op.hpp:129
#30 0x00007aca828f03e6 in boost::asio::detail::scheduler_operation::complete (this=0x7ac99d988210, owner=0x6294ddd2a230, ec=..., bytes_transferred=0)
at /home/mydeps/include/boost/asio/detail/scheduler_operation.hpp:40
#31 0x00007aca828f5f48 in boost::asio::detail::scheduler::do_run_one (this=0x6294ddd2a230, lock=..., this_thread=..., ec=...) at /home/mydeps/include/boost/asio/detail/impl/scheduler.ipp:447
#32 0x00007aca828f57c5 in boost::asio::detail::scheduler::run (this=0x6294ddd2a230, ec=...) at /home/mydeps/include/boost/asio/detail/impl/scheduler.ipp:200
#33 0x00007aca828f95d8 in boost::asio::io_context::run (this=0x6294ddd0ed10) at /home/mydeps/include/boost/asio/impl/io_context.ipp:63
#34 0x00007aca82937a70 in ccapi::ServiceContext::start()::{lambda()#1}::operator()() const (__closure=0x6294ddc8e518)
at /data/XX/../API/ccapi_cpp/service/ccapi_service_context.h:73
#35 0x00007aca82df8321 in std::__invoke_impl<void, ccapi::ServiceContext::start()::{lambda()#1}>(std::__invoke_other, ccapi::ServiceContext::start()::{lambda()#1}&&) (__f=...)
at /usr/include/c++/13/bits/invoke.h:61
#36 0x00007aca82df8049 in std::__invoke<ccapi::ServiceContext::start()::{lambda()#1}>(ccapi::ServiceContext::start()::{lambda()#1}&&) (__fn=...) at /usr/include/c++/13/bits/invoke.h:96
#37 0x00007aca82df7854 in std::thread::_Invoker<std::tuple<ccapi::ServiceContext::start()::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) (this=0x6294ddc8e518)
at /usr/include/c++/13/bits/std_thread.h:292
#38 0x00007aca82df5fc6 in std::thread::_Invoker<std::tuple<ccapi::ServiceContext::start()::{lambda()#1}> >::operator()() (this=0x6294ddc8e518) at /usr/include/c++/13/bits/std_thread.h:299
#39 0x00007aca82df3770 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<ccapi::ServiceContext::start()::{lambda()#1}> > >::_M_run() (this=0x6294ddc8e510)
at /usr/include/c++/13/bits/std_thread.h:244
#40 0x00007aca842ecdb4 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#41 0x00007aca83e9caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#42 0x00007aca83f29c6c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Expected behavior
The application should not abort due to an internal assertion when managing WebSocket connections.
Timeout handling for WebSocket connections should be safe even when:
- there are pending asynchronous read/write operations
- WebSocket reconnect logic is active
- concurrent WebSocket I/O is occurring
At minimum, ccapi should avoid calling basic_stream::expires_after() in a way that violates Boost.Beast usage constraints.
Screenshots
N/A (runtime assertion failure / abort)
Additional context
-
Root cause
boost::beast::basic_stream::expires_after()must not be called while there are pending async read/write operations. Boost.Beast enforces this with a hard assertion and callsabort(). -
Location in code
File:include/ccapi_cpp/service/ccapi_service.h
Function:Service::startConnectWsif (timeoutMilliseconds > 0) { beast::get_lowest_layer(*streamPtr) .expires_after(std::chrono::milliseconds(timeoutMilliseconds)); }
-Why this is problematic:
In WebSocket / SSL / reconnect scenarios, the stream may already have pending I/O (e.g. leftover read/write operations or concurrent operations), making this call unsafe.
-Suggested fix:
Remove usage of basic_stream::expires_after() for WebSocket connections, and
Use websocket::stream_base::timeout::suggested(role_type::client) for WebSocket timeouts, or
Manage connect timeouts via an external asio::steady_timer instead.
Environment:
OS: Linux (Ubuntu)
Compiler: GCC 13.x
Boost: uses Boost.Beast / Boost.Asio
ccapi: current master branch (commit at time of report)
Crash signal: SIGABRT