diff --git a/cmake/XrplConfig.cmake b/cmake/XrplConfig.cmake index 6a28d2635d..930320ac2f 100644 --- a/cmake/XrplConfig.cmake +++ b/cmake/XrplConfig.cmake @@ -16,12 +16,12 @@ find_dependency(Boost COMPONENTS chrono container - coroutine + context + coroutine2 date_time filesystem program_options regex - system thread) #[=========================================================[ OpenSSL diff --git a/cmake/XrplInterface.cmake b/cmake/XrplInterface.cmake index f471b37dd7..b89b1f7060 100644 --- a/cmake/XrplInterface.cmake +++ b/cmake/XrplInterface.cmake @@ -22,7 +22,7 @@ target_compile_definitions( BOOST_FILESYSTEM_NO_DEPRECATED > $<$>: - BOOST_COROUTINES_NO_DEPRECATION_WARNING + BOOST_COROUTINES2_NO_DEPRECATION_WARNING BOOST_BEAST_ALLOW_DEPRECATED BOOST_FILESYSTEM_DEPRECATED > diff --git a/cmake/deps/Boost.cmake b/cmake/deps/Boost.cmake index f8193f7a95..9506693a8d 100644 --- a/cmake/deps/Boost.cmake +++ b/cmake/deps/Boost.cmake @@ -4,13 +4,12 @@ include(XrplSanitizers) find_package(Boost REQUIRED COMPONENTS chrono container - coroutine + context date_time filesystem json program_options regex - system thread) add_library(xrpl_boost INTERFACE) @@ -21,7 +20,7 @@ target_link_libraries( INTERFACE Boost::headers Boost::chrono Boost::container - Boost::coroutine + Boost::context Boost::date_time Boost::filesystem Boost::json diff --git a/conan/profiles/sanitizers b/conan/profiles/sanitizers index 4c859b939b..40871240bf 100644 --- a/conan/profiles/sanitizers +++ b/conan/profiles/sanitizers @@ -65,11 +65,14 @@ tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags" [options] {% if sanitizers %} {% if "address" in sanitizers %} -# Build Boost.Context with ucontext backend (not fcontext) so that -# ASAN fiber-switching annotations (__sanitizer_start/finish_switch_fiber) -# are compiled into the library. fcontext (assembly) has no ASAN support. -boost/*:extra_b2_flags=context-impl=ucontext address-sanitizer=norecover -# Boost stacktrace fails to build with some sanitizers -boost/*:without_stacktrace=True + # Build Boost.Context with ucontext backend (not fcontext) so that + # ASAN fiber-switching annotations (__sanitizer_start/finish_switch_fiber) + # are compiled into the library. fcontext (assembly) has no ASAN support. + # define=BOOST_USE_ASAN=1 is critical: it must be defined when building + # Boost.Context itself so the ucontext backend compiles in the ASAN annotations. + boost/*:extra_b2_flags=context-impl=ucontext address-sanitizer=on define=BOOST_USE_ASAN=1 + boost/*:without_context=False + # Boost stacktrace fails to build with some sanitizers + boost/*:without_stacktrace=True {% endif %} {% endif %} diff --git a/conanfile.py b/conanfile.py index 866d853b03..25a5352b66 100644 --- a/conanfile.py +++ b/conanfile.py @@ -58,6 +58,9 @@ class Xrpl(ConanFile): "tests": False, "unity": False, "xrpld": False, + "boost/*:without_context": False, + "boost/*:without_coroutine": True, + "boost/*:without_coroutine2": False, "date/*:header_only": True, "ed25519/*:shared": False, "grpc/*:shared": False, @@ -126,6 +129,9 @@ class Xrpl(ConanFile): self.options["boost"].visibility = "global" if self.settings.compiler in ["clang", "gcc"]: self.options["boost"].without_cobalt = True + self.options["boost"].without_context = False + self.options["boost"].without_coroutine = True + self.options["boost"].without_coroutine2 = False # Check if environment variable exists if "SANITIZERS" in os.environ: sanitizers = os.environ["SANITIZERS"] @@ -202,7 +208,8 @@ class Xrpl(ConanFile): "boost::headers", "boost::chrono", "boost::container", - "boost::coroutine", + "boost::context", + "boost::coroutine2", "boost::date_time", "boost::filesystem", "boost::json", diff --git a/include/xrpl/core/Coro.ipp b/include/xrpl/core/Coro.ipp index d8269d6f47..8829880829 100644 --- a/include/xrpl/core/Coro.ipp +++ b/include/xrpl/core/Coro.ipp @@ -1,33 +1,21 @@ #pragma once -#include - namespace xrpl { -// Coroutine stack size is set to 2MB to provide sufficient headroom for -// deep call stacks in RPC operations. With 1MB, stack exhaustion occurred -// in production scenarios, particularly in: -// - RPC handlers processing complex JSON (ServerHandler::processRequest) -// - Transaction validation with deep parsing (TransactionSign::getCurrentNetworkFee) -// - Amount parsing with boost::split operations (amountFromJson) -// The 2MB stack provides ~50% safety margin even for the deepest observed -// call chains while keeping memory overhead reasonable (~2MB per coroutine). template JobQueue::Coro::Coro(Coro_create_t, JobQueue& jq, JobType type, std::string const& name, F&& f) : jq_(jq) , type_(type) , name_(name) , running_(false) - , coro_( - [this, fn = std::forward(f)](boost::coroutines::asymmetric_coroutine::push_type& do_yield) { - yield_ = &do_yield; - yield(); - fn(shared_from_this()); + , coro_([this, fn = std::forward(f)](boost::coroutines2::coroutine::push_type& do_yield) { + yield_ = &do_yield; + yield(); + fn(shared_from_this()); #ifndef NDEBUG - finished_ = true; + finished_ = true; #endif - }, - boost::coroutines::attributes(megabytes(4))) // 4MB stack + }) { } diff --git a/include/xrpl/core/JobQueue.h b/include/xrpl/core/JobQueue.h index b410e200e1..e95952d399 100644 --- a/include/xrpl/core/JobQueue.h +++ b/include/xrpl/core/JobQueue.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include @@ -48,8 +48,8 @@ public: std::mutex mutex_; std::mutex mutex_run_; std::condition_variable cv_; - boost::coroutines::asymmetric_coroutine::pull_type coro_; - boost::coroutines::asymmetric_coroutine::push_type* yield_; + boost::coroutines2::coroutine::pull_type coro_; + boost::coroutines2::coroutine::push_type* yield_; #ifndef NDEBUG bool finished_ = false; #endif