[Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed#130589
[Trimming] Fix startup crash when TypeMapAssemblyTarget attribute survives but target assembly is fully trimmed#130589AaronRobinsonMSFT with Copilot wants to merge 4 commits into
Conversation
…no surviving entries Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
….cs and assemblynative.cpp Co-authored-by: AaronRobinsonMSFT <30635565+AaronRobinsonMSFT@users.noreply.github.com>
|
@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>
Reverted all changes to
Reverted all changes to |
|
@copilot Please update the PR description to reflect the current changes in this PR. |
|
Tagging subscribers to this area: @agocke, @dotnet/illink |
In trimmed CoreCLR apps, a
TypeMapAssemblyTargetattribute 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,TypeMapLazyDictionaryunconditionally callsAssembly.Loadfor every surviving attribute, crashing withFileNotFoundException.Changes
Fix (a) — ILLink
TypeMapHandler.cs(primary fix)TypeMapAssemblyTargetattributes are now only marked when their target assembly is also marked (has at least one surviving TypeMap/TypeMapAssociation entry)._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(): called fromMarkTypeMapAttributewhenever a TypeMap/TypeMapAssociation entry is marked, flushing any deferred assembly-target attributes for that assembly.Fix (c) — Defense-in-depth
assemblynative.cppAssemblyTargetProcessor::Processnow callsspec.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
TypeMapAssemblyTargetRemovedWhenAllEntriesTrimmedwith two dependency assemblies: a shared group-type assembly, and aconditional.dllwith only conditional TypeMap entries (trim target never marked). Verifies theTypeMapAssemblyTargetattribute is removed from the main assembly after linking.