Skip to content

Commit d490308

Browse files
xusheng6claude
andcommitted
Use detached std::thread instead of WorkerEnqueue for accessor deletion
BinaryNinja's worker threads are meant for analysis tasks. Use a plain detached thread instead for deferring the m_accessor deletion off the event thread. Also expanded the comment to document the race condition root cause: Destroy() can remove the global array ref between SetConnectionStatus (NotConnected) and the accessor deletion, making the accessor's DbgRef the last reference to the controller. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent dc76983 commit d490308

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

core/debuggercontroller.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,13 +1875,18 @@ void DebuggerController::EventHandler(const DebuggerEvent& event)
18751875

18761876
if (m_accessor)
18771877
{
1878-
// Defer deletion to a worker thread. The accessor holds a DbgRef<DebuggerController>,
1878+
// Defer deletion to a detached thread. The accessor holds a DbgRef<DebuggerController>,
18791879
// and if it is the last reference, deleting it here (on the event thread) would trigger
1880-
// ~DebuggerController which calls m_debuggerEventThread.join() -- deadlocking because
1881-
// we ARE the event thread.
1880+
// ~DebuggerController which calls m_debuggerEventThread.join() -- deadlocking/crashing
1881+
// because we ARE the event thread.
1882+
//
1883+
// This can happen when Destroy() races with event processing: EventHandler sets
1884+
// ConnectionStatus to NotConnected (line above), and another thread observes this,
1885+
// calls Destroy() which removes the global array ref, making the accessor's DbgRef
1886+
// the last reference to the controller.
18821887
auto* accessor = m_accessor;
18831888
m_accessor = nullptr;
1884-
BinaryNinja::WorkerEnqueue([accessor]() { delete accessor; });
1889+
std::thread([accessor]() { delete accessor; }).detach();
18851890
}
18861891
m_lastIP = m_currentIP;
18871892
m_currentIP = 0;

0 commit comments

Comments
 (0)