async_simple icon indicating copy to clipboard operation
async_simple copied to clipboard

asio使用自定义完成令牌的方式兼容Lazy

Open banderzhm opened this issue 10 months ago • 2 comments

我想提交一个pull,替代asio_coro_util.hpp,让asio::awaitable无缝兼容async_simple::coro::Lazy,但是现在遇到点阻碍请求指导下,msvc 平台可以正常运行,clang-21运行错误。

boost version:1.87 async_simple version: main msvc verion: 14.43.34808 clang version: 21.0.0 (++20250416083926+11857bef8a5f-1~exp1~20250416084034.851)

use_lazy.hpp


#ifndef ASYNC_SIMPLE_LAZY_TOKENS_3_HPP
#define ASYNC_SIMPLE_LAZY_TOKENS_3_HPP

#include <async_simple/Promise.h>
#include <async_simple/coro/FutureAwaiter.h>
#include <async_simple/coro/Lazy.h>
#include <async_simple/Executor.h>

// --- Asio 头文件配置 ---
// 如果使用独立版 Asio 而不是 Boost.Asio, 在此之前定义 USE_STANDALONE_ASIO
#ifdef USE_STANDALONE_ASIO
    #include <asio/async_result.hpp>
    #include <asio/error.hpp>        
    #include <asio/error_code.hpp>
    #include <asio/system_error.hpp>
    #include <asio/post.hpp>
    #include <asio/io_context.hpp>

    namespace ASIO_NAMESPACE = ::asio;
    namespace SYSTEM_NAMESPACE = ::asio;
#else // 默认使用 Boost.Asio
    #include <boost/asio/async_result.hpp>
    #include <boost/asio/error.hpp>        
    #include <boost/asio/post.hpp>
    #include <boost/asio/io_context.hpp>
    #include <boost/system/error_code.hpp>
    #include <boost/system/system_error.hpp>

    namespace ASIO_NAMESPACE = ::boost::asio;
    namespace SYSTEM_NAMESPACE = ::boost::system;
#endif
// --- Asio 头文件配置结束 ---

#include <exception>
#include <functional>
#include <memory> 
#include <stdexcept>
#include <tuple>
#include <utility>
#include <type_traits>


// async_simple 的 Asio 集成命名空间
namespace async_simple
{
    // Asio/System 类型别名
    using error_code_type = SYSTEM_NAMESPACE::error_code;       // 错误码
    using system_error_type = SYSTEM_NAMESPACE::system_error;   // 系统错误 (异常)
    using io_context_type = ASIO_NAMESPACE::io_context;         // IO 上下文

    // --- 令牌定义 ---

    // 令牌 1: use_lazy
    // 行为: 返回单个主结果值(或void)。出错(且非eof)时抛出 system_error_type 异常。
    // 用法: auto result = co_await async_op(..., use_lazy);
    struct use_lazy_t {};
    constexpr use_lazy_t use_lazy{};

    // 令牌 2: use_lazy_tuple
    // 行为: 返回包含所有回调参数(含ec)的 std::tuple。不抛出异常。
    // 用法: auto [ec, result] = co_await async_op(..., use_lazy_tuple);
    struct use_lazy_tuple_t {};
    constexpr use_lazy_tuple_t use_lazy_tuple{};


    namespace detail
    {
        // --- use_lazy_t 的辅助模板 ---

        // 推断 Lazy<T> 中的主结果类型 T
        template <typename... Args> struct DeduceLazyType;
        template <typename T, typename... Rest>
        struct DeduceLazyType<error_code_type, T, Rest...> { using type = T; };
        template <> struct DeduceLazyType<error_code_type> { using type = void; };
        template <> struct DeduceLazyType<> { using type = void; };
        template <typename T, typename... Rest>
            requires(!std::is_same_v<std::remove_cvref_t<T>, error_code_type>)
        struct DeduceLazyType<T, Rest...> { using type = T; };


        // 为 use_lazy_t 解包结果: 检查 ec (忽略 EOF), 出错则抛异常, 否则返回主值
        template <typename T>
        struct AsioResultUnwrapper
        {
            using type = T;
            template <typename ValueType, typename... RestArgs>
            static T get(error_code_type ec, ValueType&& value, RestArgs&&... /* rest */) {
                if (ec && ec != ASIO_NAMESPACE::error::eof) { throw system_error_type(ec); }
                return T(std::forward<ValueType>(value));
            }
            static T get(error_code_type ec) {
                 if (ec && ec != ASIO_NAMESPACE::error::eof) { throw system_error_type(ec); }
                 throw std::logic_error("AsioResultUnwrapper<T>: Non-void T expected, but Asio signature was void(error_code). Deduction mismatch?");
            }
             static T get() {
                  throw std::logic_error("AsioResultUnwrapper<T>: Non-void T expected, but Asio signature was void(). Cannot determine success or failure.");
             }
        };
        // void 返回类型的特化
        template <>
        struct AsioResultUnwrapper<void>
        {
            using type = void;
            template <typename... OpArgs>
            static void get(error_code_type ec, OpArgs&&... /* rest */) {
                if (ec && ec != ASIO_NAMESPACE::error::eof) { throw system_error_type(ec); }
            }
            static void get() {} // No error code to check
        };

        // 从签名推断 Lazy<T> 的值类型 T
        template <typename Signature> struct SignatureHelper;
        template <typename... Args>
        struct SignatureHelper<void(Args...)> {
            using LazyValueType = typename detail::DeduceLazyType<typename std::decay_t<Args>...>::type;
        };

    } // namespace detail


    // --- AsioExecutor (通用) ---
    // 基于 Asio io_context 实现 async_simple::Executor
    class AsioExecutor : public async_simple::Executor {
    public:
        explicit AsioExecutor(io_context_type &io_context) : io_context_(io_context) {}
        virtual bool schedule(Func func) override {
            ASIO_NAMESPACE::post(io_context_, std::move(func));
            return true;
        }
        io_context_type& context() { return io_context_; }
        const io_context_type& context() const { return io_context_; }
    private:
        io_context_type &io_context_;
    };

} // namespace async_simple

// --- Asio async_result 特化 ---
// 必须位于 boost::asio 或 asio 命名空间内
#ifdef USE_STANDALONE_ASIO
namespace asio {
#else
namespace boost::asio {
#endif

    // --- 特化 1: 针对 use_lazy_t (单一值 / 异常) ---
    template <typename... Args>
    struct async_result<async_simple::use_lazy_t, void(Args...)>
    {
        using LazyValueType = typename async_simple::detail::SignatureHelper<void(Args...)>::LazyValueType;
        using return_type = async_simple::coro::Lazy<LazyValueType>; // 返回 Lazy<T>
        using promise_type = async_simple::Promise<LazyValueType>;

        // State 结构体,在堆上持有 promise
        struct PromiseState { promise_type promise; };

        template <typename Initiation, typename... InitArgs>
        static return_type initiate(Initiation initiation,
                                    async_simple::use_lazy_t /*token*/,
                                    InitArgs &&...args)
        {
            auto state = std::make_shared<PromiseState>(); // 在堆上分配
            async_simple::Future<LazyValueType> future = state->promise.getFuture();

            std::invoke(
                std::move(initiation),
                // 完成处理器 Lambda: 使用 Unwrapper 处理结果或异常
                [state](Args... operation_args) mutable
                {
                    try {
                        if constexpr (std::is_void_v<LazyValueType>) {
                             async_simple::detail::AsioResultUnwrapper<void>::get(std::forward<Args>(operation_args)...);
                             state->promise.setValue();
                        } else {
                            auto value = async_simple::detail::AsioResultUnwrapper<LazyValueType>::get(std::forward<Args>(operation_args)...);
                             state->promise.setValue(std::move(value));
                        }
                    } catch (...) {
                         state->promise.setException(std::current_exception());
                    }
                },
                std::forward<InitArgs>(args)...
            );
            // co_await future: 获取值或重新抛出异常
            co_return co_await std::move(future);
        }
    };


    // --- 特化 2: 针对 use_lazy_tuple_t (元组返回 / 无异常) ---
    template <typename... Args>
    struct async_result<async_simple::use_lazy_tuple_t, void(Args...)>
    {
        using ResultTupleType = std::tuple<std::decay_t<Args>...>; // 结果是元组
        using return_type = async_simple::coro::Lazy<ResultTupleType>; // 返回 Lazy<Tuple>
        using promise_type = async_simple::Promise<ResultTupleType>;

        // State 结构体,在堆上持有 promise
        struct PromiseState { promise_type promise; };

        template <typename Initiation, typename... InitArgs>
        static return_type initiate(Initiation initiation,
                                    async_simple::use_lazy_tuple_t /*token*/,
                                    InitArgs &&...args)
        {
            auto state = std::make_shared<PromiseState>(); // 在堆上分配
            async_simple::Future<ResultTupleType> future = state->promise.getFuture();

            std::invoke(
                std::move(initiation),
                // 完成处理器 Lambda: 直接将参数打包成元组
                [state](Args... operation_args) mutable
                {
                    try {
                        state->promise.setValue(ResultTupleType(std::forward<Args>(operation_args)...));
                    } catch (...) {
                        state->promise.setException(std::current_exception());
                    }
                },
                std::forward<InitArgs>(args)...
            );
            // co_await future: 获取包含 error_code 和结果的元组
            co_return co_await std::move(future);
        }
    };

} // namespace boost::asio or asio

#endif // ASYNC_SIMPLE_LAZY_TOKENS_3_HPP

测试代码

async_simple::coro::Lazy<void> handle_connection(boost::asio::ip::tcp::socket socket,
                                                 async_simple::AsioExecutor& executor)
{
    try
    {
        char data[1024];
        boost::asio::mutable_buffer buffer = boost::asio::buffer(data);

        auto [e1, n] = co_await socket.async_read_some(buffer, async_simple::use_lazy_tuple);
        if (e1)
        {
            std::cout << "Read " << n << " error: " << e1.what() << std::endl;
        }
        std::cout << "Read " << n << " bytes: " << std::string_view(data, n) << std::endl;
        std::size_t written =
            co_await boost::asio::async_write(socket, boost::asio::buffer(" PONG\n"), async_simple::use_lazy);
        std::cout << "Wrote " << written << " bytes" << std::endl;
    }
    catch (const std::system_error& e)
    {
        std::cerr << "Connection error: " << e.what() << " (" << e.code() << ")" << std::endl;
    }
    catch (const std::exception& e)
    {
        std::cerr << "General error: " << e.what() << std::endl;
    }

    co_return;
}


async_simple::coro::Lazy<void> run_server(boost::asio::io_context& io_context, unsigned short port)
{
    async_simple::AsioExecutor executor(io_context);
    boost::asio::ip::tcp::acceptor acceptor(io_context);

    try
    {
        boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
        acceptor.open(endpoint.protocol());
        boost::system::error_code set_option_ec;
        acceptor.set_option(boost::asio::socket_base::reuse_address(true), set_option_ec);
        if (set_option_ec)
        {
            std::cerr << "警告: 设置 reuse_address 失败: " << set_option_ec.message() << std::endl;
        }

        acceptor.bind(endpoint);

        acceptor.listen(boost::asio::socket_base::max_listen_connections);


        std::cout << "服务器正在监听端口 " << port << " (线程 ID: " << std::this_thread::get_id() << ")" << std::endl;

        while (true)
        {
            boost::asio::ip::tcp::socket socket(io_context);

            std::cout << "等待连接..." << std::endl;

            auto [accept_ec] = co_await acceptor.async_accept(socket, async_simple::use_lazy_tuple);

            if (accept_ec)
            {
                if (accept_ec == boost::asio::error::operation_aborted)
                {
                    std::cout << "Acceptor 已停止。" << std::endl;
                    break; // 退出循环
                }
                std::cerr << "Accept 失败: " << accept_ec.message() << std::endl;
                continue;
            }
            try
            {

                std::cout << "已接受来自 " << socket.remote_endpoint() << " 的连接" << std::endl;

                handle_connection(std::move(socket), executor)
                    .via(&executor)
                    .start(
                        [](auto&& try_result)
                        {
                            if (try_result.hasError())
                            {
                                try
                                {
                                    std::rethrow_exception(try_result.getException());
                                }
                                catch (const std::exception& e)
                                {
                                }
                            }
                        });
            }
            catch (const boost::system::system_error& endpoint_ex)
            {

                std::cerr << "获取 remote_endpoint 时出错: " << endpoint_ex.what() << std::endl;
            }
        }
    }
    catch (const std::system_error& e)
    {

        std::cerr << "服务器设置/循环错误: " << e.what() << " (错误码: " << e.code() << ")" << std::endl;
    }
    catch (const std::exception& e)
    {

        std::cerr << "服务器一般错误: " << e.what() << std::endl;
    }

    std::cout << "服务器协程结束。" << std::endl;


    if (acceptor.is_open())
    {
        boost::system::error_code ignored_ec;
        acceptor.close(ignored_ec);
    }
    co_return;
}

TEST(asio_, test_asio_and_a_simple)
{
    try
    {
        boost::asio::io_context io_context;

        // Start the server coroutine
        run_server(io_context, 12345).start([](auto&&) {}); // Fire-and-forget the server runner itself

        // Run the io_context event loop
        io_context.run();
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception in main: " << e.what() << std::endl;
    }
    
}

gdb 错误信息


==395384==ERROR: AddressSanitizer: stack-use-after-return on address 0x7bfff5607ec0 at pc 0x55555578cfb6 bp 0x7fffffffc700 sp 0x7fffffffc6f8
READ of size 8 at 0x7bfff5607ec0 thread T0
[Detaching after fork from child process 395495]
    #0 0x55555578cfb5 in decltype(std::declval<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept>()(std::declval<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*>(), std::declval<boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>())) std::__1::__invoke[abi:ne210000]<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::coro::Lazy<std::__1::tuple<boost::system::error_code>> boost::asio::async_result<async_simple::use_lazy_tuple_t, void (boost::system::error_code)>::initiate<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::use_lazy_tuple_t, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&)::'lambda'(boost::system::error_code), boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept&&, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&) /usr/lib/llvm-21/bin/../include/c++/v1/__type_traits/invoke.h:179:70
    #1 0x555555784bfc in std::__1::invoke_result<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>::type std::__1::invoke[abi:ne210000]<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::coro::Lazy<std::__1::tuple<boost::system::error_code>> boost::asio::async_result<async_simple::use_lazy_tuple_t, void (boost::system::error_code)>::initiate<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::use_lazy_tuple_t, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&)::'lambda'(boost::system::error_code), boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept&&, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&) /usr/lib/llvm-21/bin/../include/c++/v1/__functional/invoke.h:29:10
    #2 0x55555572990d in async_simple::coro::Lazy<std::__1::tuple<boost::system::error_code>> boost::asio::async_result<async_simple::use_lazy_tuple_t, void (boost::system::error_code)>::initiate<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::use_lazy_tuple_t, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&) (.resume) /mnt/h/study/aggre_cpp23_modules/src/common/asio_uitls_my_3.hpp:209:13
    #3 0x55555571b8e5 in void async_simple::coro::detail::LazyBase<void, false>::start<asio__test_asio_and_a_simple_Test::TestBody()::$_0>(asio__test_asio_and_a_simple_Test::TestBody()::$_0&&) requires isLazyCallback<asio__test_asio_and_a_simple_Test::TestBody()::$_0, TL0_>::'lambda'(async_simple::coro::detail::LazyBase<void, false>, asio__test_asio_and_a_simple_Test::TestBody()::$_0)::operator()(async_simple::coro::detail::LazyBase<void, false>, asio__test_asio_and_a_simple_Test::TestBody()::$_0) const /mnt/h/study/aggre_cpp23_modules/third_party/async_simple/async_simple/coro/Lazy.h:423:16
    #4 0x5555557138d4 in void async_simple::coro::detail::LazyBase<void, false>::start<asio__test_asio_and_a_simple_Test::TestBody()::$_0>(asio__test_asio_and_a_simple_Test::TestBody()::$_0&&) requires isLazyCallback<asio__test_asio_and_a_simple_Test::TestBody()::$_0, TL0_> /mnt/h/study/aggre_cpp23_modules/third_party/async_simple/async_simple/coro/Lazy.h:426:13
    #5 0x555555713536 in asio__test_asio_and_a_simple_Test::TestBody() /mnt/h/study/aggre_cpp23_modules/demo/test_asio_and_a_simple.cpp:175:39
    #6 0x5555558735dd in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2664:10
    #7 0x555555815ab5 in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2700:14
    #8 0x5555557d3b5d in testing::Test::Run() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2739:5
    #9 0x5555557d4f42 in testing::TestInfo::Run() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2885:11
    #10 0x5555557d6165 in testing::TestSuite::Run() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:3063:30
    #11 0x5555557f3d42 in testing::internal::UnitTestImpl::RunAllTests() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:6054:44
    #12 0x555555879ecd in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2664:10
    #13 0x555555819f3a in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:2700:14
    #14 0x5555557f2cef in testing::UnitTest::Run() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/src/gtest.cc:5594:10
    #15 0x5555556942d0 in RUN_ALL_TESTS() /mnt/h/study/aggre_cpp23_modules/third_party/googletest/googletest/include/gtest/gtest.h:2334:73
    #16 0x55555569426e in main /mnt/h/study/aggre_cpp23_modules/main.cpp:7:12
    #17 0x7ffff73af1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #18 0x7ffff73af28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #19 0x5555555a9e24 in _start (/mnt/h/study/aggre_cpp23_modules/cmake-build-debug-wsl-24-clang-cmake3/aggre_cpp23_modules+0x55e24) (BuildId: 78b00f0db8589fe1b8c4bd38fd7088c0dd50a425)

Address 0x7bfff5607ec0 is located in stack of thread T0 at offset 64 in frame
    #0 0x55555574806f in decltype(async_initiate<async_simple::use_lazy_tuple_t const&, void (boost::system::error_code)>(decltype(std::__declval<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept>(0)) std::__1::declval[abi:ne210000]<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept>()(), fp0, &fp, static_cast<boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(0))) boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::async_accept<boost::asio::ip::tcp, boost::asio::any_io_executor, async_simple::use_lazy_tuple_t const&>(boost::asio::basic_socket<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::any_io_executor>&, async_simple::use_lazy_tuple_t const&, boost::asio::constraint<is_convertible<boost::asio::ip::tcp, boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept>::value, int>::type) /mnt/f/runtime/dep_lib/ubuntu24/clang-boost/boost_1_87_0/boost/asio/basic_socket_acceptor.hpp:1397

  This frame has 3 object(s):
    [32, 40) 'ref.tmp' (line 1398)
    [64, 72) 'ref.tmp' (line 1398) <== Memory access at offset 64 is inside this variable
    [96, 104) 'ref.tmp' (line 1398)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-return /mnt/h/study/aggre_cpp23_modules/src/common/asio_uitls_my_3.hpp:209:13 in async_simple::coro::Lazy<std::__1::tuple<boost::system::error_code>> boost::asio::async_result<async_simple::use_lazy_tuple_t, void (boost::system::error_code)>::initiate<boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*>(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::any_io_executor>::initiate_async_accept, async_simple::use_lazy_tuple_t, boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::any_io_executor>*&&, boost::asio::ip::basic_endpoint<boost::asio::ip::tcp>*&&) (.resume)
Shadow bytes around the buggy address:
  0x7bfff5607c00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607c80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607d00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607d80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607e00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
=>0x7bfff5607e80: f5 f5 f5 f5 f5 f5 f5 f5[f5]f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607f00: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5607f80: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x7bfff5608000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bfff5608080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7bfff5608100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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

banderzhm avatar Apr 21 '25 15:04 banderzhm

代码太长了,很难理解问题在哪里,你可以再 reduce 下

ChuanqiXu9 avatar Apr 22 '25 03:04 ChuanqiXu9

io_context.run()需要用executor_work_guard block住吧 https://stackoverflow.com/questions/55224449/boost-asio-run-vs-work-ambiguity-whats-the-purpose-of-the-work-class

chloro-pn avatar Apr 22 '25 14:04 chloro-pn