Skip to content

[tests] Detect GC.KeepAlive kept-alive objects reached via a dup in HandleSafety - #26214

Merged
rolfbjarne merged 3 commits into
mainfrom
dev/rolf/handle-safety-dup
Jul 22, 2026
Merged

[tests] Detect GC.KeepAlive kept-alive objects reached via a dup in HandleSafety#26214
rolfbjarne merged 3 commits into
mainfrom
dev/rolf/handle-safety-dup

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

The C# compiler often compiles this (safe) pattern:

var obj = ...;
DoSomethingWith (obj.GetHandle ());
GC.KeepAlive (obj);

by emitting a dup for obj instead of storing it in a local: one copy
feeds GetHandle, the other stays on the stack until GC.KeepAlive
consumes it. The HandleSafety test traced the dup'd value back to the
instruction that produced it and, when that was a method call, reported
"the object was never stored anywhere" - a false positive, since the
object is explicitly kept alive.

Teach the test to treat a handle fetch as safe when the same object is
passed to GC.KeepAlive somewhere in the method. This resolves
CFProxy.get_ProxyType and nine other entries that already had a
GC.KeepAlive but were still flagged:

  • AVFoundation.AVCaptureReactionType_Extensions.GetSystemImage
  • CoreGraphics.CGColor.Create
  • CoreText.CTFontDescriptor.Create
  • CoreVideo.CVImageBuffer.GetCodePoint (x3)
  • Security.SecKeyChain.Remove
  • Security.SecKeyChain.Update
  • UIKit.UIContentSizeCategoryExtensions.Compare

Copilot-Session: dd86cf03-297a-43e8-ae1f-3c0b22bb67c4

…andleSafety

The C# compiler often compiles this (safe) pattern:

    var obj = ...;
    DoSomethingWith (obj.GetHandle ());
    GC.KeepAlive (obj);

by emitting a `dup` for `obj` instead of storing it in a local: one copy
feeds `GetHandle`, the other stays on the stack until `GC.KeepAlive`
consumes it. The HandleSafety test traced the dup'd value back to the
instruction that produced it and, when that was a method call, reported
"the object was never stored anywhere" - a false positive, since the
object is explicitly kept alive.

Teach the test to treat a handle fetch as safe when the same object is
passed to `GC.KeepAlive` somewhere in the method. This resolves
`CFProxy.get_ProxyType` and nine other entries that already had a
`GC.KeepAlive` but were still flagged:

* AVFoundation.AVCaptureReactionType_Extensions.GetSystemImage
* CoreGraphics.CGColor.Create
* CoreText.CTFontDescriptor.Create
* CoreVideo.CVImageBuffer.GetCodePoint (x3)
* Security.SecKeyChain.Remove
* Security.SecKeyChain.Update
* UIKit.UIContentSizeCategoryExtensions.Compare

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: dd86cf03-297a-43e8-ae1f-3c0b22bb67c4
Copilot AI review requested due to automatic review settings July 21, 2026 14:54

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

Updates the Cecil-based HandleSafety test to recognize a common compiler-emitted dup pattern where an object’s handle is fetched and the object is later kept alive via GC.KeepAlive, eliminating false positives in handle-lifetime analysis.

Changes:

  • Added logic in HandleSafety to treat handle fetches as safe when the same object is passed to GC.KeepAlive.
  • Removed multiple entries from HandleSafety.KnownFailures that were previously (incorrectly) flagged despite having GC.KeepAlive.

Reviewed changes

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

File Description
tests/cecil-tests/HandleSafety.cs Adds GC.KeepAlive awareness to suppress false positives for dup-based patterns (needs a small fix to ensure KeepAlive is after the handle fetch).
tests/cecil-tests/HandleSafety.KnownFailures.cs Removes failures that are no longer expected after the improved analysis.

Comment thread tests/cecil-tests/HandleSafety.cs Outdated
Comment thread tests/cecil-tests/HandleSafety.cs
dalexsoto
dalexsoto previously approved these changes Jul 21, 2026
…eSafety

Address review feedback: IsKeptAlive scanned the entire method body, so a
GC.KeepAlive call that occurs *before* the handle fetch would incorrectly
be treated as safe, hiding real lifetime issues. Restrict the search to
GC.KeepAlive calls that occur after the handle fetch instruction, since a
call before the fetch doesn't keep the object alive while its handle is
in use.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: dd86cf03-297a-43e8-ae1f-3c0b22bb67c4
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: 880652612ef1e58e9fe26bd6ed7b5fa9af20d4bf [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🚀 [CI Build #8806526] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 203 tests passed 🎉

Tests counts

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker (iOS): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (MacCatalyst): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (macOS): All 21 tests passed. Html Report (VSDrops) Download
✅ linker (tvOS): All 15 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 19 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: 880652612ef1e58e9fe26bd6ed7b5fa9af20d4bf [PR build]

@rolfbjarne
rolfbjarne merged commit 14ba2cb into main Jul 22, 2026
56 checks passed
@rolfbjarne
rolfbjarne deleted the dev/rolf/handle-safety-dup branch July 22, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants