Deterministic repro
- Build a private coreclr.dll with
Sleep(1000) added here:
- Enable page heap for corerun.exe using
gflags
- Compile and run the following test using corerun.exe:
using System;
using System.Threading;
using System.Runtime.CompilerServices;
Helper.Initialize();
new Thread(Work).Start();
GC.Collect();
GC.WaitForPendingFinalizers();
Thread.Sleep(3000);
static void Work()
{
for (;;)
{
if (Helper.ResurectedThread != null)
{
Helper.ResurectedThread.DisableComObjectEagerCleanup();
}
}
}
class Helper
{
public static volatile Thread ResurectedThread;
Thread _thread;
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Initialize() => GC.KeepAlive(new Helper());
Helper()
{
_thread = new Thread(() => { });
_thread.Start();
_thread.Join();
}
~Helper()
{
ResurectedThread = _thread;
}
}
(It is also possible to build non-deterministic repro that reproduces the crash on shipping bits.)
Actual result
Assert failure(PID 23336 [0x00005b28], Thread: 21216 [0x52e0]): Consistency check failed: AV in clr at this callstack:
------
CORECLR! DoJoin + 0x2C3 (0x00007ffa`175c9d83)
CORECLR! ThreadNative_Join + 0x15B (0x00007ffa`175cd87b)
-----
.AV on tid=0x52e0 (21216), cxr=0000009F9477E6C0, exr=0000009F9477EBB0
The crash is caused by use-after-free of the unmanaged Thread object.
Expected result
No runtime crash. C# code that does not used unsafe blocks and that does not call any memory unsafe APIs should not lead to runtime crash.
Deterministic repro
Sleep(1000)added here:runtime/src/coreclr/vm/comsynchronizable.cpp
Line 790 in c2de915
gflags(It is also possible to build non-deterministic repro that reproduces the crash on shipping bits.)
Actual result
The crash is caused by use-after-free of the unmanaged Thread object.
Expected result
No runtime crash. C# code that does not used
unsafeblocks and that does not call any memory unsafe APIs should not lead to runtime crash.