zhllxt / asio2

Header only c++ network library, based on asio,support tcp,udp,http,websocket,rpc,ssl,icmp,serial_port,socks5.
Boost Software License 1.0
800 stars 183 forks source link

求助单线程 IO 设置 #75

Closed AdjWang closed 2 minutes ago

AdjWang commented 3 days ago

您好,我想同时启动 http, tcp 和 udp 服务,并且让所有服务运行在单线程内,请问该如何配置? 我尝试下面这个代码,结果阻塞在 server.start 函数里了:

std::string_view host = "0.0.0.0";
std::string_view port = "8080";

auto io_ctx = std::make_shared<asio::io_context>(1);
asio2::http_server server(io_ctx.get());
// bind callbacks
// ...
server.start(host, port);
zhllxt commented 1 day ago

参考example\shared_iopool\shared_iopool.cpp的代码

    // 1 threads
    asio2::iopool iopool(1);

    // iopool must start first, othwise the server.start will blocked forever.
    iopool.start();

    asio2::tcp_server server1(iopool.get(0));
    asio2::http_server server2(iopool.get(0));

    // must call iopool.stop() before exit.
    iopool.stop();
AdjWang commented 17 hours ago

正常工作了,非常感谢!

AdjWang commented 12 hours ago

还想请教下析构时序问题。我有一部分需要运行时动态释放的asio2::tcp_server对象,另一些是全局的不必释放。如果 tcp_server.reset()iopool.stop() 之前执行就会出错,请问该如何正确释放 asio2::tcp_server

#include <iostream>

#include "asio2/asio2.hpp"

int main() {
    asio2::iopool iopool(1);
    iopool.start();
    auto tcp_server = std::make_unique<asio2::tcp_server>(iopool.get(0));
    // ... other static handles, never release
    tcp_server->start("0.0.0.0", "8080");
    std::cout << "tcp server stopped: " << tcp_server->is_stopped() << "\n";
    tcp_server->stop();
    std::cout << "tcp server stopped: " << tcp_server->is_stopped() << "\n";
    tcp_server.reset(); // <<<<<<<<<<<< how to free?

    while(std::getchar() != '\n');
    iopool.stop();
    return 0;
}

报错信息:

adjwang@DESKTOP-J8LS933:~/testserver$ ./bin/debug/test_client_reclaim
tcp server stopped: 0
tcp server stopped: 0
Segmentation fault (core dumped)

使用 memory sanitizer 跟踪:

adjwang@DESKTOP-J8LS933:~/testserver$ LD_PRELOAD=$(gcc -print-file-name=libasan.so) ./bin/debug/test_client_reclaim
tcp server stopped: 0
tcp server stopped: 0
=================================================================
==72650==ERROR: AddressSanitizer: heap-use-after-free on address 0x50c000000160 at pc 0x55b4a1028496 bp 0x7fba4bafda30 sp 0x7fba4bafda20
READ of size 8 at 0x50c000000160 thread T1
    #0 0x55b4a1028495 in asio::execution::detail::any_executor_base::target_type() const 3rd/asio2/3rd/asio/execution/any_executor.hpp:710
    #1 0x55b4a10283e6 in asio::detail::handler_work_base<asio::any_io_executor, void, asio::io_context, asio::executor, void>::handler_work_base(int, int, asio::any_io_executor const&) 3rd/asio2/3rd/asio/detail/handler_work.hpp:355
    #2 0x55b4a1026074 in asio::detail::handler_work<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}, asio::any_io_executor, void>::handler_work(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}&, asio::any_io_executor const&) 3rd/asio2/3rd/asio/detail/handler_work.hpp:457
    #3 0x55b4a10251c0 in asio::detail::wait_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}, asio::any_io_executor>::wait_handler(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}&, asio::any_io_executor const&) 3rd/asio2/3rd/asio/detail/wait_handler.hpp:40
    #4 0x55b4a1024c71 in void asio::detail::deadline_timer_service<asio::detail::chrono_time_traits<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock> > >::async_wait<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}, asio::any_io_executor>(asio::detail::deadline_timer_service<asio::detail::chrono_time_traits<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock> > >::implementation_type&, asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}&, asio::any_io_executor const&) 3rd/asio2/3rd/asio/detail/deadline_timer_service.hpp:257
    #5 0x55b4a1024a06 in void asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor>::initiate_async_wait::operator()<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()()::{lambda(std::error_code const&)#1}&&) const 3rd/asio2/3rd/asio/basic_waitable_timer.hpp:805
    #6 0x55b4a102486c in _ZN4asio6detail31completion_handler_async_resultIZZN5asio26detail17tcp_server_impl_tINS2_12tcp_server_tINS2_11tcp_sessionEEES6_E10_post_stopERKSt10error_codeSt10shared_ptrIS7_ENS3_7state_tEENUlvE_clEvEUlSB_E_JFvS9_EEE8initiateINS_20basic_waitable_timerINSt6chrono3_V212steady_clockENS_11wait_traitsISN_EENS_15any_io_executorEE19initiate_async_waitETkNS_22completion_handler_forIDpT0_EESG_JEEEvOT_OT0_DpOT1_ 3rd/asio2/3rd/asio/async_result.hpp:272
    #7 0x55b4a10247ec in _ZN4asio14async_initiateIZZN5asio26detail17tcp_server_impl_tINS1_12tcp_server_tINS1_11tcp_sessionEEES5_E10_post_stopERKSt10error_codeSt10shared_ptrIS6_ENS2_7state_tEENUlvE_clEvEUlSA_E_TpTkNS_20completion_signatureEJFvS8_EENS_20basic_waitable_timerINSt6chrono3_V212steady_clockENS_11wait_traitsISK_EENS_15any_io_executorEE19initiate_async_waitEJEEENS_10constraintIXsr6detail31async_result_has_initiate_memfnIT_DpT0_EE5valueEDTclsr12async_resultINSt5decayISR_E4typeEST_EE8initiatescT1_fp_scSR_fp0_spscT2_fp1_EEE4typeEOSX_RNS_13type_identityISR_E4typeEDpOSY_ 3rd/asio2/3rd/asio/async_result.hpp:569
    #8 0x55b4a1022d2e in _ZN4asio20basic_waitable_timerINSt6chrono3_V212steady_clockENS_11wait_traitsIS3_EENS_15any_io_executorEE10async_waitITkNS_20completion_token_forIFvSt10error_codeEEEZZN5asio26detail17tcp_server_impl_tINSC_12tcp_server_tINSC_11tcp_sessionEEESG_E10_post_stopERKSA_St10shared_ptrISH_ENSD_7state_tEENUlvE_clEvEUlSK_E_EEDTcl14async_initiateIT_SB_EclL_ZSt7declvalINS7_19initiate_async_waitEEDTcl9__declvalISQ_ELi0EEEvEEfp_EEOSQ_ 3rd/asio2/3rd/asio/basic_waitable_timer.hpp:773
    #9 0x55b4a1022112 in asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}::operator()() 3rd/asio2/include/asio2/tcp/tcp_server.hpp:556
    #10 0x55b4a1021da8 in void asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> >::operator()<>() 3rd/asio2/include/asio2/base/detail/allocator.hpp:506
    #11 0x55b4a1021a64 in asio::detail::binder0<asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >::operator()() 3rd/asio2/3rd/asio/detail/bind_handler.hpp:55
    #12 0x55b4a10210d3 in void asio::io_context::basic_executor_type<asio2::detail::handler_allocator<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> >, 0ul>::execute<asio::detail::binder0<asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > > >(asio::detail::binder0<asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >&&) const 3rd/asio2/3rd/asio/impl/io_context.hpp:282
    #13 0x55b4a1020b7e in void asio::detail::initiate_dispatch_with_executor<asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >::operator()<asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >(asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> >&&, std::enable_if<execution::is_executor<std::conditional<true, asio::io_context::basic_executor_type<std::allocator<void>, 0ul>, asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >::type>::value, void>::type*, std::enable_if<!detail::is_work_dispatcher_required<std::decay<asio2::detail::custom_alloc_handler<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >::type, asio::io_context::basic_executor_type<std::allocator<void>, 0ul> >::value, void>::type*) const 3rd/asio2/3rd/asio/detail/initiate_dispatch.hpp:105
    #14 0x55b4a1020993 in _ZN4asio6detail31completion_handler_async_resultIN5asio26detail20custom_alloc_handlerIZNS3_17tcp_server_impl_tINS2_12tcp_server_tINS2_11tcp_sessionEEES7_E10_post_stopERKSt10error_codeSt10shared_ptrIS8_ENS3_7state_tEEUlvE_St17integral_constantIbLb0EENS3_17allocator_size_opILm0EEEEEJFvvEEE8initiateINS0_31initiate_dispatch_with_executorINS_10io_context19basic_executor_typeISaIvELm0EEEEETkNS_22completion_handler_forIDpT0_EESL_JEEEvOT_OT0_DpOT1_ 3rd/asio2/3rd/asio/async_result.hpp:272
    #15 0x55b4a102095c in _ZN4asio14async_initiateIN5asio26detail20custom_alloc_handlerIZNS2_17tcp_server_impl_tINS1_12tcp_server_tINS1_11tcp_sessionEEES6_E10_post_stopERKSt10error_codeSt10shared_ptrIS7_ENS2_7state_tEEUlvE_St17integral_constantIbLb0EENS2_17allocator_size_opILm0EEEEETpTkNS_20completion_signatureEJFvvEENS_6detail31initiate_dispatch_with_executorINS_10io_context19basic_executor_typeISaIvELm0EEEEEJEEENS_10constraintIXsr6detail31async_result_has_initiate_memfnIT_DpT0_EE5valueEDTclsr12async_resultINSt5decayISU_E4typeESW_EE8initiatescT1_fp_scSU_fp0_spscT2_fp1_EEE4typeEOS10_RNS_13type_identityISU_E4typeEDpOS11_ 3rd/asio2/3rd/asio/async_result.hpp:569
    #16 0x55b4a1020781 in _ZN4asio8dispatchINS_10io_contextETkNS_20completion_token_forIFvvEEEN5asio26detail20custom_alloc_handlerIZNS5_17tcp_server_impl_tINS4_12tcp_server_tINS4_11tcp_sessionEEES9_E10_post_stopERKSt10error_codeSt10shared_ptrISA_ENS5_7state_tEEUlvE_St17integral_constantIbLb0EENS5_17allocator_size_opILm0EEEEEEEDTcl14async_initiateIT0_S3_Ecl7declvalINS_6detail31initiate_dispatch_with_executorINT_13executor_typeEEEEEfp0_EERSR_OSO_NS_10constraintIXsr14is_convertibleISV_RNS_17execution_contextEEE5valueEiE4typeE 3rd/asio2/3rd/asio/dispatch.hpp:187
    #17 0x55b4a1020491 in asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_post_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >, asio2::detail::state_t) 3rd/asio2/include/asio2/tcp/tcp_server.hpp:542
    #18 0x55b4a101fb2d in asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::_do_stop(std::error_code const&, std::shared_ptr<asio2::tcp_server_t<asio2::tcp_session> >) 3rd/asio2/include/asio2/tcp/tcp_server.hpp:531
    #19 0x55b4a1113e37 in asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}::operator()() 3rd/asio2/include/asio2/tcp/tcp_server.hpp:142
    #20 0x55b4a1113cd5 in asio2::detail::post_cp<asio2::tcp_server_t<asio2::tcp_session>, void>::post<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}&&)::{lambda()#1}::operator()() 3rd/asio2/include/asio2/base/impl/post_cp.hpp:61
    #21 0x55b4a1113ca8 in void asio2::detail::custom_alloc_handler<asio2::detail::post_cp<asio2::tcp_server_t<asio2::tcp_session>, void>::post<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}&&)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> >::operator()<>() 3rd/asio2/include/asio2/base/detail/allocator.hpp:506
    #22 0x55b4a1113964 in asio::detail::binder0<asio2::detail::custom_alloc_handler<asio2::detail::post_cp<asio2::tcp_server_t<asio2::tcp_session>, void>::post<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}&&)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >::operator()() 3rd/asio2/3rd/asio/detail/bind_handler.hpp:55
    #23 0x55b4a1114248 in asio::detail::executor_op<asio::detail::binder0<asio2::detail::custom_alloc_handler<asio2::detail::post_cp<asio2::tcp_server_t<asio2::tcp_session>, void>::post<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}&&)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> > >, asio2::detail::handler_allocator<asio2::detail::post_cp<asio2::tcp_server_t<asio2::tcp_session>, void>::post<asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}>(asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::stop()::{lambda()#1}&&)::{lambda()#1}, std::integral_constant<bool, false>, asio2::detail::allocator_size_op<0ul> >, asio::detail::scheduler_operation>::do_complete(void*, asio::detail::scheduler_operation*, std::error_code const&, unsigned long) 3rd/asio2/3rd/asio/detail/executor_op.hpp:69
    #24 0x55b4a0fb83ea in asio::detail::scheduler_operation::complete(void*, std::error_code const&, unsigned long) 3rd/asio2/3rd/asio/detail/scheduler_operation.hpp:39
    #25 0x55b4a0fb72da in asio::detail::scheduler::do_run_one(asio::detail::conditionally_enabled_mutex::scoped_lock&, asio::detail::scheduler_thread_info&, std::error_code const&) 3rd/asio2/3rd/asio/detail/impl/scheduler.ipp:492
    #26 0x55b4a0fb66ca in asio::detail::scheduler::run(std::error_code&) 3rd/asio2/3rd/asio/detail/impl/scheduler.ipp:209
    #27 0x55b4a0fc738b in asio::io_context::run() 3rd/asio2/3rd/asio/impl/io_context.ipp:63
    #28 0x55b4a0fc6cc7 in asio2::detail::iopool::start()::{lambda()#1}::operator()() 3rd/asio2/include/asio2/base/iopool.hpp:512
    #29 0x55b4a0fc6ae4 in void std::__invoke_impl<void, asio2::detail::iopool::start()::{lambda()#1}>(std::__invoke_other, asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:61
    #30 0x55b4a0fc6aa4 in std::__invoke_result<asio2::detail::iopool::start()::{lambda()#1}>::type std::__invoke<asio2::detail::iopool::start()::{lambda()#1}>(asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/invoke.h:96
    #31 0x55b4a0fc6a7c in void std::thread::_Invoker<std::tuple<asio2::detail::iopool::start()::{lambda()#1}> >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:292
    #32 0x55b4a0fc6a54 in std::thread::_Invoker<std::tuple<asio2::detail::iopool::start()::{lambda()#1}> >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:299
    #33 0x55b4a0fc6998 in std::thread::_State_impl<std::thread::_Invoker<std::tuple<asio2::detail::iopool::start()::{lambda()#1}> > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:244
    #34 0x7fba4ee26db3  (/lib/x86_64-linux-gnu/libstdc++.so.6+0xecdb3) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #35 0x7fba4f01ca41 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:234
    #36 0x7fba4eaada93 in start_thread nptl/pthread_create.c:447
    #37 0x7fba4eb3ac3b in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

0x50c000000160 is located 96 bytes inside of 120-byte region [0x50c000000100,0x50c000000178)
freed by thread T0 here:
    #0 0x7fba4f0bd0a8 in operator delete(void*) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:152
    #1 0x55b4a0fea693 in std::default_delete<asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor> >::operator()(asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor>*) const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:99
    #2 0x55b4a0fcb3db in std::unique_ptr<asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor>, std::default_delete<asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor> > >::~unique_ptr() /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:404
    #3 0x55b4a0fed76d in asio2::detail::tcp_server_impl_t<asio2::tcp_server_t<asio2::tcp_session>, asio2::tcp_session>::~tcp_server_impl_t() 3rd/asio2/include/asio2/tcp/tcp_server.hpp:105
    #4 0x55b4a0fed734 in asio2::tcp_server_t<asio2::tcp_session>::~tcp_server_t() 3rd/asio2/include/asio2/tcp/tcp_server.hpp:830
    #5 0x55b4a0fed69a in std::default_delete<asio2::tcp_server_t<asio2::tcp_session> >::operator()(asio2::tcp_server_t<asio2::tcp_session>*) const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:99
    #6 0x55b4a0fed61f in std::__uniq_ptr_impl<asio2::tcp_server_t<asio2::tcp_session>, std::default_delete<asio2::tcp_server_t<asio2::tcp_session> > >::reset(asio2::tcp_server_t<asio2::tcp_session>*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:211
    #7 0x55b4a0fa3fec in std::unique_ptr<asio2::tcp_server_t<asio2::tcp_session>, std::default_delete<asio2::tcp_server_t<asio2::tcp_session> > >::reset(asio2::tcp_server_t<asio2::tcp_session>*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:509
    #8 0x55b4a0fa2749 in main /home/adjwang/testserver/src/bin/test_client_reclaim.cpp:13
    #9 0x7fba4ea3b1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #10 0x7fba4ea3b28a in __libc_start_main_impl ../csu/libc-start.c:360
    #11 0x55b4a0fa2154 in _start (/home/adjwang/testserver/bin/debug/test_client_reclaim+0x101154) (BuildId: 4901ae01d6dd73f2bab97f1d5baab615078d6503)

previously allocated by thread T0 here:
    #0 0x7fba4f0bc548 in operator new(unsigned long) ../../../../src/libsanitizer/asan/asan_new_delete.cpp:95
    #1 0x55b4a0fcb2f4 in std::__detail::_MakeUniq<asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor> >::__single_object std::make_unique<asio::basic_waitable_timer<std::chrono::_V2::steady_clock, asio::wait_traits<std::chrono::_V2::steady_clock>, asio::any_io_executor>, asio::io_context&>(asio::io_context&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1070
    #2 0x55b4a0fcacaf in _ZN5asio26detail17tcp_server_impl_tINS_12tcp_server_tINS_11tcp_sessionEEES3_EC2ISt10shared_ptrINS0_4io_tEETnNSt9enable_ifIXntsr3stdE13is_integral_vINS0_12remove_cvrefIT_E4typeEEEiE4typeELi0EEEmmOSC_ 3rd/asio2/include/asio2/tcp/tcp_server.hpp:69
    #3 0x55b4a0fcabe8 in _ZN5asio26detail17tcp_server_impl_tINS_12tcp_server_tINS_11tcp_sessionEEES3_EC2ISt10shared_ptrINS0_4io_tEETnNSt9enable_ifIXntsr3stdE13is_integral_vINS0_12remove_cvrefIT_E4typeEEEiE4typeELi0EEEOSC_ 3rd/asio2/include/asio2/tcp/tcp_server.hpp:77
    #4 0x55b4a0fcab6c in _ZN5asio212tcp_server_tINS_11tcp_sessionEECI2NS_6detail17tcp_server_impl_tIS2_S1_EEISt10shared_ptrINS3_4io_tEETnNSt9enable_ifIXntsr3stdE13is_integral_vINS3_12remove_cvrefIT_E4typeEEEiE4typeELi0EEEOSA_ 3rd/asio2/include/asio2/tcp/tcp_server.hpp:833
    #5 0x55b4a0fa3977 in std::__detail::_MakeUniq<asio2::tcp_server_t<asio2::tcp_session> >::__single_object std::make_unique<asio2::tcp_server_t<asio2::tcp_session>, std::shared_ptr<asio2::detail::io_t> >(std::shared_ptr<asio2::detail::io_t>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:1070
    #6 0x55b4a0fa2620 in main /home/adjwang/testserver/src/bin/test_client_reclaim.cpp:8
    #7 0x7fba4ea3b1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #8 0x7fba4ea3b28a in __libc_start_main_impl ../csu/libc-start.c:360
    #9 0x55b4a0fa2154 in _start (/home/adjwang/testserver/bin/debug/test_client_reclaim+0x101154) (BuildId: 4901ae01d6dd73f2bab97f1d5baab615078d6503)

Thread T1 created by T0 here:
    #0 0x7fba4f0b31f9 in pthread_create ../../../../src/libsanitizer/asan/asan_interceptors.cpp:245
    #1 0x7fba4ee26eb0 in std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xeceb0) (BuildId: ca77dae775ec87540acd7218fa990c40d1c94ab1)
    #2 0x55b4a0fc6616 in std::thread::thread<asio2::detail::iopool::start()::{lambda()#1}, , void>(asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_thread.h:164
    #3 0x55b4a0fc64f0 in decltype (::new ((void*)(0)) std::thread((std::declval<asio2::detail::iopool::start()::{lambda()#1}>)())) std::construct_at<std::thread, asio2::detail::iopool::start()::{lambda()#1}>(std::thread*, asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_construct.h:97
    #4 0x55b4a0fbf9b9 in void std::allocator_traits<std::allocator<std::thread> >::construct<std::thread, asio2::detail::iopool::start()::{lambda()#1}>(std::allocator<std::thread>&, std::thread*, asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/alloc_traits.h:540
    #5 0x55b4a0fbf9b9 in std::thread& std::vector<std::thread, std::allocator<std::thread> >::emplace_back<asio2::detail::iopool::start()::{lambda()#1}>(asio2::detail::iopool::start()::{lambda()#1}&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/vector.tcc:117
    #6 0x55b4a0fa34d0 in asio2::detail::iopool::start() 3rd/asio2/include/asio2/base/iopool.hpp:492
    #7 0x55b4a0fa25ec in main /home/adjwang/testserver/src/bin/test_client_reclaim.cpp:7
    #8 0x7fba4ea3b1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #9 0x7fba4ea3b28a in __libc_start_main_impl ../csu/libc-start.c:360
    #10 0x55b4a0fa2154 in _start (/home/adjwang/testserver/bin/debug/test_client_reclaim+0x101154) (BuildId: 4901ae01d6dd73f2bab97f1d5baab615078d6503)

SUMMARY: AddressSanitizer: heap-use-after-free 3rd/asio2/3rd/asio/execution/any_executor.hpp:710 in asio::execution::detail::any_executor_base::target_type() const
Shadow bytes around the buggy address:
  0x50bffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50bfffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50bfffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50c000000000: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x50c000000080: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
=>0x50c000000100: fd fd fd fd fd fd fd fd fd fd fd fd[fd]fd fd fa
  0x50c000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50c000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50c000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50c000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x50c000000380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==72650==ABORTING
zhllxt commented 4 hours ago

改为如下即可:

auto tcp_server = std::make_shared<asio2::tcp_server>(iopool.get(0));

原因:tcp_server->stop(); 完成之后,iopool中的io_context对象可能还在操纵tcp_server,也就是说tcp_server此时用的是iopool中的io_context,这导致tcp_server->stop(); 时无法完全的判断io_context是否全部stopped了(如果tcp_server没有用iopool用的io_context则可以正确判断),具体逻辑有点复杂,你大致了解就行吧。

AdjWang commented 2 minutes ago

好的谢谢!