Skip to content

Deduplicate "all managed object wrappers" mapping - #133260

Merged
jkoritzinsky merged 1 commit into
mainfrom
jkoritzinsky-patch-1
Sep 5, 2026
Merged

Deduplicate "all managed object wrappers" mapping#133260
jkoritzinsky merged 1 commit into
mainfrom
jkoritzinsky-patch-1

Conversation

@jkoritzinsky

Copy link
Copy Markdown
Member

Prevent duplicate entries in the "all managed object wrappers" table.

Fixes#129191

For the case in #129191, there is always only one ComWrappers instance, so this collection will be length 1.

I chose to do a simple fix like this for the following reasons:

  1. This collection is read from the DAC and cDAC directly to support the !DumpObj command. Any significant changes to the structure (such as moving to a HashSet<ManagedObjectWrapperHolder>) would require very large changes to enable enumerating the structure from DAC or cDAC code, creating a higher risk change for backporting.
  2. In practice, objects are passed to unmanaged code via 1 ComWrappers instance in the vast majority of cases outside of our own tests. In the unlikely case it's passed via more than 1, it would be via 2, the CsWinRT ComWrappers instance and the StrategyBasedComWrappers default instance.
  3. I considered adding a parallel HashSet for deduplication. However, that felt like a very large memory cost for the common scenario (.NET object passed to native via only one ComWrappers instance) for a minor savings in a very unlikely scenario (many ComWrappers for the same .NET object).

Prevent duplicate entries in the "all managed object wrappers" table.
Fixes#129191
For the case in #129191, there is always only one ComWrappers instance, so this collection will be length 1.
I chose to do a simple fix like this for the following reasons:
1. This collection is read from the DAC and cDAC directly to support the `!DumpObj` command. Any significant changes to the structure (such as moving to a `HashSet<ManagedObjectWrapperHolder>`) would require very large changes to enable enumerating the structure from DAC or cDAC code, creating a higher risk change for backporting.
2. In practice, objects are passed to unmanaged code via 1 ComWrappers instance in the vast majority of cases outside of our own tests. In the unlikely case it's passed via more than 1, it would be via 2, the CsWinRT ComWrappers instance and the StrategyBasedComWrappers default instance.
3. I considered adding a parallel HashSet for deduplication. However, that felt like a very large memory cost for the common scenario (.NET object passed to native via only one ComWrappers instance) for a minor savings in a very unlikely scenario (many ComWrappers for the same .NET object).
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

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

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 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.

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

Copilot review overview

🟢 Approval recommended

The change is small, localized to diagnostics registration, and avoids unbounded list growth while keeping the existing DAC/cDAC-observable structure intact.

Review tier: Lite
Findings: None

What changed in this PR

Prevents duplicate ManagedObjectWrapperHolder entries from being recorded in the global “all managed object wrappers” ConditionalWeakTable, which is used by diagnostics tooling to enumerate managed object wrappers.

Changes:

  • Adds a guarded insert (Contains check) when registering a managed object wrapper for diagnostics, preventing repeated additions of the same ManagedObjectWrapperHolder to the per-object list.
FileDescription
src/​libraries/​System.Private.CoreLib/​src/​System/​Runtime/​InteropServices/​ComWrappers.csDeduplicates per-object wrapper registration in the diagnostics tracking table to avoid list growth from repeated registrations.

@jtschusterjtschuster 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.

LGTM

@jkoritzinsky

Copy link
Copy Markdown
MemberAuthor

/backport to release/10.0

@jkoritzinsky

Copy link
Copy Markdown
MemberAuthor

/backport to release/11.0

@dotnetdotnet deleted a comment from github-actionsBotSep 5, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

@github-actions

Copy link
Copy Markdown
Contributor

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

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

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Regression] COMWrapper Leak when targeting .NET 10 on a WinUI3 project

4 participants

@jkoritzinsky@AaronRobinsonMSFT@jtschuster