Skip to content

GCHandle Target unexpectedly change during VS debugger breakpoint debugging #116337

Open
@Liangjia0411

Description

@Liangjia0411

Description

When using coreclr as the runtime and debugging C# code with Visual Studio debugger, we discovered that the GCHandle's Target value unexpectedly changes (becomes null or changes to objects of other types). This causes program exceptions. This issue only occurs when using debugger breakpoints; the program runs normally without breakpoint debugging.

Environment Information

  • .NET version: 9.0.3
  • Visual Studio version: 17.13.2

Additional Information

We suspect this might be related to how the debugger handles interactions between managed and unmanaged code, especially when dealing with pinned GCHandles. This leads to abnormal garbage collector behavior or the debugger incorrectly displaying/modifying the GCHandle's target.

Reproduction Steps

  1. Use coreclr as the runtime
  2. Enable mixed debugging (Native + Managed)
  3. Set a breakpoint at the third line of the following code:
public static unsafe bool LoadFileToArray(ref byte[] Result, string FileName, uint Flags = 0) 
{
   using var gcHandleScopeForResult = new Interop.GCHandleScope(Result, GCHandleType.Pinned);
   var interopArrayForResult = new Interop.RefStructArray<byte>(Result, gcHandleScopeForResult.GetHandle());
   bool Return_Temp = MonoInit.BoolConverter.ToManagedBool(Internal_LoadFileToArray(ref interopArrayForResult, FileName, Flags));
   Result = interopArrayForResult.GetArrayAfterInterop();
   return Return_Temp;
}

Expected behavior

When execution reaches the third line, the GCHandle in gcHandleScopeForResult should still point to the passed Result array.

Actual behavior

  1. In the first line of code, a GCHandle is created for Result and stored in gcHandleScopeForResult
  2. When the breakpoint hits the third line, we find that the GCHandle's Target in gcHandleScopeForResult has become null

Image

  1. With mixed debugging enabled, this issue consistently occurs in specific scenarios when breaking at this function, but we haven't encountered this problem in other scenarios
  2. With mixed debugging enabled, if no breakpoints are set, the program runs normally
  3. As we continue stepping through with breakpoints, the Target value may change again, for example, in one case it changed to a string object

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions