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

Commit 970884a

Browse files
authored
Fix GC stress C bug for arm (#15269)
* Fix GC stress C bug for arm The OnGcCoverageInterrupt function was not removing the "thumb" bit from the address before putting back the original instruction that was previously replaced by an invalid instruction that invokes the OnGcCoverageInterrupt. That resulted in the original instruction being restored to incorrect location (to the original address + 1) and later to the GC stress failure. * Reflect PR feedback
1 parent 9e9bfd7 commit 970884a

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

src/vm/gccover.cpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ bool IsGcCoverageInterrupt(LPVOID ip)
12931293
// original instruction. Only one instruction must be used,
12941294
// because multiple threads can be executing the same code stream.
12951295

1296-
void RemoveGcCoverageInterrupt(Volatile<BYTE>* instrPtr, BYTE * savedInstrPtr)
1296+
void RemoveGcCoverageInterrupt(TADDR instrPtr, BYTE * savedInstrPtr)
12971297
{
12981298
#ifdef _TARGET_ARM_
12991299
if (GetARMInstructionLength(savedInstrPtr) == 2)
@@ -1303,7 +1303,7 @@ void RemoveGcCoverageInterrupt(Volatile<BYTE>* instrPtr, BYTE * savedInstrPtr)
13031303
#elif defined(_TARGET_ARM64_)
13041304
*(DWORD *)instrPtr = *(DWORD *)savedInstrPtr;
13051305
#else
1306-
*instrPtr = *savedInstrPtr;
1306+
*(BYTE *)instrPtr = *savedInstrPtr;
13071307
#endif
13081308
}
13091309

@@ -1315,12 +1315,12 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs)
13151315
GCcoverCount++;
13161316
forceStack[0]= &regs; // This is so I can see it fastchecked
13171317

1318-
BYTE* pControlPc = (BYTE*)GetIP(regs);
1318+
PCODE controlPc = GetIP(regs);
1319+
TADDR instrPtr = PCODEToPINSTR(controlPc);
13191320

1320-
Volatile<BYTE>* instrPtr = (Volatile<BYTE>*)pControlPc;
13211321
forceStack[0] = &instrPtr; // This is so I can see it fastchecked
13221322

1323-
EECodeInfo codeInfo((PCODE)pControlPc);
1323+
EECodeInfo codeInfo(controlPc);
13241324
if (!codeInfo.IsValid())
13251325
return(FALSE);
13261326

@@ -1384,27 +1384,27 @@ FORCEINLINE void UpdateGCStressInstructionWithoutGC ()
13841384

13851385
void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
13861386
{
1387-
BYTE* pControlPc = (BYTE*)GetIP(regs);
1388-
Volatile<BYTE>* instrPtr = (Volatile<BYTE>*)pControlPc;
1387+
PCODE controlPc = GetIP(regs);
1388+
TADDR instrPtr = PCODEToPINSTR(controlPc);
13891389

13901390
if (!pMD)
13911391
{
1392-
pMD = ExecutionManager::GetCodeMethodDesc((PCODE)pControlPc);
1392+
pMD = ExecutionManager::GetCodeMethodDesc(controlPc);
13931393
if (!pMD)
13941394
return;
13951395
}
13961396

13971397
GCCoverageInfo *gcCover = pMD->m_GcCover;
13981398

1399-
EECodeInfo codeInfo((TADDR)instrPtr);
1399+
EECodeInfo codeInfo(controlPc);
14001400
_ASSERTE(codeInfo.GetMethodDesc() == pMD);
14011401
DWORD offset = codeInfo.GetRelOffset();
14021402

14031403
Thread *pThread = GetThread();
14041404

14051405
#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
14061406

1407-
BYTE instrVal = *instrPtr;
1407+
BYTE instrVal = *(BYTE *)instrPtr;
14081408
forceStack[6] = &instrVal; // This is so I can see it fastchecked
14091409

14101410
if (instrVal != INTERRUPT_INSTR &&
@@ -1419,9 +1419,6 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
14191419

14201420
#elif defined(_TARGET_ARM_)
14211421

1422-
_ASSERTE(((TADDR)instrPtr) & THUMB_CODE);
1423-
instrPtr = instrPtr - THUMB_CODE;
1424-
14251422
WORD instrVal = *(WORD*)instrPtr;
14261423
forceStack[6] = &instrVal; // This is so I can see it fastchecked
14271424

@@ -1680,7 +1677,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
16801677
}
16811678

16821679
// Must flush instruction cache before returning as instruction has been modified.
1683-
FlushInstructionCache(GetCurrentProcess(), instrPtr, 6);
1680+
FlushInstructionCache(GetCurrentProcess(), (LPCVOID)instrPtr, 6);
16841681

16851682
// It's not GC safe point, the GC Stress instruction is
16861683
// already commited and interrupt is already put at next instruction so we just return.
@@ -1770,7 +1767,7 @@ void DoGcStress (PCONTEXT regs, MethodDesc *pMD)
17701767
UpdateGCStressInstructionWithoutGC ();
17711768

17721769
// Must flush instruction cache before returning as instruction has been modified.
1773-
FlushInstructionCache(GetCurrentProcess(), instrPtr, 4);
1770+
FlushInstructionCache(GetCurrentProcess(), (LPCVOID)instrPtr, 4);
17741771

17751772
CONSISTENCY_CHECK(!pThread->HasPendingGCStressInstructionUpdate());
17761773

0 commit comments

Comments
 (0)