Skip to content

Partially revert PR #125326: revert ComActivator/LicenseInteropProxy changes#125706

Open
Copilot wants to merge 3 commits intomainfrom
copilot/fix-netclientlicense-test-failures
Open

Partially revert PR #125326: revert ComActivator/LicenseInteropProxy changes#125706
Copilot wants to merge 3 commits intomainfrom
copilot/fix-netclientlicense-test-failures

Conversation

Copy link
Contributor

Copilot AI commented Mar 18, 2026

main PR #125326

Description

PR #125326 converted LicenseInteropProxy call sites to use [UnmanagedCallersOnly] with raw managed object pointers (object*, Type*, LicenseInteropProxy*). Under GC stress, the collector can move objects between pin points, invalidating those pointers and causing heap corruption (exit code -1073740940 / STATUS_HEAP_CORRUPTION).

Reverts only the LicenseInteropProxy-related changes; other conversions in that PR are left intact.

  • ComActivator.cs: Restore public static object Create() returning a new LicenseInteropProxy; remove unsafe [UnmanagedCallersOnly] static wrappers for GetCurrentContextInfo and SaveKeyInCurrentContext
  • corelib.h: Restore original method binding signatures — SM_RetObj, IM_RuntimeTypeHandle_RefBool_RefIntPtr_RetVoid, IM_IntPtr_RetVoid
  • runtimecallablewrapper.cpp: Replace UnmanagedCallersOnlyCaller with GC-safe MethodDescCallSite + ARG_SLOT for all three license interop call sites
  • metasig.h: Remove the two PtrLicenseInteropProxy_* metasig entries no longer referenced

Customer Impact

NETClientLicense test crashes under all GC stress modes on Windows x86 and x64. Any application using COM licensed object activation via IClassFactory2 is at risk of heap corruption at runtime.

Regression

Yes — introduced by PR #125326.

Testing

Covered by the existing Interop/COM/NETClients/Licensing/NETClientLicense test, which consistently fails under gcstress0xc_* configurations without this fix.

Risk

Low. This is a targeted revert to well-understood, previously-working code paths. The MethodDescCallSite pattern is the established GC-safe mechanism for calling managed methods from native code; no new logic is introduced.

Package authoring no longer needed in .NET 9

IMPORTANT: Starting with .NET 9, you no longer need to edit a NuGet package's csproj to enable building and bump the version.
Keep in mind that we still need package authoring in .NET 8 and older versions.

Original prompt

This section details on the original issue you should resolve

<issue_title>Test failure: Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd</issue_title>
<issue_description>Failed in: runtime-coreclr gcstress-extra 20260314.1

Failed tests:

coreclr windows x86 Checked gcstress0xc_disabler2r @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x86 Checked gcstress0xc_disabler2r_jitstress2 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x86 Checked gcstress0xc_jitstress1 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x86 Checked gcstress0xc_jitstress2 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x86 Checked gcstress0xc_disabler2r_heapverify1 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x86 Checked gcstress0xc_tailcallstress @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x64 Checked gcstress0xc_disabler2r_heapverify1 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x64 Checked gcstress0xc_tailcallstress @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x64 Checked gcstress0xc_jitstress2 @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd
coreclr windows x64 Checked gcstress0xc_disabler2r @ Windows.10.Amd64.Open
- Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd

Error message:


Return code:      1
Raw output file:      C:hwAC54096BwBFF409D3uploadsCOMNETClientsLicensingNETClientLicenseoutput.txt
Raw output:
BEGIN EXECUTION
 "C:hwAC54096Bpcorerun.exe" -p "System.Reflection.Metadata.MetadataUpdater.IsSupported=false" -p "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization=true"  NETClientLicense.dll 
Calling ActivateLicensedObject...
Calling ActivateUnderDesigntimeContext...
Calling ActivateUnderRuntimeContext...
Expected: 100
Actual: -1073740940
END EXECUTION - FAILED
FAILED
Test Harness Exitcode is : 1
To run the test:
Set up CORE_ROOT and run.
> C:hwAC54096BwBFF409D3eInteropInterop../COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd

Stack trace:

   at Xunit.Assert.True(Nullable`1 condition, String userMessage) in /_/src/arcade/src/Microsoft.DotNet.XUnitAssert/src/BooleanAsserts.cs:line 141
   at TestLibrary.OutOfProcessTest.RunOutOfProcessTest(String assemblyPath, String testPathPrefix)
   at Program.<<Main>$>g__TestExecutor260|0_261(StreamWriter tempLogSw, StreamWriter statsCsvSw, <>c__DisplayClass0_0&)

</issue_description>

<agent_instructions>Create PR that partially reverts #125326 - revert all changes related to ComActivator</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@jkoritzinsky cc @am11 likely due to your COM UCO changes? @JulieLeeMSFT **Failed in** - [runtime-coreclr gcstress0x3-gcstress0xc 20260315.1](https://dev.azure.com/dnceng-public/public/_build/results?buildId=1336206)

Console Log: Console Log

Analysis:
NETClientLicense.cmd consistently fails under gcstress modes on Windows. The test crashes with exit code -1073740940 (STATUS_HEAP_CORRUPTION) during COM licensing API calls.</comment_new>
<comment_new>@jkotas
Likely introduced by #125326</comment_new>


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

…changes

The [UnmanagedCallersOnly] approach for LicenseInteropProxy was causing heap corruption (STATUS_HEAP_CORRUPTION) under GC stress scenarios. Revert to the original MethodDescCallSite-based approach.

Changes:
- ComActivator.cs: Restore public static object Create() and remove the unsafe [UnmanagedCallersOnly] static methods for GetCurrentContextInfo and SaveKeyInCurrentContext
- corelib.h: Restore original LICENSE_INTEROP_PROXY method signatures (SM_RetObj, IM_RuntimeTypeHandle_RefBool_RefIntPtr_RetVoid, IM_IntPtr_RetVoid)
- runtimecallablewrapper.cpp: Restore MethodDescCallSite calls for license interop
- metasig.h: Remove added PtrLicenseInteropProxy_* metasig definitions

Co-authored-by: jkotas <6668460+jkotas@users.noreply.github.com>
Copilot AI changed the title [WIP] [runtime-coreclr] Fix test failure in NETClientLicense Partially revert PR #125326: revert ComActivator/LicenseInteropProxy changes Mar 18, 2026
Copilot AI requested a review from jkotas March 18, 2026 03:24
@dotnet-policy-service
Copy link
Contributor

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

@jkotas
Copy link
Member

jkotas commented Mar 18, 2026

/azp run runtime-coreclr gcstress-extra

@jkotas jkotas marked this pull request as ready for review March 18, 2026 03:43
Copilot AI review requested due to automatic review settings March 18, 2026 03:43
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
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

Partially reverts PR #125326 for COM licensing activation by restoring GC-safe managed-call patterns for LicenseInteropProxy, addressing heap corruption under GC stress.

Changes:

  • Restore LicenseInteropProxy method bindings/signatures and remove pointer-based metasigs.
  • Switch native license interop call sites from UnmanagedCallersOnlyCaller to MethodDescCallSite + ARG_SLOT.
  • Revert CoreLib LicenseInteropProxy back to a managed Create() factory and remove unsafe [UnmanagedCallersOnly] wrappers.

Reviewed changes

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

File Description
src/coreclr/vm/runtimecallablewrapper.cpp Replaces UCO pointer calls with MethodDescCallSite invocations for license interop.
src/coreclr/vm/metasig.h Removes metasig entries for pointer-based LicenseInteropProxy UCO signatures.
src/coreclr/vm/corelib.h Restores original method binding signatures for LicenseInteropProxy.
src/coreclr/System.Private.CoreLib/src/Internal/Runtime/InteropServices/ComActivator.cs Restores managed Create() and removes unsafe UCO wrappers for licensing methods.

Comment on lines 142 to +153
gc.pType = rth.GetManagedClassObject();

// Query the current licensing context
UnmanagedCallersOnlyCaller getCurrentContextInfo(METHOD__LICENSE_INTEROP_PROXY__GETCURRENTCONTEXTINFO);
MethodDescCallSite getCurrentContextInfo(METHOD__LICENSE_INTEROP_PROXY__GETCURRENTCONTEXTINFO, &gc.pProxy);
CLR_BOOL fDesignTime = FALSE;
INT_PTR bstrKeyRaw = NULL;
getCurrentContextInfo.InvokeThrowing(&gc.pProxy, &gc.pType, &fDesignTime, &bstrKeyRaw);
bstrKey = (BSTR)bstrKeyRaw;
ARG_SLOT args[4];
args[0] = ObjToArgSlot(gc.pProxy);
args[1] = ObjToArgSlot(gc.pType);
args[2] = (ARG_SLOT)&fDesignTime;
args[3] = (ARG_SLOT)(BSTR*)&bstrKey;

getCurrentContextInfo.Call(args);
Comment on lines +147 to +153
ARG_SLOT args[4];
args[0] = ObjToArgSlot(gc.pProxy);
args[1] = ObjToArgSlot(gc.pType);
args[2] = (ARG_SLOT)&fDesignTime;
args[3] = (ARG_SLOT)(BSTR*)&bstrKey;

getCurrentContextInfo.Call(args);
Comment on lines +186 to +188
args[0] = ObjToArgSlot(gc.pProxy);
args[1] = (ARG_SLOT)(BSTR)bstrKey;
saveKeyInCurrentContext.Call(args);
@jkotas
Copy link
Member

jkotas commented Mar 18, 2026

/azp run runtime-coreclr gcstress-extra

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

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.

Test failure: Interop/COM/NETClients/Licensing/NETClientLicense/NETClientLicense.cmd

3 participants