Skip to content

Preserve the V1 async-profiler stitch boundary - #132158

Merged
steveisok merged 1 commit into
mainfrom
steveisok-debug-async-profiler-frames
Aug 12, 2026
Merged

steveisok merged 1 commit into
mainfrom
steveisok-debug-async-profiler-frames

Conversation

@steveisok

Copy link
Copy Markdown
Member

Summary

  • Mark AsyncProfilerAsyncStateMachineBox<TStateMachine>.MoveNextAsDispatcher as NoInlining so the V1 stitch boundary remains a physical frame.
  • Extend the existing V1 method-name contract test to require MethodImplAttributes.NoInlining for that boundary.
  • Include every captured DiagnosticMethodInfo declaring type and method name in physical-stack assertion failures, with explicit unknown markers.

Debugger evidence

A checked CoreCLR debugger probe showed that Debug and Release both:

  • allocate AsyncProfilerAsyncStateMachineBox<TStateMachine>;
  • arm _isLeaf before resume;
  • execute through MoveNextAsDispatcher; and
  • resolve that frame through DiagnosticMethodInfo when it is physically present.

The compiler lowering differs as expected: the Debug state machine is a class, while the Release state machine is a struct. This rules out an alternate Debug dispatch path, listener activation, box selection, and frame classification as the intended difference. The missing CI frame therefore exposes an unenforced physical-frame contract.

The CI-specific omission was not reproduced locally, including with Debug libraries, checked CoreCLR, CI build properties, tiering disabled, ReadyToRun disabled, and JIT minopts. Normal PR CI should validate the affected Debug/checked legs.

Validation

  • ./build.sh clr.corelib+clr.nativecorelib+libs.pretest -rc checked -lc debug
  • V1AsyncDispatchMethod_NameContract_IsStable: 2 passed
  • StateMachineAsync_ResumeDispatchStack: 1 passed
  • StateMachineAsync_InlineCompletionClimb: 1 passed

Fixes #132025
Fixes #132026

Note

This PR description was generated with GitHub Copilot.

Keep MoveNextAsDispatcher as a physical frame and strengthen its contract and stack-capture diagnostics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @dotnet/area-system-threading-tasks
See info in area-owners.md if you want to be subscribed.

@steveisok
steveisok requested a review from a team August 11, 2026 19:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reinforces the async-profiler V1 “stitch boundary” contract by ensuring AsyncProfilerAsyncStateMachineBox<TStateMachine>.MoveNextAsDispatcher remains a physical (non-inlined) stack frame, and by tightening tests to validate both the naming and non-inlining requirements while improving failure diagnostics.

Changes:

  • Mark AsyncProfilerAsyncStateMachineBox<TStateMachine>.MoveNextAsDispatcher as MethodImplOptions.NoInlining to preserve the physical stitch boundary frame.
  • Extend the V1 method-name contract test to also require MethodImplAttributes.NoInlining for V1.MoveNextAsDispatcher.
  • Improve test diagnostics by capturing and printing full per-frame DeclaringType::Method information (with explicit <unknown-*> markers) when stack-based assertions fail.
Show a summary per file
File Description
src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncProfilerV2Tests.cs Update resume-dispatch capture plumbing to carry diagnostic frame strings into boundary assertions.
src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncProfilerV1Tests.cs Extend V1 boundary tests to pass diagnostic frames through and enforce NoInlining for MoveNextAsDispatcher; improve assertion failure messages.
src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Runtime.CompilerServices/AsyncProfilerTests.cs Enhance shared helpers to capture diagnostic frame names and thread them into assertion helpers; expose MethodInfo for contract checks.
src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/AsyncTaskMethodBuilderT.cs Add MethodImplOptions.NoInlining to MoveNextAsDispatcher to preserve the V1 physical stitch boundary frame.

Review details

  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

@steveisok
steveisok enabled auto-merge (squash) August 12, 2026 16:31
@steveisok

Copy link
Copy Markdown
Member Author

/ba-g Helix monitor job failed

@steveisok
steveisok merged commit e97796d into main Aug 12, 2026
130 of 132 checks passed
@steveisok
steveisok deleted the steveisok-debug-async-profiler-frames branch August 12, 2026 16:31
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-rc1 milestone Aug 13, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Test] AsnycProfilerV1Tests StateMachineAsync_ResumeDispatchStack Fails [Test] AsnycProfilerV1Tests StateMachineAsync_InlineCompletionClimb Fails

3 participants