镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

[browser] Disable stack trace line numbers by default on publish - #136971

Merged
pavelsavara merged 3 commits into
dotnet:mainfrom
pavelsavara:browser-coreclr-trimmed-closure
Nov 6, 2026
Merged

pavelsavara merged 3 commits into
dotnet:mainfrom
pavelsavara:browser-coreclr-trimmed-closure

Conversation

@pavelsavara

@pavelsavara pavelsavara commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Default StackTraceLineNumberSupport to false for browser publishing, including Debug publish, while preserving development-build defaults and explicit property values.
  • Resolve WebAssembly feature configuration before publish trimming, including dotnet publish --no-build.
  • Guard that early configuration so native-only nested publishes cannot write an incomplete boot manifest and shared completion stamp before the outer publish stages managed assemblies.
  • Add browser regression coverage for build -> publish -> build, default behavior, explicit true/false, and publishing without rebuilding. Document source-location opt-in and symbol publishing.

This is a behavioral change: published CoreCLR managed stack traces keep method names, but source file/line lookup now requires explicit opt-in. The existing property restores the previous behavior:

<PropertyGroup>
  <StackTraceLineNumberSupport>true</StackTraceLineNumberSupport>
  <DebugSymbols>true</DebugSymbols>
  <CopyOutputSymbolsToPublishDirectory>true</CopyOutputSymbolsToPublishDirectory>
</PropertyGroup>

Breaking-change documentation has been prepared as a local draft; the source PR is not merged yet.

Size evidence

Using the source-built WebAssembly SDK pack with the same optimized 12.0.0-alpha.1.26528.120 browser runtime pack, a minimal trimmed Debug Blazor publish gives:

Default publish Explicit line-number opt-in
Linked managed assemblies 4 9
Linked managed bytes 2,373,632 2,614,784
Published *.wasm.gz bytes 2,703,287 2,807,850

The default removes exactly System.Collections.Immutable, System.Diagnostics.StackTrace, System.IO.Compression, System.IO.MemoryMappedFiles and System.Reflection.Metadata from both the linked closure and published WebCIL assets: 241,152 managed bytes and 104,563 gzip bytes saved. The consumed SDK target bytes were verified against the source-built package.

Locally built unoptimized Debug CoreLib can retain unreachable PDB-reader code after feature substitution. Size results above intentionally use an optimized shipping runtime pack; browser behavior tests use the locally built Debug runtime.

Validation

All commands ran from the isolated Windows worktree.

.\build.cmd -bl -os browser -subset clr+libs+host+packs -c Debug /p:RuntimeFlavor=CoreCLR /p:EnableHotReloadInRuntimeConfigDevFile=false

Passed: zero warnings/errors.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\pack-final.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:EnableHotReloadInRuntimeConfigDevFile=false .\src\mono\nuget\Microsoft.NET.Sdk.WebAssembly.Pack\Microsoft.NET.Sdk.WebAssembly.Pack.pkgproj

Passed: zero warnings/errors.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\wbt-green-final.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:TestUsingWorkloads=false /p:SdkVersionForWorkloadTesting=12.0.100-alpha.1.26528.120 /p:InstallWorkloadForTesting=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:InstallChromeForTests=false /p:XUnitClassName=Wasm.Build.Tests.DebugLevelTests /t:Test .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj

Passed in Chrome: 6 passed, 0 failed, 0 skipped, including all four new cases and both existing trimmed-PDB cases. The new cases check actual source-line availability and retained method names across build/publish/build. Against the unchanged SDK package, the two new default-publish cases failed because source lines remained enabled; both explicit-override cases passed.

Two additional minimal publishes with the changed SDK package passed exact assertions for the linked and published five-assembly difference above. git diff --check passed.

The complete WBT suite, Mono runtime lane, and interactive managed debugger were not run.

Nested-publish CI follow-up

The early configuration dependency initially ran inside native-only nested publishes.
That generated an incomplete boot manifest before the outer publish staged managed
assemblies, then poisoned its shared incremental completion stamp. A guarded wrapper
now keeps the early dependency in the outer publish only; the original satellite and
reference preparation still runs in both contexts.

The existing workload LazyLoadingTests.FailOnMissingLazyAssembly reproduced
BLAZORSDK1001 with the unguarded package and passed with the guarded source-built
package. Existing coverage therefore catches this regression without adding redundant
tests.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\nested-guard-pack.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:EnableHotReloadInRuntimeConfigDevFile=false .\src\mono\nuget\Microsoft.NET.Sdk.WebAssembly.Pack\Microsoft.NET.Sdk.WebAssembly.Pack.pkgproj

Passed: zero warnings/errors.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\nested-existing-green.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:TestUsingWorkloads=true /p:SdkVersionForWorkloadTesting=12.0.100-alpha.1.26528.120 /p:InstallWorkloadForTesting=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:InstallChromeForTests=false /p:XUnitMethodName=Wasm.Build.Tests.LazyLoadingTests.FailOnMissingLazyAssembly /t:Test .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj

Passed in Chrome: 1 passed, 0 failed, 0 skipped.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\nested-noworkload-confirm.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:TestUsingWorkloads=false /p:SdkVersionForWorkloadTesting=12.0.100-alpha.1.26528.120 /p:InstallWorkloadForTesting=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:InstallChromeForTests=false /p:XUnitMethodName=Wasm.Build.Tests.DebugLevelTests.StackTraceLineNumbersBuildPublishBuild /t:Test .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj

Passed in Chrome: 4 passed, 0 failed, 0 skipped, covering defaults, explicit
true/false, no-build publish, and build/publish/build. An initial run had one
ten-second harness exit-message timeout; that exact published opt-in artifact
independently printed source information, method name and WASM EXIT 0, and the
complete four-case confirmation above passed.

All consumed package targets matched the final source bytes. git diff --check
passed. The complete CI matrix and full Mono test lane have not been rerun locally.

Review follow-up: direct MSBuild publishing

The guarded publish target now applies the line-number default even when publishing
with dotnet msbuild -t:Publish, which does not supply _IsPublishing. Explicit
property values remain honored. The managed probe is now a standard
StackTraceTest scenario in WasmBasicTestApp, uses TestOutput.WriteLine, and the
theory uses the coreclr test category.

The expanded theory covers CLI and direct-MSBuild publishing, no-build publishing,
explicit true/false, and build/publish/build. Against the preceding package, both
direct-MSBuild default cases failed because source lines remained enabled; the
other six cases passed.

The source-built SDK package passed with zero warnings/errors:

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\review-pack.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:EnableHotReloadInRuntimeConfigDevFile=false .\src\mono\nuget\Microsoft.NET.Sdk.WebAssembly.Pack\Microsoft.NET.Sdk.WebAssembly.Pack.pkgproj

Final browser validation:

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\review-green.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:TestUsingWorkloads=false /p:SdkVersionForWorkloadTesting=12.0.100-alpha.1.26528.120 /p:InstallWorkloadForTesting=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:InstallChromeForTests=false /p:XUnitMethodName=Wasm.Build.Tests.DebugLevelTests.StackTraceLineNumbersBuildPublishBuild /t:Test .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj

Passed in Chrome: 8 passed, 0 failed, 0 skipped.

.\dotnet.cmd build -bl:artifacts\tmp\trimmed-closure\review-nested-green.binlog /p:TargetOS=browser /p:TargetArchitecture=wasm /p:RuntimeFlavor=CoreCLR /p:Configuration=Debug /p:TestUsingWorkloads=true /p:SdkVersionForWorkloadTesting=12.0.100-alpha.1.26528.120 /p:InstallWorkloadForTesting=false /p:EnableHotReloadInRuntimeConfigDevFile=false /p:InstallChromeForTests=false /p:XUnitMethodName=Wasm.Build.Tests.LazyLoadingTests.FailOnMissingLazyAssembly /t:Test .\src\mono\wasm\Wasm.Build.Tests\Wasm.Build.Tests.csproj

Passed in Chrome: 1 passed, 0 failed, 0 skipped. Packaged target bytes match the
source; git diff --check passed.

Resolves #135222

Note

This PR was generated with assistance from GitHub Copilot.

Preserve development-build defaults and explicit source-location opt-in.
Resolve runtime feature configuration before trimming no-build publishes,
and verify build-publish-build behavior with browser regression tests.

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

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

@pavelsavara pavelsavara added arch-wasm WebAssembly architecture os-browser Browser variant of arch-wasm labels Nov 4, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag
See info in area-owners.md if you want to be subscribed.

Resolve WebAssembly configuration before trimming only in the outer publish.
Initializing it in native-only nested publishes generates an incomplete boot
manifest and completion stamp before the managed assemblies are staged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@pavelsavara pavelsavara added this to the 12.0.0 milestone Nov 6, 2026
@pavelsavara
pavelsavara marked this pull request as ready for review November 6, 2026 09:30
Set the default in the guarded publish target when the CLI publishing flag
is absent. Cover direct MSBuild publishing and move the stack trace probe
into the shared test app with its standard output helper and runtime category.

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

Copy link
Copy Markdown
Member Author

/ba-g known windows infra

@pavelsavara
pavelsavara merged commit a4106c7 into dotnet:main Nov 6, 2026
48 of 50 checks passed
@pavelsavara
pavelsavara deleted the browser-coreclr-trimmed-closure branch November 6, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-wasm WebAssembly architecture area-Diagnostics-coreclr os-browser Browser variant of arch-wasm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[browser][coreclr] Investigate five additional assemblies retained in trimmed Blazor WebAssembly publishes

2 participants