boostorg / cobalt

Coroutines for C++20 & asio
https://www.boost.org/doc/libs/master/libs/cobalt/doc/html/index.html
207 stars 24 forks source link

Crash on resuming cancelled push generators #142

Closed daumantas-kavolis-sensmetry closed 10 months ago

daumantas-kavolis-sensmetry commented 10 months ago

Seems like cancelling push generators destroys associated receiver but the generator is still resumed, resulting in segfault/sanitizer errors.

#include <boost/cobalt/channel.hpp>
#include <boost/cobalt/generator.hpp>
#include <boost/cobalt/main.hpp>

using Channel = boost::cobalt::channel<int>;

static auto source_gen(Channel &channel) -> boost::cobalt::generator<int> {
  while (channel.is_open()) { co_yield co_await channel.read(); }
}

static auto sink_gen(Channel &channel) -> boost::cobalt::generator<boost::system::error_code, int> {
  while (channel.is_open()) {
    auto message = co_yield boost::system::error_code{};
    //             ^ when resuming a cancelled generator crashes here due to `generator_promise::receiver ==
    //                nullptr`
    co_await channel.write(std::move(message));
  }
}

auto co_main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) -> boost::cobalt::main {
  Channel channel;
  auto source = source_gen(channel);
  auto sink = sink_gen(channel);

  co_await sink(42);
}
klemens-morgenstern commented 10 months ago

Thanks for reporting that, I can reproduce it. I hope to have a fix tomorrow so it can be in the upcoming release.