Skip to content

Fix ComWrappers ICustomQueryInterface exception handling - #132716

Merged
jkoritzinsky merged 1 commit into
mainfrom
dev/jkoritzinsky/turbo-bassoon
Aug 24, 2026
Merged

jkoritzinsky merged 1 commit into
mainfrom
dev/jkoritzinsky/turbo-bassoon

Conversation

@jkoritzinsky

Copy link
Copy Markdown
Member

Description

When a user's ICustomQueryInterface.GetInterface implementation throws an exception, the native QueryInterface path in comwrappers.cpp asserts and crashes the process (Assertion failed: ((*ppvObject != nullptr))).

The root cause is in the [UnmanagedCallersOnly] CallICustomQueryInterface wrapper in ComWrappers.CoreCLR.cs. It catches the exception but returns default (0) from the catch block. 0 happens to be the numeric value of TryInvokeICustomQueryInterfaceResult.Handled, so native code is told the call succeeded and that *ppvObject was set - but it's still null, tripping the assert.

The fix returns -1 (TryInvokeICustomQueryInterfaceResult.FailedToInvoke) from the catch block instead, so native code correctly treats the call as failed and falls back rather than asserting on a null pointer.

Fixes the CI failure reported in #132677, reproduced locally by Regressions/coreclr/GitHub_117393/test117393.

Verification

  • Built checked clr+libs, built test117393, generated Core_Root - test passes with the fix applied.
  • Reverted the fix, rebuilt System.Private.CoreLib only, reran the test - reproduced the exact native assertion crash from the issue.
  • Reapplied the fix, rebuilt, reran - test passes again.

Closes #132677

Note

This description was generated with AI assistance.

When the user's ICustomQueryInterface.GetInterface implementation throws,
the UnmanagedCallersOnly wrapper caught the exception but returned
default (0), which is TryInvokeICustomQueryInterfaceResult.Handled.
This told native code the call succeeded with *ppvObject set, but it
was still null, tripping the QueryInterface assertion in comwrappers.cpp
and crashing the process.

Return -1 (FailedToInvoke) instead so native code falls back correctly.

Fixes the assertion failure in Regressions/coreclr/GitHub_117393/test117393
(#132677).

Co-authored-by: Copilot <[email protected]>
Copilot AI lite review requested due to automatic review settings August 24, 2026 20:10
@github-actions github-actions Bot added the area-ExceptionHandling-coreclr only use for closed issues label Aug 24, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@jkoritzinsky jkoritzinsky added area-Interop-coreclr and removed area-ExceptionHandling-coreclr only use for closed issues labels Aug 24, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes incorrect return value from the [UnmanagedCallersOnly] ComWrappers.CallICustomQueryInterface wrapper when ICustomQueryInterface.GetInterface throws, ensuring the native COM QueryInterface path treats the call as failed-to-invoke instead of “handled”.

Changes:

  • In the exception path, return -1 (maps to TryInvokeICustomQueryInterfaceResult.FailedToInvoke) instead of default/0 (maps to Handled).
  • Add an inline comment clarifying the intended enum mapping for the -1 return value.

@AaronRobinsonMSFT AaronRobinsonMSFT left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Should we also backport to .NET 11?

@jkoritzinsky
jkoritzinsky enabled auto-merge (squash) August 24, 2026 20:23
@jkoritzinsky
jkoritzinsky merged commit 6d57017 into main Aug 24, 2026
118 checks passed
@jkoritzinsky
jkoritzinsky deleted the dev/jkoritzinsky/turbo-bassoon branch August 24, 2026 23:05
@github-project-automation github-project-automation Bot moved this to Done in AppModel Aug 24, 2026
@jkoritzinsky

Copy link
Copy Markdown
Member Author

/backport to release/11.0

@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Aug 25, 2026
artl93 pushed a commit that referenced this pull request Sep 5, 2026
…ng (#132725)

Backport of #132716 to release/11.0

/cc @jkoritzinsky

## Customer Impact

- [ ] Customer reported
- [X] Found internally

User gets a null object from a `QueryInterface` against a .NET object
that implements `ICustomQueryInterface` exposed to COM via ComWrappers
that causes the `ICustomQueryInterface` implementation to throw an
exception

## Regression

- [X] Yes
- [ ] No

Regressed in #125697

## Testing

Caught in outerloop testing

## Risk

Low. Targeted scenario and we have testing validation.

**IMPORTANT**: If this backport is for a servicing release, please
verify that:

- For .NET 8 and .NET 9: The PR target branch is `release/X.0-staging`,
not `release/X.0`.
- For .NET 10+: The PR target branch is `release/X.0` (no `-staging`
suffix).

## 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.

Co-authored-by: Jeremy Koritzinsky <[email protected]>
Co-authored-by: Jeremy Koritzinsky <[email protected]>
Co-authored-by: Copilot <[email protected]>
@github-actions github-actions Bot locked and limited conversation to collaborators Sep 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[ci-scan] Test failure: Regressions/coreclr/GitHub_117393/test117393 — comwrappers.cpp QueryInterface assertion

3 participants