-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Description
Hey, folks. I've noticed unmanaged memory isn't released if you are using public debugging API in a certain way.
The problem is happening if you'll get an CorDbEnumerator and clone it. There is no way to neuter the cloned object and the items array it contain never gets freed.
Reproduction Steps
In our codebase the repro looks like this:
In OnException callback pseudo code is following:
ICorDebugValue exceptionObjectReference = thread.CorDebugThread.GetCurrentException();
ICorDebugExceptionObjectValue exceptionValue = GetExceptionValue(exceptionObjectReference);
exceptionValue.EnumerateExceptionCallStack(out ICorDebugExceptionObjectCallStackEnum callStackEnumerator);
callStackEnumerator.Clone(out ICorDebugEnum exceptionCallStackEnumerator);
exceptionCallStackEnumerator.Release();
//exceptionCallStackEnumerator still holds memory after the last release
//callStackEnumerator is added to the ContinueNeuterList and frees its resources properly.
Run the debugger on any application which throws exceptions from deep call stacks to magnify effect. For example:
using System.Diagnostics;
using System.Text.RegularExpressions;
void CallSync(int i)
{
if (i == 0)
throw new Exception("Zero");
CallSync(i - 1);
}
void DoTestSync(int i)
{
try
{
CallSync(i);
}
catch (Exception e)
{
if (e.Message == "Zero")
{
// Debug.WriteLine($"{i}");
}
}
}
Console.WriteLine(Environment.Version);
while (true)
{
DoTestSync(150);
}
Expected behavior
Clone is released either when refCounter == 0 or there is a Neuter() API to free resources
Actual behavior
Overtime debugger leaks native memory and in debug version of runtime I'm getting an assertion:
Microsoft Visual C++ Runtime Library
---------------------------
Debug Assertion Failed!
Program: ...\runtime\artifacts\bin\coreclr\windows.x64.Debug\mscordbi.dll
File: C:\work\other\runtime\src\coreclr\debug\di\rsenumerator.hpp
Line: 120
Expression: IsNeutered()
For information on how your program can cause an assertion
failure, see the Visual C++ documentation on asserts.
(Press Retry to debug the application)
---------------------------
Abort Retry Ignore
---------------------------
Regression?
No response
Known Workarounds
Not use Clone() API and recreate enumerator when needed.
Configuration
.NET 9, 10 and the latest master are affected, probably earlier versions too.
Other information
No response