This is happening with Asio V1.29.0 (non-Boost) on Windows 10. I have also tried using the code from master and it still causes the crash.
I compile with Visual Studio 2022 V17.8.3 and /std:C++20. I am using coroutines and the following experimental classes:
awaitable_operators
concurrent_channel
Brief Description of Asio Usage
A std::thread is using the asio::concurrent_channel to send a std::sting to coroutines running in an asio::thread_pool. The thread pool size is 2. An asio coroutine is started using asio::co_spawn that after opening a socket does a
and then reads data from socket or processes std::string from concurrent_channel.
Crash Details
This is emit method from cancellationsignal where handler is nullptr and the dereference of handler_ is done for call method.:
/// Emits the signal and causes invocation of the slot's handler, if any.
void emit(cancellation_type_t type)
{
if (handler_)
handler_->call(type);
}
Visual Studio showing the nullptr value for handler_:
Call Stack
```
ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 28
ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 154
ucrtbased.dll!abort() Line 61
vcruntime140d.dll!_purecall() Line 30
MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99
MyProg.exe!asio::cancellation_state::impl,asio::cancellation_filter<1>>::operator()(asio::cancellation_type in) Line 222
MyProg.exe!asio::detail::cancellation_handler,asio::cancellation_filter<1>>>::call(asio::cancellation_type type) Line 56
MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99
MyProg.exe!asio::detail::co_spawn_cancellation_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,void>::operator()(asio::cancellation_type type) Line 279
MyProg.exe!asio::detail::cancellation_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,void>>::call(asio::cancellation_type type) Line 56
MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99
MyProg.exe!asio::experimental::detail::parallel_group_op_handler<0,asio::experimental::wait_for_one_success,asio::detail::awaitable_async_op_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>::operator()(std::exception_ptr ) Line 225
MyProg.exe!asio::detail::co_spawn_entry_point::__l2::::operator()() Line 207
MyProg.exe!asio::detail::binder0<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>::operator()() Line 56
MyProg.exe!asio::detail::executor_function::complete,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>,std::allocator>(asio::detail::executor_function::impl_base * base, bool call) Line 112
MyProg.exe!asio::detail::executor_function::operator()() Line 62
MyProg.exe!asio::io_context::basic_executor_type,4>::execute(asio::detail::executor_function && f) Line 282
MyProg.exe!asio::execution::detail::any_executor_base::execute_ex,4>>(const asio::execution::detail::any_executor_base & ex, asio::detail::executor_function && f) Line 900
MyProg.exe!asio::execution::detail::any_executor_base::execute,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>>(asio::detail::binder0<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::> && f) Line 680
MyProg.exe!asio::detail::initiate_dispatch_with_executor::operator()<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>(asio::detail::co_spawn_entry_point::__l2:: && handler, void * __formal, void * __formal) Line 105
MyProg.exe!??@e461c3c8f1d18d37e393182ac754932e@(asio::detail::initiate_dispatch_with_executor && initiation, asio::detail::co_spawn_entry_point::__l2:: && token) Line 275
MyProg.exe!asio::async_initiate<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::,void __cdecl(void),asio::detail::initiate_dispatch_with_executor>(asio::detail::initiate_dispatch_with_executor && initiation, asio::detail::co_spawn_entry_point::__l2:: & token) Line 573
MyProg.exe!asio::dispatch,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>(const asio::any_io_executor & ex, asio::detail::co_spawn_entry_point::__l2:: && token, int __formal) Line 155
MyProg.exe!asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>(asio::awaitable * $FP2, asio::detail::co_spawn_state,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function,void> s) Line 203
MyProg.exe!std::coroutine_handle::resume() Line 85
MyProg.exe!asio::detail::awaitable_frame_base::resume() Line 501
MyProg.exe!asio::detail::awaitable_thread::pump() Line 769
MyProg.exe!asio::detail::awaitable_handler::operator()(const std::error_code & ec) Line 93
MyProg.exe!asio::detail::binder1,std::error_code>::operator()() Line 116
MyProg.exe!asio::detail::handler_work,asio::any_io_executor,void>::complete,std::error_code>>(asio::detail::binder1,std::error_code> & function, asio::detail::awaitable_handler & handler) Line 433
MyProg.exe!asio::detail::win_iocp_wait_op,asio::any_io_executor>::do_complete(void * owner, asio::detail::win_iocp_operation * base, const std::error_code & result_ec, unsigned __int64 __formal) Line 112
MyProg.exe!asio::detail::win_iocp_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 47
MyProg.exe!asio::detail::win_iocp_socket_service_base::reactor_op_cancellation::do_complete(void * owner, asio::detail::win_iocp_operation * base, const std::error_code & result_ec, unsigned __int64 bytes_transferred) Line 762
MyProg.exe!asio::detail::win_iocp_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 47
MyProg.exe!asio::detail::win_iocp_io_context::do_one(unsigned long msec, asio::detail::win_iocp_thread_info & this_thread, std::error_code & ec) Line 475
MyProg.exe!asio::detail::win_iocp_io_context::run(std::error_code & ec) Line 205
MyProg.exe!asio::io_context::run() Line 63
MyProg.exe!pac::PortASIOCtx::getIOContext::__l48::::operator()() Line 998
MyProg.exe!asio::detail::binder0<`pac::PortASIOCtx::getIOContext'::`48'::>::operator()() Line 56
MyProg.exe!asio::detail::executor_op>,std::allocator,asio::detail::scheduler_operation>::do_complete(void * owner, asio::detail::scheduler_operation * base, const std::error_code & __formal, unsigned __int64 __formal) Line 69
MyProg.exe!asio::detail::scheduler_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 40
MyProg.exe!asio::detail::scheduler::do_run_one(asio::detail::conditionally_enabled_mutex::scoped_lock & lock, asio::detail::scheduler_thread_info & this_thread, const std::error_code & ec) Line 493
MyProg.exe!asio::detail::scheduler::run(std::error_code & ec) Line 209
MyProg.exe!asio::thread_pool::thread_function::operator()() Line 38
MyProg.exe!asio::detail::win_thread::func::run() Line 122
MyProg.exe!asio::detail::win_thread_function(void * arg) Line 126
ucrtbased.dll!thread_start(void * const parameter) Line 97
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
```
Notes
I have written a small peiece of code to try to repro the issue but have not been able to get it to reproduce with the snipit. Reproducing with the full program sometimes takes a while.
I have a dump file from Windows but can't make that public.
Environment Info
This is happening with Asio V1.29.0 (non-Boost) on Windows 10. I have also tried using the code from master and it still causes the crash.
I compile with Visual Studio 2022 V17.8.3 and
/std:C++20
. I am using coroutines and the following experimental classes:Brief Description of Asio Usage
A std::thread is using the asio::concurrent_channel to send a std::sting to coroutines running in an asio::thread_pool. The thread pool size is 2. An asio coroutine is started using asio::co_spawn that after opening a socket does a
and then reads data from socket or processes std::string from concurrent_channel.
Crash Details
This is emit method from cancellationsignal where handler is nullptr and the dereference of handler_ is done for call method.:
Visual Studio showing the nullptr value for handler_:
Call Stack
``` ucrtbased.dll!issue_debug_notification(const wchar_t * const message) Line 28 ucrtbased.dll!__acrt_report_runtime_error(const wchar_t * message) Line 154 ucrtbased.dll!abort() Line 61 vcruntime140d.dll!_purecall() Line 30 MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99 MyProg.exe!asio::cancellation_state::impl,asio::cancellation_filter<1>>::operator()(asio::cancellation_type in) Line 222
MyProg.exe!asio::detail::cancellation_handler,asio::cancellation_filter<1>>>::call(asio::cancellation_type type) Line 56
MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99
MyProg.exe!asio::detail::co_spawn_cancellation_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,void>::operator()(asio::cancellation_type type) Line 279
MyProg.exe!asio::detail::cancellation_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,void>>::call(asio::cancellation_type type) Line 56
MyProg.exe!asio::cancellation_signal::emit(asio::cancellation_type type) Line 99
MyProg.exe!asio::experimental::detail::parallel_group_op_handler<0,asio::experimental::wait_for_one_success,asio::detail::awaitable_async_op_handler,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>::operator()(std::exception_ptr ) Line 225
MyProg.exe!asio::detail::co_spawn_entry_point::__l2::::operator()() Line 207
MyProg.exe!asio::detail::binder0<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>::operator()() Line 56
MyProg.exe!asio::detail::executor_function::complete,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>,std::allocator>(asio::detail::executor_function::impl_base * base, bool call) Line 112
MyProg.exe!asio::detail::executor_function::operator()() Line 62
MyProg.exe!asio::io_context::basic_executor_type,4>::execute(asio::detail::executor_function && f) Line 282
MyProg.exe!asio::execution::detail::any_executor_base::execute_ex,4>>(const asio::execution::detail::any_executor_base & ex, asio::detail::executor_function && f) Line 900
MyProg.exe!asio::execution::detail::any_executor_base::execute,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>>(asio::detail::binder0<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::> && f) Line 680
MyProg.exe!asio::detail::initiate_dispatch_with_executor::operator()<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>(asio::detail::co_spawn_entry_point::__l2:: && handler, void * __formal, void * __formal) Line 105
MyProg.exe!??@e461c3c8f1d18d37e393182ac754932e@(asio::detail::initiate_dispatch_with_executor && initiation, asio::detail::co_spawn_entry_point::__l2:: && token) Line 275
MyProg.exe!asio::async_initiate<`asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::,void __cdecl(void),asio::detail::initiate_dispatch_with_executor>(asio::detail::initiate_dispatch_with_executor && initiation, asio::detail::co_spawn_entry_point::__l2:: & token) Line 573
MyProg.exe!asio::dispatch,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>'::`2'::>(const asio::any_io_executor & ex, asio::detail::co_spawn_entry_point::__l2:: && token, int __formal) Line 155
MyProg.exe!asio::detail::co_spawn_entry_point,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function>(asio::awaitable * $FP2, asio::detail::co_spawn_state,std::exception_ptr,std::exception_ptr,std::string),asio::any_io_executor>,asio::deferred_async_operation,asio::detail::awaitable_as_function>,asio::deferred_async_operation,asio::detail::awaitable_as_function>>,asio::any_io_executor,asio::detail::awaitable_as_function,void> s) Line 203
MyProg.exe!std::coroutine_handle::resume() Line 85
MyProg.exe!asio::detail::awaitable_frame_base::resume() Line 501
MyProg.exe!asio::detail::awaitable_thread::pump() Line 769
MyProg.exe!asio::detail::awaitable_handler::operator()(const std::error_code & ec) Line 93
MyProg.exe!asio::detail::binder1,std::error_code>::operator()() Line 116
MyProg.exe!asio::detail::handler_work,asio::any_io_executor,void>::complete,std::error_code>>(asio::detail::binder1,std::error_code> & function, asio::detail::awaitable_handler & handler) Line 433
MyProg.exe!asio::detail::win_iocp_wait_op,asio::any_io_executor>::do_complete(void * owner, asio::detail::win_iocp_operation * base, const std::error_code & result_ec, unsigned __int64 __formal) Line 112
MyProg.exe!asio::detail::win_iocp_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 47
MyProg.exe!asio::detail::win_iocp_socket_service_base::reactor_op_cancellation::do_complete(void * owner, asio::detail::win_iocp_operation * base, const std::error_code & result_ec, unsigned __int64 bytes_transferred) Line 762
MyProg.exe!asio::detail::win_iocp_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 47
MyProg.exe!asio::detail::win_iocp_io_context::do_one(unsigned long msec, asio::detail::win_iocp_thread_info & this_thread, std::error_code & ec) Line 475
MyProg.exe!asio::detail::win_iocp_io_context::run(std::error_code & ec) Line 205
MyProg.exe!asio::io_context::run() Line 63
MyProg.exe!pac::PortASIOCtx::getIOContext::__l48::::operator()() Line 998
MyProg.exe!asio::detail::binder0<`pac::PortASIOCtx::getIOContext'::`48'::>::operator()() Line 56
MyProg.exe!asio::detail::executor_op>,std::allocator,asio::detail::scheduler_operation>::do_complete(void * owner, asio::detail::scheduler_operation * base, const std::error_code & __formal, unsigned __int64 __formal) Line 69
MyProg.exe!asio::detail::scheduler_operation::complete(void * owner, const std::error_code & ec, unsigned __int64 bytes_transferred) Line 40
MyProg.exe!asio::detail::scheduler::do_run_one(asio::detail::conditionally_enabled_mutex::scoped_lock & lock, asio::detail::scheduler_thread_info & this_thread, const std::error_code & ec) Line 493
MyProg.exe!asio::detail::scheduler::run(std::error_code & ec) Line 209
MyProg.exe!asio::thread_pool::thread_function::operator()() Line 38
MyProg.exe!asio::detail::win_thread::func::run() Line 122
MyProg.exe!asio::detail::win_thread_function(void * arg) Line 126
ucrtbased.dll!thread_start(void * const parameter) Line 97
kernel32.dll!BaseThreadInitThunk() Unknown
ntdll.dll!RtlUserThreadStart() Unknown
```
Notes
Thanks, SLDR (Stephen L. De Rudder)