Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit b825061

Browse files
authored
Port to 3.1 - Fix DynamicMethodDesc::Destroy vs code heap enumeration race (#28036)
There is a race between DynamicMethodDesc::Destroy called from the finalizer thread and the MethodDescs enumeration called from ETW::MethodLog::SendEventsForJitMethods at process exit. DynamicMethodDesc::Destroy cleanos up its members m_pSig and m_pszMethodName and then it calls GetLCGMethodResolver()->Destroy(); That calls EEJitManager::FreeCodeMemory, which tries to take the m_CodeHeapCritSec lock. But this lock is already held by the ETW::MethodLog::SendEventsForJitMethods. So the iterator can see half-destroyed DynamicMethodDesc and a crash happens when trying to get the dynamic method name from the m_pszMethodName for the ETW event purposes. The fix is to call the GetLCGMethodResolver()->Destroy() before destroying the m_pSig and m_pszMethodName.
1 parent b53a526 commit b825061

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/vm/dynamicmethod.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -851,20 +851,26 @@ void DynamicMethodDesc::Destroy()
851851
LoaderAllocator *pLoaderAllocator = GetLoaderAllocator();
852852

853853
LOG((LF_BCL, LL_INFO1000, "Level3 - Destroying DynamicMethod {0x%p}\n", this));
854-
if (!m_pSig.IsNull())
854+
855+
// The m_pSig and m_pszMethodName need to be destroyed after the GetLCGMethodResolver()->Destroy() call
856+
// otherwise the EEJitManager::CodeHeapIterator could return DynamicMethodDesc with these members NULLed, but
857+
// the nibble map for the corresponding code memory indicating that this DynamicMethodDesc is still alive.
858+
PCODE pSig = m_pSig.GetValue();
859+
PTR_CUTF8 pszMethodName = m_pszMethodName.GetValue();
860+
861+
GetLCGMethodResolver()->Destroy();
862+
// The current DynamicMethodDesc storage is destroyed at this point
863+
864+
if (pszMethodName != NULL)
855865
{
856-
delete[] (BYTE*)m_pSig.GetValue();
857-
m_pSig.SetValueMaybeNull(NULL);
866+
delete[] pszMethodName;
858867
}
859-
m_cSig = 0;
860-
if (!m_pszMethodName.IsNull())
868+
869+
if (pSig != NULL)
861870
{
862-
delete[] m_pszMethodName.GetValue();
863-
m_pszMethodName.SetValueMaybeNull(NULL);
871+
delete[] (BYTE*)pSig;
864872
}
865873

866-
GetLCGMethodResolver()->Destroy();
867-
868874
if (pLoaderAllocator->IsCollectible())
869875
{
870876
if (pLoaderAllocator->Release())

0 commit comments

Comments
 (0)