Skip to content

[browser][CoreCLR][R2R] AsyncProfiler callstack identities are missing: Wasm ResumeInfo.DiagnosticIP is null #133626

Description

@lewing

Description

Browser CoreCLR ReadyToRun AsyncProfiler tests receive callstack events but cannot resolve the originating managed methods. This prevents marker-based assertions from observing otherwise-present callstacks. The runtime-async path has a concrete implementation gap: Wasm code generation explicitly emits a null ResumeInfo.DiagnosticIP.

This is R2R-dependent with aggressive trimming held fixed, not evidence for missing trimming roots. A related pair of state-machine ValueTask marker failures is listed below; that path has a different identity provider, so the null ResumeInfo field is not asserted to explain those two failures.

Reproduction Steps

With current browser CoreCLR Release runtime/host/packs and host crossgen2 built, run the existing Tasks tests on Chrome. The browser library-test pipeline enables full trimming and R2R, sets TEST_READY_TO_RUN_MODE=1, and excludes only TestUtilities.dll from R2R (the Tasks assembly and runtime libraries remain in the R2R compilation).

XHARNESS_COMMAND=test-browser ./dotnet.sh build /t:Test \
  src/libraries/System.Runtime/tests/System.Threading.Tasks.Tests/System.Threading.Tasks.Tests.csproj \
  /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR \
  /p:Configuration=Release /p:EnableAggressiveTrimming=true /p:PublishReadyToRun=true \
  /p:Scenario=WasmTestOnChrome /p:InstallChromeForTests=true /p:XunitShowProgress=true \
  /p:WasmXHarnessTestsTimeout=00:03:00 \
  /p:WasmTestAppArgs="-method System.Threading.Tasks.Tests.AsyncProfilerTests.RuntimeAsync_ValueTask_CallstackDepthMatchesChainDepth -method System.Threading.Tasks.Tests.AsyncProfilerTests.RuntimeAsync_CreateCallstackPrecedesResumeCallstack -method System.Threading.Tasks.Tests.AsyncProfilerTests.RuntimeAsync_ResetContext_ReplaysPendingV2Chain -method System.Threading.Tasks.Tests.AsyncProfilerTests.StateMachineAsync_ValueTask_SingleThread_ChainEventsAndCallstack -method System.Threading.Tasks.Tests.AsyncProfilerTests.StateMachineAsync_PoolingValueTask_SingleThread_ChainEventsAndCallstack"

Compare with PublishReadyToRun=false, keeping aggressive trimming true. Force Tasks-only relinking when switching properties: stale incremental outputs can otherwise cause a pre-discovery System.Runtime load failure, which is a separate artifact problem. Once temporary ActiveIssues are applied, remove only their annotations on these methods to reproduce the ON failures.

Expected behavior

Runtime-async callstack identities should resolve to the originating managed methods, including marker methods. The selected tests should pass in both interpreter and R2R configurations.

Actual behavior

The five selected cases fail 5/5 with R2R and interpreted TestUtilities. They all pass in the trimmed interpreter baseline. The full interpreter AsyncProfiler class completes with 137 results: 62 passed, 75 existing skips, 0 failed.

Across earlier grouped and isolated ON runs, 19 distinct marker-assertion failures reproduced and their corresponding OFF cases all passed. These include callstack depth, create/resume ordering, normal/exception simulation, lifecycle, method-count, native-IP-delta, cancellation, WhenAll, scheduler, ValueTask, and pending-context replay checks. RuntimeAsync_UnhandledExceptionUnwind additionally reaches the same missing-marker assertion in isolation, although throwing scenarios can also encounter the separate async exception-escape failure tracked in #132311 and the companion R2R EH report.

A representative exception scenario emits a four-frame create/resume callstack, an unwind of four, and context completion, but the marker-filtered collection is empty. This is not simply a duplicate physical stack-frame count.

Regression?

Unknown whether this ever worked for browser CoreCLR R2R. The Wasm emitter explicitly documents diagnostic IPs as unimplemented. The same aggressively trimmed tests pass with R2R off.

Known Workarounds

Run with PublishReadyToRun=false. Excluding only TestUtilities.dll from R2R does not fix these failures. Temporary method-level ActiveIssue annotations conditioned on PlatformDetection.IsBrowserReadyToRun can preserve interpreter and unaffected-test coverage while this is addressed.

Configuration

Local development runtime on macOS arm64 host, browser-wasm CoreCLR Release target, single-threaded Chromium 153.0.8010.12. Tests target net11.0; the runtime startup banner reports 12.0.0. EnableAggressiveTrimming=true, PublishTrimmed=true, TrimMode=full; R2R ON/OFF is the comparison variable. The failures were refreshed after rebuilding CoreLib/packs with the #133615 dynamic-code substitution fix, and representative cases were refreshed after the TestUtilities-only R2R exclusion.

Other information

In src/coreclr/jit/emit.cpp, the dataSection::asyncResumeInfo path sets target = nullptr under TARGET_WASM, explaining that diagnostic virtual-IP relocation/modeling is not implemented, then assigns that value to DiagnosticIP. AsyncProfiler.CoreCLR.cs serializes Continuation.ResumeInfo->DiagnosticIP as frame identities. The tests' GetMethodNameFromMethodId does not resolve zero, so HasMarkerFrame cannot match these frames.

StateMachineAsync_ValueTask_SingleThread_ChainEventsAndCallstack and StateMachineAsync_PoolingValueTask_SingleThread_ChainEventsAndCallstack also fail only ON, but their AsyncStateMachineDiagnostics<TStateMachine>.ResolveMethodId path uses reflected MoveNext / RuntimeMethodHandle.GetNativeCodeInternal. Their precise failure mechanism still needs investigation; they are correlated diagnostic-identity symptoms, not proven instances of the null ResumeInfo cause.

#133610 filters duplicate physical PrestubMethodFrame stack entries; it does not populate the missing runtime-async diagnostic identities. No runtime fix was merged or tested as part of this report.

Note

This issue was generated by GitHub Copilot from locally reproduced test results and source inspection.

Activity

  1. added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Sep 10, 2026
  2. dotnet-policy-service commented on Sep 10, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
    See info in area-owners.md if you want to be subscribed.

  3. lewing commented on Sep 10, 2026

    @lewing
    MemberAuthor

    Full-suite follow-through identified additional instances of the same diagnostic-identity assertions previously masked by process aborts. The method-level diagnostic quarantine now covers 35 methods: 32 RuntimeAsync and three StateMachineAsync single-thread chain variants (Task, ValueTask, and pooled ValueTask). The state-machine identity path remains separately unresolved; this does not establish null ResumeInfo as its mechanism.

    The additional runtime-async failures cover suspend emission/order/depth, create/first-resume matching, resume callstacks, distinct IDs, shrinking chains, handled-exception simulation/unwind, custom synchronization context, ValueTask ordering/IDs/unhandled unwind, and reset/replay balance. All affected methods have passing aggressively trimmed interpreter controls.

    After narrowly quarantining these identities and the separately tracked execution failures, full Tasks results are R2R ON: 332 passed / 427 existing skips / 0 failed, OFF: 379 passed / 427 skips / 0 failed. Exactly 47 cases from 38 annotated methods across the three issues are omitted ON and pass OFF; every other case has identical results. Only TestUtilities.dll is excluded from R2R. The 47 ActiveIssue-filtered cases are not included in the reported 427 skips.

    Note

    This update was generated by GitHub Copilot from local source changes and ON/OFF result XML.

  4. dotnet-policy-service commented on Sep 10, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara
    See info in area-owners.md if you want to be subscribed.

  5. AndyAyersMS commented on Sep 10, 2026

    @AndyAyersMS
    Member

    IIRC there is no easy way to support this. Will look again though.

  6. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 10, 2026
  7. self-assigned this
    on Sep 10, 2026
  8. davidwrighton commented on Sep 11, 2026

    @davidwrighton
    Member

    @AndyAyersMS I can take a look at this. We should be able to generate a valid DiagnosticIP with a helper call.

  9. added a commit that references this issue on Sep 14, 2026
    e377ef8
  10. added a commit that references this issue on Sep 18, 2026
    f73e2a4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

arch-wasmWebAssembly architecturearea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions