fix: Switch to boost::coroutine2 - #6372
Conversation
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #6372 +/- ##
=========================================
- Coverage 79.8% 79.8% -0.0%
=========================================
Files 878 878
Lines 67887 67888 +1
Branches 7549 7555 +6
=========================================
- Hits 54206 54197 -9
- Misses 13681 13691 +10
🚀 New features to boost your workflow:
|
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
…RPLF/rippled into pratik/Fix_asan_boost_coroutine_issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
…RPLF/rippled into pratik/Fix_asan_boost_coroutine_issues
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
godexsoft
left a comment
There was a problem hiding this comment.
Leaving some questions.
| ) | ||
| endif() | ||
|
|
||
| # if (SANITIZERS_ENABLED AND is_clang) |
There was a problem hiding this comment.
Is this comment still needed here?
There was a problem hiding this comment.
I was testing if we need to instrument boost with asan or not. It was flaky a bit. Removing now.
| #interceptor_via_fun:swapcontext | ||
| #interceptor_via_fun:makecontext | ||
| #interceptor_via_fun:boost::context::basic_fixedsize_stack*deallocate | ||
| #interceptor_via_fun:boost::context::fiber::~fiber |
There was a problem hiding this comment.
Does this work in practice? i recall these kind of suppressions did not actually work for me because suppressions "only work on your code", not library code.. or so i read online.
There was a problem hiding this comment.
These are commented anyway. I put them for GCC actually, since we can't pass ignorelist at compile time to gcc.
| self.options["boost"].visibility = "global" | ||
| if self.settings.compiler in ["clang", "gcc"]: | ||
| self.options["boost"].without_cobalt = True | ||
| self.options["boost"].without_context = False |
There was a problem hiding this comment.
Does this not duplicate lines 61-63?
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
|
/ai-review |
| [this, fn = std::forward<F>(f)]( | ||
| boost::coroutines::asymmetric_coroutine<void>::push_type& do_yield) { | ||
| boost::coroutines2::asymmetric_coroutine<void>::push_type& do_yield) { | ||
| yield_ = &do_yield; |
There was a problem hiding this comment.
Dangling raw pointer to coroutine push_type parameter
The yield_ member is assigned the address of do_yield, which is the push_type& parameter passed into the coroutine lambda body. While this pointer is valid during coroutine execution (the parameter lives in the coroutine frame), it becomes a dangling pointer once the coroutine completes or is destroyed. The migration from boost::coroutines to boost::coroutines2 preserves this pre-existing pattern, but boost::coroutines2 has stricter lifetime semantics: after fn(shared_from_this()) returns and the coroutine lambda exits, do_yield is destroyed. Any subsequent call through yield_ (e.g., via a stale Coro reference) would access freed memory. The finished_ debug flag partially guards against this but is only active in debug builds.
There was a problem hiding this comment.
There is not path in the code which can create or preserve such a dangling ref. to Coro.
yield can only be called from inside a coroutine's stack, there are no semantics to call it from outside and hence reference any dangling yield_. So the current implementation is safe.
There was a problem hiding this comment.
Three correctness issues flagged inline: wrong coroutine2 type name in Coro.ipp, a no-op default_options mutation in conanfile.py, and missing context-impl=ucontext for the TSAN path in the sanitizers profile.
Review by Claude Opus 4.6 · Prompt: V15
There was a problem hiding this comment.
Pull request overview
This PR migrates the core JobQueue coroutine implementation from Boost.Coroutine to Boost.Coroutine2 (with Boost.Context/ucontext) to improve AddressSanitizer (ASAN) accuracy around context switches, and updates build/config tooling to match.
Changes:
- Replace Boost.Coroutine usage in JobQueue with Boost.Coroutine2 and a protected fixed-size stack allocator.
- Update Conan/CMake/CI sanitizer configuration to build/link Boost.Context appropriately and set ASAN runtime options.
- Remove now-unneeded ASAN suppressions and update spelling dictionary.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sanitizers/suppressions/asan.supp | Removes Boost-related suppressions that should no longer be needed with the coroutine2/ucontext approach. |
| include/xrpl/core/JobQueue.h | Switches coroutine member types and includes to Boost.Coroutine2/Boost.Context. |
| include/xrpl/core/Coro.ipp | Updates coroutine construction to use protected_fixedsize_stack and coroutine2 API. |
| cspell.config.yaml | Adds fcontext to spelling allowlist. |
| conanfile.py | Adjusts Boost options/components and adds sanitizer-driven configuration logic. |
| conan/profiles/sanitizers | Adds sanitizer defines and Boost build options for ucontext/ASAN annotations. |
| cmake/deps/Boost.cmake | Switches linked Boost component from coroutine to context; adds gcc14 warning workaround and ASAN-related defines. |
| cmake/XrplInterface.cmake | Updates deprecation-warning suppression macro for Coroutine2. |
| .github/workflows/reusable-build-test-config.yml | Extends sanitizer job timeout and refines ASAN_OPTIONS (plus gcc-specific tweak). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
ASAN wasn't able to keep track of `boost::coroutine` context switches, and would lead to many false positives being detected. By switching to `boost::coroutine2` and `ucontext`, ASAN is able to know about the context switches advertised by the `boost::fiber` class, which in turn leads to more cleaner ASAN analysis.
High Level Overview of Change
Switch boost::coroutine with boost::coroutine2, to fix ASAN issues
Context of Change
ASAN wasn't able to keep track of boost::coroutine context switches. It would lead to many false positives from ASAN. Switched to boost::coroutine2 and ucontext, allows ASAN to know about the context switches advertized by boost::fiber class. This leads to more cleaner ASAN analysis.
Type of Change
.gitignore, formatting, dropping support for older tooling)Test based testing.