Compiling on gcc-10.2 (Gentoo Linux) the following code
#include <iostream>
#include <cppcoro/sync_wait.hpp>
#include <cppcoro/task.hpp>
static int ii = 0;
auto foo() -> cppcoro::task<int> {
co_return (++ii);
}
auto process() -> cppcoro::task<int> {
co_return (co_await foo()) + (co_await foo());
}
auto main() -> int {
std::cout << cppcoro::sync_wait(process()) << std::endl;
}
with options --std=c++20 -fcoroutines -O2 -lcppcoro -pthread results in memory leaks according to valgrind.
==10070== Memcheck, a memory error detector
==10070== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==10070== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==10070== Command: ./main_2
==10070==
3
==10070==
==10070== HEAP SUMMARY:
==10070== in use at exit: 128 bytes in 2 blocks
==10070== total heap usage: 6 allocs, 4 frees, 74,048 bytes allocated
==10070==
==10070== 64 bytes in 1 blocks are definitely lost in loss record 1 of 2
==10070== at 0x4838E0F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==10070== by 0x10A6C5: _Z7processv.actor(process()::_Z7processv.frame*) (in main_2)
==10070== by 0x10AB0E: cppcoro::detail::_ZN7cppcoro6detail19make_sync_wait_taskINS_4taskIiEEiLi0EEENS0_14sync_wait_taskIT0_EEOT_.actor(cppcoro::detail::sync_wait_task<int> cppcoro::detail::make_sync_wait_task<cppcoro::task<int>, int, 0>(cppcoro::task<int>&&)::_ZN7cppcoro6detail19make_sync_wait_taskINS_4taskIiEEiLi0EEENS0_14sync_wait_taskIT0_EEOT_.frame*) (in main_2)
==10070== by 0x10AD8B: cppcoro::awaitable_traits<cppcoro::task<int>&&, void>::await_result_t cppcoro::sync_wait<cppcoro::task<int> >(cppcoro::task<int>&&) (in main_2)
==10070== by 0x10A349: main (in main_2)
==10070==
==10070== 64 bytes in 1 blocks are definitely lost in loss record 2 of 2
==10070== at 0x4838E0F: operator new(unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==10070== by 0x10A710: _Z7processv.actor(process()::_Z7processv.frame*) (in main_2)
==10070== by 0x10AB0E: cppcoro::detail::_ZN7cppcoro6detail19make_sync_wait_taskINS_4taskIiEEiLi0EEENS0_14sync_wait_taskIT0_EEOT_.actor(cppcoro::detail::sync_wait_task<int> cppcoro::detail::make_sync_wait_task<cppcoro::task<int>, int, 0>(cppcoro::task<int>&&)::_ZN7cppcoro6detail19make_sync_wait_taskINS_4taskIiEEiLi0EEENS0_14sync_wait_taskIT0_EEOT_.frame*) (in main_2)
==10070== by 0x10AD8B: cppcoro::awaitable_traits<cppcoro::task<int>&&, void>::await_result_t cppcoro::sync_wait<cppcoro::task<int> >(cppcoro::task<int>&&) (in main_2)
==10070== by 0x10A349: main (in main_2)
==10070==
==10070== LEAK SUMMARY:
==10070== definitely lost: 128 bytes in 2 blocks
==10070== indirectly lost: 0 bytes in 0 blocks
==10070== possibly lost: 0 bytes in 0 blocks
==10070== still reachable: 0 bytes in 0 blocks
==10070== suppressed: 0 bytes in 0 blocks
==10070==
==10070== For lists of detected and suppressed errors, rerun with: -s
==10070== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Maybe it's a gcc bug? The cppcoro task implementation seems correct but I'm no expert.
I would guess its not a gcc bug. You have to destroy coroutine_handles. They don't free the memory, when the object it destroyed. This can easily lead to memory leaks. I think, the destroy is missing in cppcoro.
Compiling on gcc-10.2 (Gentoo Linux) the following code
with options
--std=c++20 -fcoroutines -O2 -lcppcoro -pthread
results in memory leaks according to valgrind.Maybe it's a gcc bug? The cppcoro task implementation seems correct but I'm no expert.