Fix R2R TypeMap fallback for unresolved assembly targets#126123
Fix R2R TypeMap fallback for unresolved assembly targets#126123
Conversation
…assemblies When CrossGen2 encounters a TypeMapAssemblyTarget pointing to an assembly that fails to resolve (e.g. "DoesNotExist"), it catches the exception and sets exception stubs, but AddTargetModule is never called, leaving TargetModules empty. Previously, TypeMapAssemblyTargetsNode still emitted an entry with count=0 for these groups. At runtime, HasTypeMapAssemblyTargets would find this entry, return true with count=0, setting hasPrecachedTargets to true. This prevented the runtime from falling back to attribute processing, which is where the FileNotFoundException would be thrown. The fix skips emitting TypeMapAssemblyTargets entries for groups with no resolved target modules. This makes HasTypeMapAssemblyTargets return false for these groups, causing the runtime to correctly fall back to attribute processing and throw FileNotFoundException. Fixes #125941 Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f1301246-c321-4665-a75e-28efe25a1e5e Co-authored-by: stephentoub <2642209+stephentoub@users.noreply.github.com>
|
@copilot why did you not implement the option 1 as mentioned in the analysis on the issue? |
…oxy maps aren't pre-cached When CrossGen2 fails to resolve an assembly target (e.g. "DoesNotExist"), it emits a TypeMapAssemblyTargets entry with count=0 but marks the external/proxy type maps as invalid (state=0). Previously the runtime only re-processed assembly target attributes when hasPrecachedTargets was false. With this change, the runtime also re-processes assembly target attributes when the external or proxy type maps weren't pre-cached. This is the more robust fix (Option 1 from the analysis) that also handles the mixed case where some assembly targets resolve and some don't. The AssemblyTargetProcessor already deduplicates, so re-processing is safe. Co-authored-by: mangod9 <61718172+mangod9@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/35d99139-2cbe-4b13-a96f-f26d5e5bd8d2
Implemented Option 1 (the runtime fix) in |
src/coreclr/vm/assemblynative.cpp
Outdated
| if (!hasPrecachedTargets | ||
| || (newExternalTypeEntry != nullptr && !hasPrecachedExternal) | ||
| || (newProxyTypeEntry != nullptr && !hasPrecachedProxy)) |
There was a problem hiding this comment.
This condition is the same as the condition on 1772. We can remove this and unconditionally run this block (the comment is good though).
There was a problem hiding this comment.
@copilot can you make the update as requested here ?
There was a problem hiding this comment.
Removed the redundant inner condition in bd14f210. The ProcessTypeMapAttribute call is now unconditional within the outer if block, with the explanatory comment preserved.
…allback Co-authored-by: mangod9 <61718172+mangod9@users.noreply.github.com> Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/e777151e-cbef-474b-8fdd-8c7832a8b797
Description
Interop/TypeMap/TypeMapApp/TypeMapApp.cmdfails deterministically in all R2R configurations because of a disconnect between CrossGen2 and the runtime when aTypeMapAssemblyTargetreferences an unresolvable assembly (e.g.,"DoesNotExist").When CrossGen2 fails to resolve an assembly target, it catches the exception and sets error stubs on the external/proxy type maps (state=0), but
AddTargetModuleis never called, leavingTargetModulesempty. CrossGen2 then emits aTypeMapAssemblyTargetsentry with count=0 while marking the external/proxy maps as invalid. At runtime,HasTypeMapAssemblyTargetsfinds this empty entry → returnstruewith count=0 → setshasPrecachedTargets = true→ skips fallback to attribute processing →FileNotFoundExceptionis never thrown.Primary fix (runtime —
assemblynative.cpp): The outerifblock already enters when any of the three precached maps (targets, external, proxy) are missing. The assembly target attribute re-processing is now unconditional within that block, since the outer condition already guarantees at least one map needs fallback. TheAssemblyTargetProcessoralready deduplicates via_toProcess/_processedSHash collections, so re-processing is always safe.Complementary cleanup (CrossGen2 —
TypeMapAssemblyTargetsNode.cs): Skip emittingTypeMapAssemblyTargetsentries for groups with zero resolved target modules, avoiding useless count=0 entries in the R2R image.⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.