Repository navigation
[Build] Avoid the intermittent ILLink native-PDB crash when trimming SamplePagesExtension - #50917
Merged
Merged
Conversation
CI intermittently fails the main build while MSIX packaging trims the CmdPal sample extension: ILLink dies with an access violation in Mono.Cecil.Pdb.ISymUnmanagedWriter2.Close() (MSB6006: "dotnet.exe" exited with code 57005, then NETSDK1144). Release builds use Windows PDBs (DebugType=pdbonly), so ILLink rewrites the sample's and the Toolkit's PDBs through the native DiaSymReader COM writer. Setting TrimmerRemoveSymbols=true for the sample's Release trim keeps ILLink away from that writer. The trimmed code is unchanged; only the PDBs next to the trimmed output are dropped. The untrimmed build output keeps its PDB, and Debug builds don't trim. Backlog item BUILD-8 (PowerToys speed & quality backlog). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
ð§ PR intakeVisual evidence: Not needed â The changed files do not indicate a visible UI change. No visual evidence is expected. Recommendation
â Ready for reviewThis PR passed the automated intake checks and is ready for maintainer review. Automated PR intake; PowerToys maintainers make final decisions. |
JiÅÃ PolÃĄÅĄek (jiripolasek)
approved these changes
Sep 30, 2026
11 tasks
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 of the Pull Request
Fixes an intermittent PowerToys CI failure. The main build sometimes fails while MSIX packaging trims the Command Palette sample extension (
SamplePagesExtension):The fix is one Release-only property in
SamplePagesExtension.csproj:TrimmerRemoveSymbols=true. With it, ILLink doesn't rewrite debug symbols for this trim, so it never loads the native Windows PDB writer that crashes. The trimmed code doesn't change. The only difference is that the trimmed output has no PDBs.This is backlog item BUILD-8 of the PowerToys speed & quality backlog.
PR Checklist
Detailed Description of the Pull Request / Additional comments
Root cause
In the failing jobs, ILLink (
dotnet.exe, Microsoft.NET.ILLink.Tasks 10.0.11) dies in its output step while it writes symbols:SamplePagesExtension.csprojsetsGenerateAppxPackageOnBuild=true, and in Release it also setsPublishTrimmed=true. MSIX packaging during the solution build publishes the app withwin-$(Platform).pubxml, so_RunILLinktrims it. It's the only ILLink invocation in PR CI.TrimmerRemoveSymbolsdefaults tofalseunlessDebuggerSupport=false, so ILLink gets-band rewrites the PDB of every assembly it trims.src\Common.Dotnet.propssets ReleaseDebugType=pdbonly. That covers the sample and alsoMicrosoft.CommandPalette.Extensions.Toolkit, aProjectReferencethat's trimmed in the same ILLink run. Mono.Cecil can only write Windows PDBs through the native COMISymUnmanagedWriter(the .NET Framework's DiaSymReader). The access violation happens inside that nativeClose(), so we can't fix it in this repo. We can only stop using that writer.Affected builds and frequency
I used the public Azure DevOps REST API to scan every build still retained for the PowerToys CI pipeline (shine-oss/PowerToys, 2026-08-31 to 2026-09-30), including earlier attempts of retried jobs. Each failure below has the same stack, in the SamplePagesExtension
_RunILLinkstep:main(batched CI)Fix and why
DebugType=portablefor the sample (preferred, because it would keep symbols)Microsoft.CommandPalette.Extensions.Toolkit.pdbas a Windows PDB (verified locally, see Validation), so the native writer is still used. Switching the Toolkit to portable PDBs would change the symbol format of a shipping CmdPal/SDK binary, which is out of scope here.TrimmerRemoveSymbols=true(chosen)-b, so it doesn't read or write any symbols and never loads the native writer. The trimmed assemblies are otherwise identical.Effects of (b):
_GenerateAppxSymbolPackagewhen the payload has no PDBs, so the sample no longer gets an.appxsym(confirmed in PR CI). The sample isn't shipped to users (it's not in the installer).<Platform>\Release\WinUI3Apps\CmdPalExtensions\SamplePagesExtension\SamplePagesExtension.pdb). That's the PDB CI's "Stage Unique Symbols" step already picks up.DebugTypeisn't touched.Other projects checked
illink.dllinvocation is SamplePagesExtension, once per platform, and nothing runs ILC.Microsoft.CmdPal.Ext.PowerToys,Microsoft.CommandPalette.Extensions.Toolkit,UITestAutomation, PowerOCR, PowerDisplay (+CLI), and PowerAccent.UI setPublishAotorPublishTrimmed. PR CI only builds them and never publishes them, so neither ILLink nor ILC runs. CmdPal UI uses Native AOT only in the release pipeline (EnableCmdPalAOT=true). Native AOT trims with ILC, not ILLink/Cecil, so it doesn't use this writer. The release pipeline builds the same solution, so its SamplePagesExtension trim gets this fix too. No follow-ups needed.src\modules\cmdpal\ExtensionTemplate: Not built in CI (it's not inPowerToys.slnx, andverifyCommonProps.ps1skips it). It doesn't importCommon.Dotnet.propsor setDebugType, so it uses the SDK default portable PDBs. The Toolkit it gets from NuGet ships without a PDB, so a trimmed template publish only uses Cecil's managed portable-PDB writer. No template change needed.Validation Steps Performed
Local environment limits: The dev box is ARM64 with VS 18 and has no C++ toolset or Windows SDK, so there's no
MakeAppxand MSIX packaging can't run locally. I exercised ILLink with a Release|x64 publish that skips packaging:The hook is local only and isn't part of this PR. Restores were anonymous (
NUGET_PLUGIN_PATHS,NUGET_NETFX_PLUGIN_PATHS, andNUGET_NETCORE_PLUGIN_PATHSpointed at an empty folder), and no new packages were needed. Local ILLink is 10.0.12 (SDK 10.0.401); CI uses 10.0.11. To tell PDB formats apart, I checked the file header: a Windows PDB starts withMicrosoft C/C++ MSF 7.00and a portable PDB starts withBSJB.main): Publish exits 0. ILLink runs with-band writesSamplePagesExtension.pdbandMicrosoft.CommandPalette.Extensions.Toolkit.pdbas Windows PDBs, which means the native writer is used.SamplePagesExtension.pdbbecomes portable (BSJB), but ILLink still writesMicrosoft.CommandPalette.Extensions.Toolkit.pdbas a Windows PDB.IL2104warnings asmain(both already inWarningsNotAsErrors). The ILLink task getsRemoveSymbols=True, so there's no-b, and it returns_ILLinkExitCode=0without writing any PDBs. Compared with the "before" output, the trimmedSamplePagesExtension.dll(171 types, 743 methods, 251 fields) andMicrosoft.CommandPalette.Extensions.Toolkit.dll(399 types, 1850 methods, 530 fields) have the same metadata counts and code size. The only change is the missing CodeView debug-directory entry (the pointer to the PDB).dotnet msbuild -getPropertygivesTrimmerRemoveSymbols=truefor Release|x64 and Release|ARM64 and leaves it empty for Debug, wherePublishTrimmed=false.dotnetand 20 times with the emulated x64dotnet(closer to the x64 CI agents), before and after the fix.DOTNET_GCgen0size=0x20000. Every run wrote two Windows PDBs through the native writer.illink.dll -a "obj\x64\Release\SamplePagesExtension.dll"andobj\ARM64\..., ILLink 10.0.11) without-b. It has 253 arguments versus 254 in build 389905, which doesn't have this change, and the only one missing is-b.Fatal error,0xC0000005,57005, orNETSDK1144markers. The task had 0 errors and the same twoIL2104warnings as 389905.SamplePagesExtension_1.0.0.0_x64.msixandSamplePagesExtension_1.0.0.0_arm64.msix, and it skipped the sample's.appxsymas expected.SamplePagesExtension.pdb.