Skip to content

Use GCPROTECT_BEGININTERIOR to protect pointers into arrays during array marshalling#123688

Merged
jkoritzinsky merged 1 commit intodotnet:mainfrom
jkoritzinsky:bstr-marshaller-gcprotect
Jan 28, 2026
Merged

Use GCPROTECT_BEGININTERIOR to protect pointers into arrays during array marshalling#123688
jkoritzinsky merged 1 commit intodotnet:mainfrom
jkoritzinsky:bstr-marshaller-gcprotect

Conversation

@jkoritzinsky
Copy link
Member

Fixes #123271
Fixes #123269
Fixes #121690

Failures introduced by #121362 where we changed the string->BSTR array marshalling to call back into managed code. This introduces a transition where the code was not expecting one where GC can trigger.

Update the BSTR marshalling to use GCPROTECT_BEGININTERIOR to ensure that our pointer into the managed array is updated by the GC.

A bunch of this code used various different patterns (manually adjusting offsets after a GC if one occurred, recalculating the offset into the array's data each iteration) instead of using GCPROTECT_BEGININTERIOR. This PR adjusts all of the marshallers where GC could possibly occur (any sort of managed or possibly managed marshalling) to all use GCPROTECT_BEGININTERIOR.

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

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

This PR fixes GC-related crashes in COM interop array marshalling by properly protecting interior pointers into managed arrays using GCPROTECT_BEGININTERIOR. The failures were introduced by PR #121362 which moved BSTR trailbyte tracking out of the sync block, causing transitions to managed code that could trigger GC during array marshalling.

Changes:

  • Replaced manual pointer recalculation logic with GCPROTECT_BEGININTERIOR protection
  • Updated 10 array marshalling functions to protect interior pointers during GC-triggering operations
  • Removed obsolete "unprotected array" tracking code that manually checked if arrays moved

Copy link
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

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

My guess is that indexing from protected base would be a tiny bit cheaper than GC protected interior pointer (avoids stacks spills, multiplication is cheap). It does not really matter.

@jkoritzinsky
Copy link
Member Author

/ba-g nativeaot size failures that have been fixed in main

@jkoritzinsky jkoritzinsky merged commit cb6a651 into dotnet:main Jan 28, 2026
94 of 101 checks passed
@github-project-automation github-project-automation bot moved this to Done in AppModel Jan 28, 2026
@jkoritzinsky jkoritzinsky deleted the bstr-marshaller-gcprotect branch January 28, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Done

3 participants