1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-16 18:13:49 +01:00

cortexm: Hard fault: Try to output as much as possible even with corrupt stack

This commit is contained in:
Joakim Nohlgård 2016-07-15 21:54:54 +02:00
parent 05685d1e21
commit 5cd91bc784

View File

@ -194,15 +194,6 @@ __attribute__((naked)) void hard_fault_default(void)
__attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted, uint32_t exc_return, uint32_t* r4_to_r11_stack) __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted, uint32_t exc_return, uint32_t* r4_to_r11_stack)
{ {
/* Check if the ISR stack overflowed previously. Not possible to detect
* after output may also have overflowed it. */
if(*(&_sstack) != STACK_CANARY_WORD) {
puts("\nISR stack overflowed");
}
/* Sanity check stack pointer and give additional feedback about hard fault */
if( corrupted ) {
puts("Stack pointer corrupted, reset to top of stack");
} else {
#if CPU_HAS_EXTENDED_FAULT_REGISTERS #if CPU_HAS_EXTENDED_FAULT_REGISTERS
/* Copy status register contents to local stack storage, this must be /* Copy status register contents to local stack storage, this must be
* done before any calls to other functions to avoid corrupting the * done before any calls to other functions to avoid corrupting the
@ -214,18 +205,30 @@ __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted,
uint32_t dfsr = SCB->DFSR; uint32_t dfsr = SCB->DFSR;
uint32_t afsr = SCB->AFSR; uint32_t afsr = SCB->AFSR;
#endif #endif
uint32_t pc;
uint32_t* orig_sp;
/* Check if the ISR stack overflowed previously. Not possible to detect
* after output may also have overflowed it. */
if(*(&_sstack) != STACK_CANARY_WORD) {
puts("\nISR stack overflowed");
}
/* Sanity check stack pointer and give additional feedback about hard fault */
if(corrupted) {
puts("Stack pointer corrupted, reset to top of stack");
}
else {
uint32_t r0 = sp[0]; uint32_t r0 = sp[0];
uint32_t r1 = sp[1]; uint32_t r1 = sp[1];
uint32_t r2 = sp[2]; uint32_t r2 = sp[2];
uint32_t r3 = sp[3]; uint32_t r3 = sp[3];
uint32_t r12 = sp[4]; uint32_t r12 = sp[4];
uint32_t lr = sp[5]; /* Link register. */ uint32_t lr = sp[5]; /* Link register. */
uint32_t pc = sp[6]; /* Program counter. */ pc = sp[6]; /* Program counter. */
uint32_t psr = sp[7]; /* Program status register. */ uint32_t psr = sp[7]; /* Program status register. */
/* Reconstruct original stack pointer before fault occurred */ /* Reconstruct original stack pointer before fault occurred */
uint32_t* orig_sp = sp + 8; orig_sp = sp + 8;
if (psr & SCB_CCR_STKALIGN_Msk) { if (psr & SCB_CCR_STKALIGN_Msk) {
/* Stack was not 8-byte aligned */ /* Stack was not 8-byte aligned */
orig_sp += 1; orig_sp += 1;
@ -244,6 +247,7 @@ __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted,
" pc: 0x%08" PRIx32 "\n" " pc: 0x%08" PRIx32 "\n"
" psr: 0x%08" PRIx32 "\n\n", " psr: 0x%08" PRIx32 "\n\n",
r12, lr, pc, psr); r12, lr, pc, psr);
}
#if CPU_HAS_EXTENDED_FAULT_REGISTERS #if CPU_HAS_EXTENDED_FAULT_REGISTERS
puts("FSR/FAR:"); puts("FSR/FAR:");
printf(" CFSR: 0x%08" PRIx32 "\n", cfsr); printf(" CFSR: 0x%08" PRIx32 "\n", cfsr);
@ -261,6 +265,8 @@ __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted,
#endif #endif
puts("Misc"); puts("Misc");
printf("EXC_RET: 0x%08" PRIx32 "\n", exc_return); printf("EXC_RET: 0x%08" PRIx32 "\n", exc_return);
if (!corrupted) {
puts("Attempting to reconstruct state for debugging..."); puts("Attempting to reconstruct state for debugging...");
printf("In GDB:\n set $pc=0x%" PRIx32 "\n frame 0\n bt\n", pc); printf("In GDB:\n set $pc=0x%" PRIx32 "\n frame 0\n bt\n", pc);
int stack_left = _stack_size_left(HARDFAULT_HANDLER_REQUIRED_STACK_SPACE); int stack_left = _stack_size_left(HARDFAULT_HANDLER_REQUIRED_STACK_SPACE);
@ -295,8 +301,8 @@ __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted,
[extra_stack] "r" (r4_to_r11_stack) [extra_stack] "r" (r4_to_r11_stack)
: "r0","r1","r2","r3","r12" : "r0","r1","r2","r3","r12"
); );
__BKPT(1);
} }
__BKPT(1);
core_panic(PANIC_HARD_FAULT, "HARD FAULT HANDLER"); core_panic(PANIC_HARD_FAULT, "HARD FAULT HANDLER");
} }