dotnet / dotnet/runtime

Mono crashes with AVE when a ref field is written during debugger evaluation

Open
#128,259 3 comments 0 reactions 0 assignees View on GitHub
area-Debugger-mono
Dominant language
C#
Stars
18.3k
Forks
5.6k
PR merge metrics
PR metrics pending

Description

### Description

Hello, folks!
The crash happens because [the current algorithm](https://github.com/dotnet/runtime/blob/87523393fdb14746ceb529ab308f11047819fd01/src/mono/mono/component/debugger-agent.c#L426) of calculating the size of the memory behind a ref field can't correctly determine the real size of the [allocated memory](https://github.com/dotnet/runtime/blob/87523393fdb14746ceb529ab308f11047819fd01/src/mono/mono/component/debugger-agent.c#L434) the ref struct points to. This causes writing outside of the allocated memory and results in AVE.
It can be reproduced by the following code snippet(included into the repro project):

```cs
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace TestScriptLib;

public ref struct MyRefStruct
{
public ref char Ptr;
public int Length;
public MyRefStruct(ref char ptr, int length)
{
Ptr = ref ptr;
Length = length;
}

public void Write()
{
for (int i = 0; i < Length; i++)
Unsafe.Add(ref Ptr, i) = '0';
}
}

public class TestClass
{
public static void TestMethod()
{
var myString = new string('1', 1 << 16).ToCharArray();
var myStruct = new MyRefStruct(ref myString[0], myString.Length);
} // set a breakpoint here and evaluate myStruct.Write() in the Immediate Window
}
```

### Reproduction Steps

You can reproduce the problem on the following solution on Windows x64 VS 2026 (I used 18.4.3, but I think any 26 version is affected):

[thinmono.zip](https://github.com/user-attachments/files/27807749/thinmono.zip)

1. Open `thinmono\TestScriptLib\TestScriptLib.sln` in VS and build it (if VS complains .NET 11 is not installed you can edit `TestScriptLib.csproj` to set the `TargetFramework net11.0 -> net10.0`)
2. Set a breakpoint at `TestFile.cs:32`
3. Go to `thinmono\ThinMono.vcxproj` and set the `PathToDotnet` to the path to `runtime` directory. Ensure the `build.cmd-subset mono+libs` is executed
4. Open `thinmono\ThinMono.sln` in VS and run Debug AnyCPU configuration
5. Once the native host is running attach to the app via VS's "Attach Unity Debugger" action with 9000 debug port specified, please see the attached screenshot
image
7. Once the managed debugger attaches the breakpoint set on the step 2 will be hit. Evaluate `myStruct.Write()` in the Immediate Window

### Expected behavior

Successful evaluation

### Actual behavior

Access Violation exception

### Regression?

_No response_

### Known Workarounds

_No response_

### Configuration

Windows 11 x64, VS 2026 (I used 18.4.3, but I think any 26 version is affected)

### Other information

I have tried to implement an approach which reuses the real addresses of by ref fields, it is probably incomplete, but works fine in the reproduction scenario. You can find it [here](https://github.com/eterekhin/runtime/commit/dd70064e2b3c0d568eb3a36eadbbdce23c44d867)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.