Skip to content

CoreCLR browser-Wasm trimmed builds stage mismatched PDBs, breaking in-memory stack traces #136286

Closed

Description

@radekdoulik

Description

Trimmed CoreCLR browser-Wasm builds can stage assemblies from the ILLink output
together with their original, untrimmed compiler PDBs. The mismatched symbols
break source information in in-memory stack traces.

This caused System.Diagnostics.SymbolStore.Tests.StackTraceSymbolsTests.StackTraceSymbolsFromMemory
to fail in libraries outerloop build 1643575,
source 2c81f626e5289f4d06a603952e38d1a6eeb6bd12, Helix job
38e0e19c-36c1-40a4-ba1d-e7ee14e649fd, work item
WasmTestOnChrome-CLR-ST-Batch-18.

The issue reproduces on a clean main checkout at
53ac1a959b35807ae208b77362a87cce94a77a0f. It affects both project and dependency
PDB selection, not only the StackTrace test assembly.

Reproduction Steps

From a clean checkout of 53ac1a959b35807ae208b77362a87cce94a77a0f on macOS/arm64:

export PATH="/opt/homebrew/bin:$PATH"
export DOTNET_WASM_TOOL_CACHE_DIR="$PWD/.dotnet/wasm-tools"
./build.sh clr+libs+host -os browser -c Release -rc Checked
./build.sh packs+libs.pretest -os browser -c Release -rc Checked \
  /p:RuntimeFlavor=CoreCLR /p:EnableAggressiveTrimming=true \
  /p:AotHostArchitecture=arm64 /p:AotHostOS=osx
./dotnet.sh build src/libraries/Common/tests/TestUtilities/TestUtilities.csproj \
  /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR \
  /p:Configuration=Release /p:RuntimeConfiguration=Checked \
  /p:EnableAggressiveTrimming=true
XHARNESS_COMMAND=test-browser ./dotnet.sh build /t:Test \
  src/libraries/System.Diagnostics.StackTrace/tests/System.Diagnostics.StackTrace.Tests.csproj \
  /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR \
  /p:Configuration=Release /p:RuntimeConfiguration=Checked \
  /p:TestWasmReadyToRun=true /p:EnableAggressiveTrimming=true \
  /p:TestScope=all /p:OuterLoop=true \
  /p:Scenario=WasmTestOnChrome /p:InstallChromeForTests=true \
  /p:WasmXHarnessMonoArgs=--diagnostic-tracing \
  /bl:artifacts/symbols-before-r2r.binlog

The clean baseline and prerequisites pass. The final test command fails with
MSBuild exit 1 and XHarness exit 71. The uploaded/raw test XML is authoritative;
the original CI parent/send task was green despite this test failure.

Expected behavior

The build stages PDBs matching the selected linked assemblies. The in-memory
StackTrace test obtains InMemorySymbols.cs as the source filename.
Symbols removed by the linker are not replaced with stale compiler PDBs.

Actual behavior

StackTraceSymbolsFromMemory fails:

Assert.Equal() Failure
Expected: "InMemorySymbols.cs"
Actual:   null

Both the original CI XML and the clean local reproduction have 141 total,
135 passed, 1 failed, 5 skipped
.

The actual downloaded test image has CodeView GUID
f2a8b6e3-c5d0-eff0-a560-95cd2ca62284, stamp 4024418303, matching its linked
PDB. However, the PDB registered in memory has GUID
a7f2ab18-457b-48c1-9394-b8e151325514, stamp 2673514198, and is byte-for-byte
the original compiler PDB.

CaptureFrame is token 0x0600002A in that image. The linked PDB maps it to
InMemorySymbols.cs:123; the loaded compiler PDB has no sequence points for
that token. It also incorrectly maps the test method's token to
SymbolTokenTests.cs:24, explaining the misleading failure-stack location.
The loaded TestUtilities assembly/PDB pair is mismatched as well.

Regression?

The introducing commit and release-to-release regression range have not been
bisected. #135653, which added
in-memory PDB lookup and this test, is already included in the failing CI source;
its merge does not resolve this failure.

Known Workarounds

No supported end-user workaround was verified. A focused build-target correction
that stages the matching linked PDBs fixes the reproduced failure without
changing the assertion, adding skips, or modifying the VM.

Configuration

  • .NET runtime source: 53ac1a959b35807ae208b77362a87cce94a77a0f.
  • Host: macOS 26.7.1, arm64; target: CoreCLR browser-Wasm.
  • Release libraries, Checked runtime; trimmed per-app ReadyToRun payload.
  • Repository SDK: 11.0.100-rc.1.26420.103; Emscripten: 6.0.2.
  • Browser: Chromium 155.0.8059.85-1697595-osx-arm64.
  • The loaded test/CoreLib R2R images were verified against the actual local
    crossgen2 outputs; this is not inferred only from an environment flag.

Other information

_WasmCoreClrRestrictBuildToTrimmedClosure redirects dependency assemblies and
the project assembly to linked output, but leaves dependency PDBs pointing to
the untrimmed compilation. _ComputeWasmBuildCandidates also supplies the final
project assembly together with _DebugSymbolsIntermediatePath, its original
compiler PDB.

#135619 already selects adjacent
PDBs on the publish side; it does not correct these build-side inputs.
In-memory symbol lookup consumes the supplied image without the CodeView
identity validation performed by file-backed portable-PDB discovery.

I have prepared a focused fix for project/dependency symbol staging and a
two-case regression for retained/removed symbols, and will submit a linked PR.
With the fix, the unchanged full StackTrace suite passes 141 total, 136 passed,
0 failed, 5 skipped
in trimmed R2R, trimmed interpreter, untrimmed WebCIL,
untrimmed raw-PE, and native-relinked trimmed R2R configurations. The new build
regression passes both cases. These are local results, not a whole-CI rerun.

Note

This issue was generated by GitHub Copilot.

Activity

  1. dotnet-policy-service commented on Oct 22, 2026

    @dotnet-policy-service
    Contributor

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

  2. added a commit that references this issue on Oct 29, 2026
    d69d3c7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions