Fix data race on RspConnector lifetime in Gdb/Corellium/Esreven adapters#1075
Open
xusheng6 wants to merge 1 commit into
Open
Fix data race on RspConnector lifetime in Gdb/Corellium/Esreven adapters#1075xusheng6 wants to merge 1 commit into
xusheng6 wants to merge 1 commit into
Conversation
DebuggerController::ExecuteAdapterAndWait uses two separate mutexes so that Pause/Quit/Detach can run concurrently with a blocked Go/Receive on another thread (debuggercontroller.cpp:2678-2695). That design is intentional, but it means BreakInto races against ResponseHandler's own teardown of m_rspConnector on target exit. The previous raw-pointer field had no synchronization on either the load or the delete, so the read side could deref a freed object. Wrap the field in a small AtomicRspConnector helper (mutex-guarded shared_ptr) and have every accessor load a strong reference before use. Teardown sites now just store(nullptr) - the connector is destroyed when the last strong reference drops, never under an in-flight call. The same fix is applied to GdbAdapter and EsrevenAdapter since they share the pattern. Fixes #1074 Refs #1066 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Properly fixes the race that #1073 only narrowed.
DebuggerController::ExecuteAdapterAndWaitdeliberately uses two separate mutexes (debuggercontroller.cpp:2678-2695) soPause/Quit/Detachcan fire while another thread is blocked insideGo→ResponseHandler. That design is correct: a blockingrecvon one thread has to coexist with a\x03send on another. The bug is thatm_rspConnectoritself - the raw pointer field - was read and freed concurrently with no synchronization, so the operations could legitimately race against a use-after-free of the connector object.Approach
Wrap
m_rspConnectorin a smallAtomicRspConnectorhelper added torspconnector.h: a mutex-guardedstd::shared_ptr<RspConnector>withload()andstore()methods. Every accessor callsload()once to obtain a strong reference, then operates on the local; the lock is held only for the duration of a shared_ptr copy (a refcount bump), never during actual I/O. Teardown sites juststore(nullptr)- the connector destructs when the last strong reference drops, which is now guaranteed to be after every in-flight call returns.The same pattern is applied to all three RSP-based adapters (
CorelliumAdapter,GdbAdapter,EsrevenAdapter) since they share the identical raw-pointer-with-no-lock layout.Why not
std::atomic<std::shared_ptr<T>>: libc++ on macOS (Apple's stdlib) doesn't implement the C++20 specialization without a trivially-copyableT, so the direct C++20 form does not compile here. The mutex-wrapped equivalent is portable and has the same observable semantics for our use.Tradeoff
Every read site now hoists a local at the top of the method. Roughly 30 call sites in
corelliumadapter.cpp, 55 ingdbadapter.cpp, 85 inesrevenadapter.cppare touched. Mechanical, no behavior change beyond the synchronization itself. The two-mutex design inDebuggerControlleris intact.Fixes #1074
Refs #1066
Test plan
🤖 Generated with Claude Code