Skip to content

Commit e31f49e

Browse files
committed
Fix bugs in GDB mem read fault detection
While testing the lastest version of ThreadMRI I noticed that it was hanging when I would ask GDB to read from an invalid memory address. It turns out that advancePCToNextInstruction() was using the XPSR register instead of the PC. I also added code to properly clear the fault status registers when GDB memory read/write faults are detected.
1 parent 15ebcd3 commit e31f49e

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

libraries/ThreadMRI/src/ThreadMRI.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ static bool isImpreciseBusFault();
167167
static void advancePCToNextInstruction(uint32_t excReturn, uint32_t psp, uint32_t msp);
168168
static uint32_t* threadSP(uint32_t excReturn, uint32_t psp, uint32_t msp);
169169
static bool isInstruction32Bit(uint16_t firstWordOfInstruction);
170+
static void clearFaultStatusBits();
170171
static void serialISRHook();
171172
static bool isDebuggerActive();
172173
static void setControlCFlag();
@@ -565,6 +566,7 @@ extern "C" void mriFaultHandler(uint32_t excReturn, uint32_t psp, uint32_t msp)
565566
if (!isImpreciseBusFault()) {
566567
advancePCToNextInstruction(excReturn, psp, msp);
567568
}
569+
clearFaultStatusBits();
568570
return;
569571
}
570572

@@ -649,7 +651,7 @@ static bool isImpreciseBusFault()
649651
static void advancePCToNextInstruction(uint32_t excReturn, uint32_t psp, uint32_t msp)
650652
{
651653
uint32_t* pSP = threadSP(excReturn, psp, msp);
652-
uint32_t* pPC = pSP + 7;
654+
uint32_t* pPC = pSP + 6;
653655
uint16_t currentInstruction = *(uint16_t*)*pPC;
654656
if (isInstruction32Bit(currentInstruction)) {
655657
*pPC += sizeof(uint32_t);
@@ -680,6 +682,14 @@ static bool isInstruction32Bit(uint16_t firstWordOfInstruction)
680682
maskedOffUpper5BitsOfWord == 0xF800);
681683
}
682684

685+
static void clearFaultStatusBits()
686+
{
687+
/* Clear fault status bits by writing 1s to bits that are already set. */
688+
SCB->DFSR = SCB->DFSR;
689+
SCB->HFSR = SCB->HFSR;
690+
SCB->CFSR = SCB->CFSR;
691+
}
692+
683693

684694
static void serialISRHook()
685695
{

0 commit comments

Comments
 (0)