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

Memory leak on gcc-10.2 #35

Open
lacc97 opened this issue Feb 8, 2021 · 1 comment
Open

Memory leak on gcc-10.2 #35

lacc97 opened this issue Feb 8, 2021 · 1 comment

Comments

@lacc97
Copy link

lacc97 commented Feb 8, 2021

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.

@go2sh
Copy link

go2sh commented May 1, 2021

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.

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

2 participants