Skip to content

C++20 coroutine heap-use-after-free is reported when I use make_parallel_group in co_composed function #1582

@redboltz

Description

@redboltz

Issue

heap-use-after-free is reported when I use make_parallel_group overload 1 and 2 in co_composed function.

I am not sure it is false positive report or I abuse the library or library bug.
So I reported the issue.

Environment

Boost Version

Boost 1.86.0 and Boost 1.87.0

Compiler

clang++ 18.1.8 on local
clang++ 19.1.0 on godbolt
g++ 14.2.1 on local
g++ 14.2 on godbolt

OS

Linux archlinux 6.10.10-arch1-1 #1 SMP PREEMPT_DYNAMIC Thu, 12 Sep 2024 17:21:02 +0000 x86_64 GNU/Linux

CPU

Intel(R) Core(TM) i7-9700K CPU @ 3.60GHz

Minimal reproduce code

#include <boost/asio.hpp>
#include <boost/asio/experimental/parallel_group.hpp>

namespace asio = boost::asio;

template <typename CompletionToken>
auto async_func(
    asio::any_io_executor exe,
    CompletionToken&& token
) {
    return asio::async_initiate<
        CompletionToken,
        void()
    >(
        asio::co_composed<
            void()
        >(
            [](
                auto /*state*/
            ) -> void {
                co_return {};
            },
           exe
        ),
        token
    );
}

template <typename CompletionToken>
auto caller(
    asio::any_io_executor exe,
    CompletionToken&& token
) {
    return asio::async_initiate<
        CompletionToken,
        void()
    >(
        asio::co_composed<
            void()
        >(
            [](
                auto /*state*/,
                asio::any_io_executor exe
            ) -> void {
                std::string s{"ABC"}; // if remove this line, heap-use-after-free disappeared

                {
                    // parallel_group part1
                    using op_type = decltype(
                        async_func(
                            exe,
                            asio::deferred
                        )
                    );
                    std::vector<op_type> ops;
                    ops.reserve(2);
                    for (std::size_t i = 0; i != 2; ++i) {
                        ops.push_back(async_func(exe, asio::deferred));
                    }
                    // https://www.boost.org/doc/html/boost_asio/reference/experimental__make_parallel_group/overload2.html
                    co_await asio::experimental::make_parallel_group(ops).async_wait(
                        asio::experimental::wait_for_all(),
                        asio::deferred
                    );
                }
                {
                    // parallel_group part2
                    // https://www.boost.org/doc/html/boost_asio/reference/experimental__make_parallel_group/overload1.html
                    co_await asio::experimental::make_parallel_group(
                        async_func(
                            exe,
                            asio::deferred
                        ),
                        async_func(
                            exe,
                            asio::deferred
                        )
                    ).async_wait(
                        asio::experimental::wait_for_all(),
                        asio::deferred
                    );
                }

                co_return {};
            },
            exe
        ),
        token,
        exe
    );
}

asio::awaitable<void> coro_main() {
    auto exe = co_await asio::this_coro::executor;
    co_await caller(exe, asio::deferred);
    co_return;
}

int main() {
    asio::io_context ioc;
    asio::any_io_executor exe{ioc.get_executor()};
    asio::co_spawn(exe, coro_main(), asio::detached);
    ioc.run();
}

Compile options

clang++ target.cpp -std=c++20 -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined

godbolt: https://godbolt.org/z/vEz9r5hv3

g++ target.cpp -std=c++20 -fsanitize=address -fno-omit-frame-pointer -fsanitize=undefined

godbolt: https://godbolt.org/z/rn5vMKv4E

reported error

clang++ generated binary's output on my local environment. result.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions