-
Notifications
You must be signed in to change notification settings - Fork 25
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
heap-use-after-free error when cancelling spawned awaitable #194
Comments
Are you on HEAD or the boost 1.84 release version? Because I can't reproduce the error above, but had a similar looking one before 61bf8d4. |
I'm working on boost 1.85, which already has the mentioned changes (61bf8d4) |
The error is not 100% reproducible, but in my environment, at least once in 10 launches the error occurred. I tested last time on debug, without optimization. Fedora 40, AMD Ryzen 7 5825U |
|
…boostorg#194 The variable "recs" was allocated on a piece of memory whose lifetime was managed at the level of the coroutine (inside its frame). This led to access to freed memory if that coroutine (its frame) was deleted.
…boostorg#194 The variable "recs" was allocated on a piece of memory whose lifetime was managed at the level of the coroutine (inside its frame). This led to access to freed memory if that coroutine (its frame) was deleted
I've added #196 |
In the code that is based on cobalt, crashes occur. When this code is run under address sanitizer, it detects a "heap-use-after-free" error. I managed to prepare a simplified scenario (maybe not the simplest possible) that leads to this memory violation.
My analysis led me to the conclusion that when we call the spawn method, one of the variables (
recs
) is allocated as a shared_ptr, but on a memory block that is probably saved on the coroutine frame (cobalt/include/boost/cobalt/detail/spawn.hpp:111 ->auto recs = std::allocate_shared<detail::task_receiver<void>>(alloc, std::move(a.receiver_));
)When the coroutine ends, the frame is freed, along with the memory pointed to by the aforementioned shared_ptr. The problem is that access to this shared_ptr is done by another thread and can occur after the frame has been removed. From the point of view of shared_ptr, everything seems to be ok, because the reference count is positive, but because we allocated the object itself (with the counter) on a "local" piece of memory, the whole thing can lead to access to the freed memory.
e.g. changing allocation to
auto recs = std::make_shared<detail::task_receiver<void>>(std::move(a.receiver_));
resolves a problemgcc 14.1, example build with address sanitizer
The text was updated successfully, but these errors were encountered: