From eef0d84d1f4b1fb73261ccadf7e3bcd1c69673cd Mon Sep 17 00:00:00 2001 From: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> Date: Tue, 17 Feb 2026 16:44:51 +0000 Subject: [PATCH] more fixes Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com> --- .../workflows/reusable-build-test-config.yml | 2 +- cspell.config.yaml | 1 + sanitizers/suppressions/tsan.supp | 126 +++++------------- src/xrpld/app/main/Application.cpp | 13 +- 4 files changed, 49 insertions(+), 93 deletions(-) diff --git a/.github/workflows/reusable-build-test-config.yml b/.github/workflows/reusable-build-test-config.yml index cc870764a0..39840fc082 100644 --- a/.github/workflows/reusable-build-test-config.yml +++ b/.github/workflows/reusable-build-test-config.yml @@ -206,7 +206,7 @@ jobs: if: ${{ !inputs.build_only && env.SANITIZERS_ENABLED == 'true' }} run: | echo "ASAN_OPTIONS=print_stacktrace=1:detect_container_overflow=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/asan.supp" >> ${GITHUB_ENV} - echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0" >> ${GITHUB_ENV} + echo "TSAN_OPTIONS=second_deadlock_stack=1:halt_on_error=0:suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/tsan.supp" >> ${GITHUB_ENV} echo "UBSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/ubsan.supp" >> ${GITHUB_ENV} echo "LSAN_OPTIONS=suppressions=${GITHUB_WORKSPACE}/sanitizers/suppressions/lsan.supp" >> ${GITHUB_ENV} diff --git a/cspell.config.yaml b/cspell.config.yaml index b2f4a33769..e78624a50e 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -96,6 +96,7 @@ words: - doxyfile - dxrpl - endmacro + - eventfd - exceptioned - Falco - finalizers diff --git a/sanitizers/suppressions/tsan.supp b/sanitizers/suppressions/tsan.supp index 1626a90aa0..223d81cd65 100644 --- a/sanitizers/suppressions/tsan.supp +++ b/sanitizers/suppressions/tsan.supp @@ -1,101 +1,45 @@ -# The idea is to empty this file gradually by fixing the underlying issues and removing suppresions. +# TSAN suppression file for rippled. +# Only suppress issues in third-party libraries and TSAN's own instrumentation. +# Races in rippled's own code should be fixed, not suppressed. -# Suppress race in Boost ASIO scheduler detected by GCC-15 -# This is a false positive in Boost's internal pipe() synchronization +# Boost ASIO / Boost Context false positives +# These are internal to Boost's reactor, fiber context switching, and memory management. race:boost/asio/ race:boost/context/ race:boost/asio/executor.hpp race:boost::asio - -# Suppress tsan related issues in rippled code. -race:src/libxrpl/basics/make_SSLContext.cpp -race:src/libxrpl/basics/Number.cpp -race:src/libxrpl/json/json_value.cpp -race:src/libxrpl/json/to_string.cpp -race:src/libxrpl/ledger/OpenView.cpp -race:src/libxrpl/net/HTTPClient.cpp -race:src/libxrpl/nodestore/backend/NuDBFactory.cpp -race:src/libxrpl/protocol/InnerObjectFormats.cpp -race:src/libxrpl/protocol/STParsedJSON.cpp -race:src/libxrpl/resource/ResourceManager.cpp -race:src/test/app/Flow_test.cpp -race:src/test/app/LedgerReplay_test.cpp -race:src/test/app/NFToken_test.cpp -race:src/test/app/Offer_test.cpp -race:src/test/app/ValidatorSite_test.cpp -race:src/test/consensus/NegativeUNL_test.cpp -race:src/test/jtx/impl/Env.cpp -race:src/test/jtx/impl/JSONRPCClient.cpp -race:src/test/jtx/impl/pay.cpp -race:src/test/jtx/impl/token.cpp -race:src/test/rpc/Book_test.cpp -race:src/xrpld/app/ledger/detail/InboundTransactions.cpp -race:src/xrpld/app/main/Application.cpp -race:src/xrpld/app/main/GRPCServer.cpp -race:src/xrpld/app/misc/detail/AmendmentTable.cpp -race:src/xrpld/app/misc/FeeVoteImpl.cpp -race:src/xrpld/app/rdb/detail/Wallet.cpp -race:src/xrpld/overlay/detail/OverlayImpl.cpp -race:src/xrpld/peerfinder/detail/PeerfinderManager.cpp -race:src/xrpld/peerfinder/detail/SourceStrings.cpp -race:src/xrpld/rpc/detail/ServerHandler.cpp -race:xrpl/server/detail/Door.h -race:xrpl/server/detail/Spawn.h -race:xrpl/server/detail/ServerImpl.h -race:xrpl/nodestore/detail/DatabaseNodeImp.h -race:src/libxrpl/beast/utility/beast_Journal.cpp -race:src/test/beast/LexicalCast_test.cpp -race:ripple::ServerHandler - -# More suppressions in external library code. -race:crtstuff.c -race:pipe - -# Deadlock / lock-order-inversion suppressions -# Note: GCC's TSAN may not fully support all deadlock suppression patterns -deadlock:src/libxrpl/beast/utility/beast_Journal.cpp -deadlock:src/libxrpl/beast/utility/beast_PropertyStream.cpp -deadlock:src/test/beast/beast_PropertyStream_test.cpp -deadlock:src/xrpld/core/detail/Workers.cpp -deadlock:src/xrpld/app/misc/detail/Manifest.cpp -deadlock:src/xrpld/app/misc/detail/ValidatorList.cpp -deadlock:src/xrpld/app/misc/detail/ValidatorSite.cpp - -signal:src/libxrpl/beast/utility/beast_Journal.cpp -signal:src/xrpld/core/detail/Workers.cpp -signal:src/xrpld/core/JobQueue.cpp -signal:ripple::Workers::Worker - -# Aggressive suppressing of deadlock tsan errors -deadlock:pthread_create -deadlock:pthread_rwlock_rdlock -deadlock:boost::asio - -# Suppress SEGV crashes in TSAN itself during stringbuf operations -# This appears to be a GCC-15 TSAN instrumentation issue with basic_stringbuf::str() -# Commonly triggered in beast::Journal::ScopedStream destructor -signal:std::__cxx11::basic_stringbuf -signal:basic_stringbuf -signal:basic_ostringstream - -called_from_lib:libclang_rt -race:ostreambuf_iterator -race:basic_ostream - -# Suppress SEGV in Boost ASIO memory allocation with GCC-15 TSAN -signal:boost::asio::aligned_new -signal:boost::asio::detail::memory - -# Suppress SEGV in execute_native_thread_routine -signal:execute_native_thread_routine - -# Suppress data race in Boost Context fiber management -# This is a false positive in Boost's exception state management during fiber context switching -race:__cxxabiv1::manage_exception_state race:boost::context::fiber::resume race:boost::asio::detail::spawned_fiber_thread race:boost::asio::detail::spawned_fiber_thread::suspend_with race:boost::asio::detail::spawned_fiber_thread::destroy - -# Suppress data race in __tsan_memcpy called from Boost fiber operations +race:__cxxabiv1::manage_exception_state race:__tsan_memcpy + +# TSAN's own syscall interceptors (false positives from fd tracking) +race:crtstuff.c +race:pipe +race:epoll_ctl +race:epoll_create +race:closedir +race:close +race:socket +race:accept +race:eventfd + +# C++ standard library internals +race:ostreambuf_iterator +race:basic_ostream +called_from_lib:libclang_rt + +# Deadlock false positives in Boost and threading primitives +deadlock:pthread_create +deadlock:pthread_rwlock_rdlock +deadlock:boost::asio + +# Signal/crash suppressions for GCC TSAN instrumentation issues +signal:std::__cxx11::basic_stringbuf +signal:basic_stringbuf +signal:basic_ostringstream +signal:boost::asio::aligned_new +signal:boost::asio::detail::memory +signal:execute_native_thread_routine diff --git a/src/xrpld/app/main/Application.cpp b/src/xrpld/app/main/Application.cpp index 4d6cad195a..70cc0483fe 100644 --- a/src/xrpld/app/main/Application.cpp +++ b/src/xrpld/app/main/Application.cpp @@ -1035,7 +1035,13 @@ private: bool ApplicationImp::setup(boost::program_options::variables_map const& cmdline) { - startIOThreads(); + // NOTE: IO threads are intentionally NOT started here. + // All setup work is non-blocking (it enqueues async work to the + // io_context but doesn't require it to be processed yet). + // IO threads are started at the beginning of start() to avoid + // data races between the main thread doing setup and IO threads + // processing enqueued work concurrently. + m_resourceManager->start(); m_nodeStore->startReadThreads(); @@ -1370,6 +1376,11 @@ ApplicationImp::start(bool withTimers) { JLOG(m_journal.info()) << "Application starting. Version is " << BuildInfo::getVersionString(); + // Start IO threads now that all setup is complete. + // This must happen before starting subsystems that post work + // to the io_context (resolver, overlay, etc.). + startIOThreads(); + if (withTimers) { setSweepTimer();