Skip to content

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

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

[Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed#130589
AaronRobinsonMSFT with Copilot wants to merge 7 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 — ILLink TypeMapHandler.cs

  • TypeMapAssemblyTarget attributes are now only marked when their target assembly is also marked (has surviving entries or is otherwise kept).
  • Added _pendingAssemblyTargetsByAssembly: when a group is seen but the target assembly is not yet marked, the attribute is deferred here rather than immediately marked.
  • TriggerPendingAssemblyTargets() is internal and called only from MarkStep.MarkAssembly whenever an assembly is first marked — ensuring deferred attributes are flushed regardless of assembly visitation order.
  • A comment notes that this is a slight over-approximation: ideally the attribute would only be kept when the target assembly has a surviving TypeMapAttribute, but the added complexity is not justified for a narrow case.
  • 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 — MarkStep.cs

  • MarkAssembly calls _typeMapHandler.TriggerPendingAssemblyTargets(assembly) to flush any pending TypeMapAssemblyTarget attributes for the assembly being marked, regardless of the order in which TypeMap entries are visited.

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 via [RemovedAttributeInAssembly] and [RemovedAssembly] that the TypeMapAssemblyTarget attribute and the conditional assembly are both removed from the linked output.

…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.

@jkotas jkotas removed the area-AssemblyLoader-coreclr only use for closed issues label 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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates ILLink’s type map handling to avoid keeping TypeMapAssemblyTargetAttribute<TGroup> metadata that can reference assemblies which end up not being present after trimming, and adds a new regression test case in the linker test suite.

Changes:

  • Update TypeMapHandler to defer marking TypeMapAssemblyTarget attributes until the referenced target assembly is known to be kept (or drop the attribute if the assembly can’t be resolved in linker input).
  • Add a new linker test plus two dependency assemblies to cover the “all TypeMap entries trimmed away” scenario.
Show a summary per file
File Description
src/tools/illink/src/linker/Linker/TypeMapHandler.cs Adds deferral/flush mechanism for TypeMapAssemblyTarget marking, keyed by resolved target assembly.
src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/TypeMapAssemblyTargetRemovedWhenAllEntriesTrimmed.cs New test case intended to validate removal of a dangling TypeMapAssemblyTarget attribute.
src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/TypeMapAllConditionalGroupDep.cs New dependency assembly containing a group marker type for the test.
src/tools/illink/test/Mono.Linker.Tests.Cases/Reflection/Dependencies/TypeMapAllConditionalEntriesDep.cs New dependency assembly containing only conditional TypeMap entries.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 1

Comment thread src/tools/illink/src/linker/Linker/TypeMapHandler.cs
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 13, 2026 16:47
@jtschuster jtschuster temporarily deployed to copilot-pat-pool July 13, 2026 16:47 — with GitHub Actions Inactive
@jtschuster jtschuster temporarily deployed to copilot-pat-pool July 13, 2026 16:47 — with GitHub Actions Inactive

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment thread src/tools/illink/src/linker/Linker/TypeMapHandler.cs
Comment on lines +138 to +142
if (_context.Annotations.IsMarked(targetAssembly))
{
// Target assembly is already in the output because it has surviving TypeMap entries.
MarkTypeMapAttribute(entry, new DependencyInfo(DependencyKind.TypeMapAssemblyTarget, callingMethod));
}
… MarkStep

Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 13, 2026 17:08

Copilot AI commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

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

Updated. The current PR description now reflects the actual changes:

Fix — ILLink TypeMapHandler.cs (only change in this PR)

  • TypeMapAssemblyTarget attributes are now only marked when their target assembly is also marked (has surviving TypeMap/TypeMapAssociation entries or is otherwise kept).
  • _pendingAssemblyTargetsByAssembly: when a group is seen but the target assembly has no surviving entries yet, the attribute is deferred here rather than immediately marked.
  • TriggerPendingAssemblyTargets() is now internal and called from two sites to avoid ordering-dependent behavior: (1) from MarkTypeMapAttribute whenever a TypeMap/TypeMapAssociation entry is marked, and (2) from MarkStep.MarkAssembly whenever an assembly is first marked, ensuring deferred attributes are flushed regardless of visitation order.
  • If the target assembly can't be resolved in the linker input at all, the attribute is silently dropped.

Test

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

(No CoreCLR changes — the previous assemblynative.cpp change was reverted.)

Copilot AI requested a review from jtschuster July 13, 2026 17:09
Comment thread src/tools/illink/src/linker/Linker/TypeMapHandler.cs Outdated
…ttribute, update comment

Co-authored-by: jtschuster <36744439+jtschuster@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot July 13, 2026 18:28
Copilot AI requested a review from jtschuster July 13, 2026 18:29
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

5 participants