Skip to content

Always add ManagedDataDescriptorProvider to compilationRoots#127643

Open
MichalStrehovsky wants to merge 1 commit intomainfrom
MichalStrehovsky-patch-1
Open

Always add ManagedDataDescriptorProvider to compilationRoots#127643
MichalStrehovsky wants to merge 1 commit intomainfrom
MichalStrehovsky-patch-1

Conversation

@MichalStrehovsky
Copy link
Copy Markdown
Member

This just causes error LNK2001: unresolved external symbol DotNetManagedContractDescriptor

This just causes `error LNK2001: unresolved external symbol DotNetManagedContractDescriptor`
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 changes the NativeAOT ILCompiler driver to always add ManagedDataDescriptorProvider to compilationRoots, instead of only doing so when --debug (EnableDebugInfo) is enabled.

Changes:

  • Remove the --debug conditional and unconditionally root ManagedDataDescriptorProvider.

Comment thread src/coreclr/tools/aot/ILCompiler/Program.cs
Comment thread src/coreclr/tools/aot/ILCompiler/Program.cs
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🤖 Copilot Code Review — PR #127643

Note

This review was generated by GitHub Copilot.

Holistic Assessment

Motivation: The PR fixes a linker error (LNK2001: unresolved external symbol DotNetManagedContractDescriptor) that occurs when NativeAOT compilation is run without debug info enabled. The native runtime unconditionally references this symbol via extern "C", so it must always be emitted.

Approach: Removing the if (Get(_command.EnableDebugInfo)) guard so ManagedDataDescriptorProvider is always added to compilation roots is the correct and minimal fix. The symbol is required by the native side regardless of debug info settings.

Summary: ✅ LGTM. The fix is correct, minimal, and well-motivated. The DotNetManagedContractDescriptor symbol is unconditionally referenced in src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.h (line 29: extern "C" ContractDescriptor DotNetManagedContractDescriptor;), so the managed compiler must always emit it. Gating it behind EnableDebugInfo was a bug.


Detailed Findings

✅ Correctness — Fix is sound

Verified that:

  • src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.h declares extern "C" ContractDescriptor DotNetManagedContractDescriptor unconditionally and takes its address into g_pManagedContractDescriptor.
  • The ManagedDataDescriptorNode (emitting the symbol) has no dependency on debug info — it scans [DataContract]-annotated types from MetadataManager.GetTypesWithEETypes().
  • No other compilation path (e.g., library mode) references ManagedDataDescriptorProvider, so this is the only site that needs the fix.

✅ No side effects — Safe to always emit

The ManagedDataDescriptorNode emits a read-only data blob describing managed type layouts for cDAC. When no [DataContract] types exist, the node emits a minimal/empty descriptor. There is no meaningful size or performance cost to always including it, and it avoids the linker failure.

💡 Observation — Original guard was likely copy-paste

The debug info guard may have been added when ManagedDataDescriptorProvider was originally introduced, perhaps conflating "diagnostic data" with "debug info." The cDAC contract descriptor is not debug info — it's structural metadata the runtime always needs.

Generated by Code Review for issue #127643 ·

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants