Skip to content

Hold a strong reference to DebuggerController in detached worker threads#1086

Merged
xusheng6 merged 1 commit into
devfrom
fix-controller-thread-lifetime
May 20, 2026
Merged

Hold a strong reference to DebuggerController in detached worker threads#1086
xusheng6 merged 1 commit into
devfrom
fix-controller-thread-lifetime

Conversation

@xusheng6
Copy link
Copy Markdown
Member

Summary

  • The 17 DebuggerController methods that spawn a detached worker thread (Launch, Attach, Connect, Go, GoReverse, Step{Into,Over,Return}{,Reverse}, RunTo{,Reverse}, Restart, Detach, Quit, Pause) all captured this by reference, with nothing ensuring the refcounted controller stayed alive for the duration of the detached call.
  • If the controller's last DbgRef was dropped (e.g. the user closed the tab) before the worker finished, the worker would dereference a freed DebuggerController — that's the crash in Crash below DebuggerController::DetachAndWait #1083 (and the same shape as several other Sentry reports: RspConnector::SendRaw, DbgEngAdapter::ReadMemory, etc.).
  • Fix: each method now takes DbgRef<DebuggerController> self = this; and the lambda captures self by value, so the refcount reflects the running thread and the controller can't be destroyed under it.

The constructor's m_debuggerEventThread (line 41) is unchanged because it's stored as a member and joined explicitly in the destructor — already safe.

Fixes #1083.

Test plan

  • Builds cleanly (ninja debuggercore)
  • Manual: launch + step + close tab while operation in flight, confirm no crash

🤖 Generated with Claude Code

The 17 `Launch`/`Attach`/`Connect`/`Go`/`Step*`/`RunTo*`/`Restart`/`Detach`/
`Quit`/`Pause` methods each spawn a detached `std::thread` that runs the
corresponding `*AndWait` work, capturing `this` by reference. Nothing keeps
the controller alive for the duration of the detached call, so if the
controller's refcount drops to zero before the worker exits (e.g. the user
closes the tab), the worker dereferences a dangling pointer.

Capture a `DbgRef<DebuggerController>` by value into each lambda so the
controller stays alive until the worker thread finishes.

Fixes #1083.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@xusheng6 xusheng6 merged commit 883348e into dev May 20, 2026
1 check passed
@xusheng6 xusheng6 deleted the fix-controller-thread-lifetime branch May 20, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Crash below DebuggerController::DetachAndWait

1 participant