[AsyncV2] Runtime support for breakpoints and stepping#123644
Merged
max-charlamb merged 19 commits intodotnet:mainfrom Feb 6, 2026
Merged
[AsyncV2] Runtime support for breakpoints and stepping#123644max-charlamb merged 19 commits intodotnet:mainfrom
max-charlamb merged 19 commits intodotnet:mainfrom
Conversation
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
This was referenced Jan 27, 2026
Open
jkotas
reviewed
Jan 28, 2026
jkotas
reviewed
Jan 28, 2026
ebc111e to
ae0626f
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds dedicated runtime and debugger support for async thunk methods so that breakpoints and stack walking operate on the underlying async methods rather than the thunk wrappers, and hides internal/diagnostics-only frames from the debugger.
Changes:
- Introduces
AsyncThunkStubManagerand wires it into the stub manager initialization and DAC type system so async thunk code can be recognized and traced correctly. - Adjusts debugger stack walking, breakpoint binding, and IL patching logic to skip async thunk methods (and generally
IsDiagnosticsHiddenmethods), routing behavior instead to the corresponding async method variants. - Extends debugger frame metadata (
fNoMetadata) and stack walking filters so methods markedIsDiagnosticsHiddenare not exposed in the debugger, while preserving existing special handling for IL stubs like multicast and tailcall call-target stubs.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/vm/stubmgr.h | Declares the new AsyncThunkStubManager (including DAC hooks) to recognize and manage async thunk methods as stubs. |
| src/coreclr/vm/stubmgr.cpp | Implements AsyncThunkStubManager (init, stub detection, tracing, DAC memory enumeration) and adds logic in PrecodeStubManager::DoTraceStub to redirect unjitted async thunk calls to the underlying async method. |
| src/coreclr/vm/appdomain.cpp | Registers AsyncThunkStubManager::Init() during SystemDomain::Attach, ensuring the new stub manager is active at runtime startup. |
| src/coreclr/inc/vptr_list.h | Adds AsyncThunkStubManager to the DAC vtable list so DAC can recognize and instantiate it for debugging. |
| src/coreclr/debug/ee/frameinfo.cpp | Updates stack-walk filtering to hide frameless methods marked IsDiagnosticsHidden, while still surfacing certain IL stubs (multicast and tailcall call target) as before. |
| src/coreclr/debug/ee/debugger.cpp | Changes MapAndBindFunctionPatches to early-return for async thunk methods, avoiding binding breakpoints directly to them. |
| src/coreclr/debug/ee/controller.cpp | Ensures AddILPatch skips DebuggerJitInfo instances for async thunk methods so IL breakpoints bind to the underlying async method instead. |
| src/coreclr/debug/daccess/dacdbiimplstackwalk.cpp | Marks frames for IsDiagnosticsHidden methods as fNoMetadata, aligning DAC-side frame metadata with the new hidden-from-diagnostics behavior. |
tommcdon
reviewed
Jan 28, 2026
noahfalk
reviewed
Jan 29, 2026
This was referenced Jan 29, 2026
Co-authored-by: Noah Falk <noahfalk@users.noreply.github.com>
Co-authored-by: Noah Falk <noahfalk@users.noreply.github.com>
e5f5801 to
ee9b1bf
Compare
This was referenced Feb 4, 2026
noahfalk
reviewed
Feb 4, 2026
noahfalk
approved these changes
Feb 5, 2026
lewing
pushed a commit
to lewing/runtime
that referenced
this pull request
Feb 9, 2026
* Add AsyncThunkStubManager * Don't set breakpoints in thunks unless filtered by methoddesc * Refactor breakpoint filtering logic * Check for IsStub in TriggerPatch
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
This PR enables debugger support for stepping into and setting breakpoints in Runtime Async methods. Runtime Async methods generate two
MethodDescvariants with the same metadata token: an async "thunk" (Task-returning adapter) and the actual async method implementation. Without this change, the debugger incorrectly interacts with async thunks, causing step-in failures and breakpoint binding issues.Problem
When stepping into or setting breakpoints on async methods:
Solution
New
AsyncThunkStubManager(stubmgr.cpp,stubmgr.h)Added a new stub manager to recognize and handle async thunk methods during debugger stepping for async v2 methods
Conditionally Skip Async Thunks in Breakpoint Binding (
controller.cpp)Don't bind breakpoints to async thunk using module/token id. Only bind if specified exactly by
MethodDescto allowPrecodeStubManagerto work properly.Handle Async Thunks in Step Patch Triggering (
controller.cpp)Added stub detection in
DebuggerStepper::TriggerPatch:TraceManagerforTRACE_MGR_PUSHtraces to resolve the async variantHide Async Thunks from Debugger Stack Walks (
frameinfo.cpp,dacdbiimplstackwalk.cpp)Extended the frame 'NoMetadata' logic to use
IsDiagnosticsHidden():