Skip to content

Commit

Permalink
Fix access ordering issue in Module::AllocateDynamicEntry on arm64 (#…
Browse files Browse the repository at this point in the history
…53556)

While stress testing runtime on Windows ARM64 to repro an issue, I have
hit an ordering issue in access to m_maxDynamicEntries and
m_pDynamicStaticsInfo in the Module::AllocateDynamicEntry.

In one of a few thousands of runs, I got a runtime crash when the
m_pDynamicStaticsInfo was NULL. I was able to repro this issue reliably
in the above mentioned number of runs. After the fix, it doesn't repro
anymore.

The newId was 1 at the time of the crash, the m_maxDynamicEntries was
around 128. So the crashing thread has got the id 1, then another thread
updated the m_maxDynamicEntries before the crashing thread executed the
`if (newId >= m_maxDynamicEntries)`, so the thread went right to the
`m_pDynamicStaticsInfo[newId].pEnclosingMT = pMT;`. The
m_pDynamicStaticInfo is written before the m_maxDynamicEntries, so it
was expected that it cannot be NULL, but the crashing thread has seen
the operations in an opposite order due to the CPU access reordering.

The fix is to add VolatileLoad for accessing the m_maxDynamicEntries and
VolatileStore to set it. That ensures that the writes will be visible in
the intended order.
  • Loading branch information
janvorli committed Jun 2, 2021
1 parent 9ab81f7 commit 190c69d
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2618,7 +2618,7 @@ DWORD Module::AllocateDynamicEntry(MethodTable *pMT)

DWORD newId = FastInterlockExchangeAdd((LONG*)&m_cDynamicEntries, 1);

if (newId >= m_maxDynamicEntries)
if (newId >= VolatileLoad(&m_maxDynamicEntries))
{
CrstHolder ch(&m_Crst);

Expand All @@ -2637,7 +2637,7 @@ DWORD Module::AllocateDynamicEntry(MethodTable *pMT)
memcpy(pNewDynamicStaticsInfo, m_pDynamicStaticsInfo, sizeof(DynamicStaticsInfo) * m_maxDynamicEntries);

m_pDynamicStaticsInfo = pNewDynamicStaticsInfo;
m_maxDynamicEntries = maxDynamicEntries;
VolatileStore(&m_maxDynamicEntries, maxDynamicEntries);
}
}

Expand Down

0 comments on commit 190c69d

Please sign in to comment.