diff --git a/cmake/deps/Boost.cmake b/cmake/deps/Boost.cmake index 7594ddc806..3b4e165dcf 100644 --- a/cmake/deps/Boost.cmake +++ b/cmake/deps/Boost.cmake @@ -61,3 +61,14 @@ if(enable_asan) INTERFACE BOOST_USE_ASAN BOOST_USE_UCONTEXT ) endif() + +# TSAN also requires the ucontext backend so that Boost.Context uses +# POSIX ucontext (not fcontext assembly) for fiber switching. This +# allows TSAN to properly track context switches and avoids false positives. +# These defines must match what Boost was compiled with (see conan/profiles/sanitizers). +if(enable_tsan) + target_compile_definitions( + xrpl_boost + INTERFACE BOOST_USE_TSAN BOOST_USE_UCONTEXT + ) +endif() diff --git a/conan/profiles/sanitizers b/conan/profiles/sanitizers index 6d37425f43..6af5565bcb 100644 --- a/conan/profiles/sanitizers +++ b/conan/profiles/sanitizers @@ -82,5 +82,12 @@ tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags" boost/*:without_context=False # Boost stacktrace fails to build with some sanitizers boost/*:without_stacktrace=True + {% elif "thread" in sanitizers %} + # Build Boost.Context with ucontext backend (not fcontext) so that + # TSAN can instrument fiber/context switches. fcontext uses raw assembly + # which TSAN cannot intercept, causing false positives and link errors. + boost/*:extra_b2_flags=context-impl=ucontext thread-sanitizer=on define=BOOST_USE_TSAN=1 + boost/*:without_context=False + boost/*:without_stacktrace=True {% endif %} {% endif %}