Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
redboltz opened this issue Jan 7, 2025 · 0 comments

Comments

@redboltz
Copy link

redboltz commented Jan 7, 2025

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant