Skip to content

[Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed#130589

Draft
AaronRobinsonMSFT with Copilot wants to merge 4 commits into
mainfrom
copilot/fix-startup-crash-trimming
Draft

[Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed#130589
AaronRobinsonMSFT with Copilot wants to merge 4 commits into
mainfrom
copilot/fix-startup-crash-trimming

Conversation

Copilot AI commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

In trimmed CoreCLR apps, a TypeMapAssemblyTarget attribute could survive trimming even when its named assembly was fully trimmed (all its TypeMap entries were conditional on trim targets that were never marked). At runtime, TypeMapLazyDictionary unconditionally calls Assembly.Load for every surviving attribute, crashing with FileNotFoundException.

Changes

Fix (a) — ILLink TypeMapHandler.cs (primary fix)

  • TypeMapAssemblyTarget attributes are now only marked when their target assembly is also marked (has at least one surviving TypeMap/TypeMapAssociation entry).
  • Added _pendingAssemblyTargetsByAssembly: when a group is seen but the target assembly has no surviving entries yet, the attribute is deferred here rather than immediately marked.
  • Added TriggerPendingAssemblyTargets(): called from MarkTypeMapAttribute whenever a TypeMap/TypeMapAssociation entry is marked, flushing any deferred assembly-target attributes for that assembly.
  • If the target assembly can't be resolved in the linker input at all, the attribute is silently dropped (Assembly.Load would fail anyway).

Fix (c) — Defense-in-depth assemblynative.cpp

  • AssemblyTargetProcessor::Process now calls spec.LoadAssembly(FILE_LOADED, /*fThrowOnFileNotFound=*/FALSE) and skips null results instead of throwing. Protects against dangling attributes reaching the runtime in edge cases or non-trimmed scenarios.

Test

  • New test TypeMapAssemblyTargetRemovedWhenAllEntriesTrimmed with two dependency assemblies: a shared group-type assembly, and a conditional.dll with only conditional TypeMap entries (trim target never marked). Verifies the TypeMapAssemblyTarget attribute is removed from the main assembly after linking.

…no surviving entries

Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 12, 2026 22:23
@dotnet-policy-service dotnet-policy-service Bot added the linkable-framework Issues associated with delivering a linker friendly framework label Jul 12, 2026
….cs and assemblynative.cpp

Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 12, 2026 22:27
Copilot AI changed the title [WIP] Fix startup crash caused by TypeMapAssemblyTarget attribute [Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed Jul 12, 2026
Copilot AI requested a review from AaronRobinsonMSFT July 12, 2026 22:28
Copilot AI temporarily deployed to copilot-pat-pool July 12, 2026 23:09 Inactive
Copilot AI temporarily deployed to copilot-pat-pool July 12, 2026 23:09 Inactive
@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

@copilot No changes should be done to CoreCLR itself. This is entirely a trimming issue. When the trimmer decides to remove a type based on the typemap reference algorithm, it should also remove the typemap attributes that reference it.

Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 12, 2026 23:15

Copilot AI commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

@copilot No changes should be done to CoreCLR itself. This is entirely a trimming issue. When the trimmer decides to remove a type based on the typemap reference algorithm, it should also remove the t...

Reverted all changes to assemblynative.cpp in commit $(git rev-parse --short HEAD). The fix is now purely in the ILLink trimmer (TypeMapHandler.cs): TypeMapAssemblyTarget attributes are only marked when their target assembly has at least one surviving TypeMap/TypeMapAssociation entry, so dangling attributes are removed at trim time rather than relying on any CoreCLR defense.

@copilot No changes should be done to CoreCLR itself. This is entirely a trimming issue. When the trimmer decides to remove a type based on the typemap reference algorithm, it should also remove the t...

Reverted all changes to assemblynative.cpp in commit 516910c2. The fix is now purely in the ILLink trimmer (TypeMapHandler.cs): TypeMapAssemblyTarget attributes are only marked when their target assembly has at least one surviving TypeMap/TypeMapAssociation entry, so dangling attributes are removed at trim time rather than relying on any CoreCLR defense.

Copilot AI temporarily deployed to copilot-pat-pool July 12, 2026 23:56 Inactive
Copilot AI temporarily deployed to copilot-pat-pool July 12, 2026 23:56 Inactive
@AaronRobinsonMSFT

Copy link
Copy Markdown
Member

@copilot Please update the PR description to reflect the current changes in this PR.

@jkotas jkotas added area-Tools-ILLink .NET linker development as well as trimming analyzers and removed area-AssemblyLoader-coreclr only use for closed issues labels Jul 13, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-Tools-ILLink .NET linker development as well as trimming analyzers linkable-framework Issues associated with delivering a linker friendly framework

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

[Trimming] Startup crash when TypeMapAssemblyTarget attribute kept but target assembly trimmed

3 participants