Skip to content

Conversation

AndyAyersMS
Copy link
Member

C++/CLI appears to leave the CORINFO_EH_CLAUSE ClassToken/FilterOffset union set to some nonzero value for fault/filter clauses. The JIT currently just passes this value along to the runtime.

If a method with such a nonzero field is inlined into a dynamic method, this trips up a check in the runtime where a nonzero entry for such a field is interpreted as a class handle, even for fault/filter clauses where it should be ignored.

Tolerate this by zeroing the field in the JIT.

Note this could not have happened in pre .NET10 as methods with EH could not be inlined, so a dynamic method would never see such an EH clause, and in non-dynamic methods this field is ignored for faults and filters.

Fixes #118837.

C++/CLI appears to leave the CORINFO_EH_CLAUSE ClassToken/FilterOffset union
set to some nonzero value for fault/filter clauses. The JIT currently just
passes this value along to the runtime.

If a method with such a nonzero field is inlined into a dynamic method, this
trips up a check in the runtime where a nonzero entry for such a field is
interpreted as a class handle, even for fault/filter clauses where it should
be ignored.

Tolerate this by zeroing the field in the JIT.

Note this could not have happened in pre .NET10 as methods
with EH could not be inlined, so a dynamic method would never see such
an EH clause, and in non-dynamic methods this field is ignored for
faults and filters.

Fixes #118837.
@Copilot Copilot AI review requested due to automatic review settings August 18, 2025 23:30
Copy link
Contributor

@Copilot 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 fixes an issue where C++/CLI generated code leaves nonzero values in the ClassToken/FilterOffset union field for fault/filter exception handling clauses. When such methods are inlined into dynamic methods in .NET 10+, the runtime incorrectly interprets these nonzero values as class handles, causing validation failures.

  • Adds explicit zeroing of the ebdTyp field for finally and fault exception handling clauses
  • Prevents runtime validation errors when C++/CLI methods with EH are inlined into dynamic methods
  • Addresses a new issue introduced in .NET 10 when method inlining with exception handling was enabled

@github-actions github-actions bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Aug 18, 2025
@AndyAyersMS
Copy link
Member Author

@jakobbotsch PTAL
cc @dotnet/jit-contrib

I could (and perhaps should) also fix this in the jit interface (to ignore the value), and/or get the C++/CLI output fixed.

We will want to propose this for a .NET 10 backport.

Also I haven't added a test case; if anyone can point me at the right way to have a dependent C++/CLI library I will do so (many JIT tests just check in IL instead, which I could also do).

@jkotas
Copy link
Member

jkotas commented Aug 19, 2025

this trips up a check in the runtime

I assume that it happened here: https://github.com/dotnet/runtime/blob/main/src/coreclr/vm/jitinterface.cpp#L12736-L12738 . We can change the condition to
(pEHClause->Flags & {COR_ILEXCEPTION_CLAUSE_FILTER | COR_ILEXCEPTION_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_FAULT) == 0

@jkotas
Copy link
Member

jkotas commented Aug 19, 2025

We can change the condition to

And also in CorInfoImpl.ReadyToRun.cs

@jkotas
Copy link
Member

jkotas commented Aug 19, 2025

many JIT tests just check in IL instead, which I could also do

I am not sure you can convince ilasm to leave bogus value in unused EHInfo fields.

If you wanted to deterministically exercise a situation with a bogus value in unused EHInfo fields, I think you would have to emit the binary using System.Reflection.Metadata. I do not think it is it worth it.

@jkotas jkotas added area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Aug 19, 2025
Copy link
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copy link
Member

@jakobbotsch jakobbotsch left a comment

Choose a reason for hiding this comment

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

Can we always zero out the entirety of compHndBBtab when we allocate/reallocate it?

@AndyAyersMS
Copy link
Member Author

/ba-g System.Security.Cryptography.Tests dead-lettered

@AndyAyersMS
Copy link
Member Author

Can we always zero out the entirety of compHndBBtab when we allocate/reallocate it?

Seems prudent. Let me add that.

@AndyAyersMS
Copy link
Member Author

AndyAyersMS commented Aug 19, 2025

Seeing unrelated failures in OSX host activation tests


[xUnit.net 00:02:30.00]       --- Resolving libhostpolicy.dylib version from deps json [/private/tmp/helix/working/B1FB09EB/w/C75E0A16/e/test_artifacts/iet2mkkp.fd2/App/App.deps.json]
[xUnit.net 00:02:30.00]       Dependency manifest /private/tmp/helix/working/B1FB09EB/w/C75E0A16/e/test_artifacts/iet2mkkp.fd2/App/App.deps.json does not contain an entry for runtime.osx-x64.Microsoft.NETCore.DotNetHostPolicy
[xUnit.net 00:02:30.00]       The expected libhostpolicy.dylib directory is [/private/tmp/helix/working/B1FB09EB/w/C75E0A16/e/test_artifacts/iet2mkkp.fd2/App/]
[xUnit.net 00:02:30.00]       Tracing enabled @ Tue Aug 19 19:01:40 2025 UTC
[xUnit.net 00:02:30.00]       Reading from host interface version: [0x16041101:248] to initialize policy version: [0x16041101:248]
[xUnit.net 00:02:30.00]       ' could not be formatted with string.Format
[xUnit.net 00:02:30.00]          at System.String.FormatHelper(IFormatProvider provider, String format, ReadOnlySpan`1 args)
...
[xUnit.net 00:02:30.01]            at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
  Failed Microsoft.DotNet.CoreSetup.Test.HostActivation.DependencyResolution.LocalPath.RuntimeAssemblies_SelfContained(useLocalPath: True) [28 s]
  Error Message:
   **WARNING** failure message 'Expected command to pass but it did not.

Opened #118904

@AndyAyersMS AndyAyersMS merged commit e517733 into main Aug 19, 2025
107 of 112 checks passed
@AndyAyersMS
Copy link
Member Author

/backport to release/10.0-rc1

Copy link
Contributor

Started backporting to release/10.0-rc1: https://github.com/dotnet/runtime/actions/runs/17081234351

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

InvalidProgramException while expression compilation with C++/CLI field
3 participants