Skip to content

Commit

Permalink
cortexm_common: check for possible stack overflow in hardfault handler
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-k committed Oct 27, 2015
1 parent 9b05f4e commit c5e220c
Showing 1 changed file with 22 additions and 3 deletions.
25 changes: 22 additions & 3 deletions cpu/cortexm_common/vectors_cortexm.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,19 @@ void nmi_default(void)
/* The hard fault handler requires some stack space as a working area for local
* variables and printf function calls etc. If the stack pointer is located
* closer than HARDFAULT_HANDLER_REQUIRED_STACK_SPACE from the lowest address of
* RAM we will reset the stack pointer to the top of available RAM. */
#define HARDFAULT_HANDLER_REQUIRED_STACK_SPACE (THREAD_EXTRA_STACKSIZE_PRINTF)
* RAM we will reset the stack pointer to the top of available RAM.
* Measured from trampoline entry to breakpoint:
* - Cortex-M0+ 344 Byte
* - Cortex-M4 344 Byte
*/
#define HARDFAULT_HANDLER_REQUIRED_STACK_SPACE (344U)

static inline int _stack_size_left(uint32_t required)
{
uint32_t* sp;
asm volatile ("mov %[sp], sp" : [sp] "=r" (sp) : : );
return ((int)((uint32_t)sp - (uint32_t)&_sstack) - required);
}

/* Trampoline function to save stack pointer before calling hard fault handler */
void hard_fault_default(void)
Expand Down Expand Up @@ -181,7 +192,11 @@ 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)
{

/* 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");
Expand Down Expand Up @@ -246,6 +261,10 @@ __attribute__((used)) void hard_fault_handler(uint32_t* sp, uint32_t corrupted,
printf("EXC_RET: 0x%08" PRIx32 "\n", exc_return);
puts("Attempting to reconstruct state for debugging...");
printf("In GDB:\n set $pc=0x%lx\n frame 0\n bt\n", pc);
int stack_left = _stack_size_left(HARDFAULT_HANDLER_REQUIRED_STACK_SPACE);
if(stack_left < 0) {
printf("\nISR stack overflowed by at least %d bytes.\n", (-1 * stack_left));
}
__ASM volatile (
"mov r0, %[sp]\n"
"ldr r2, [r0, #8]\n"
Expand Down

0 comments on commit c5e220c

Please sign in to comment.