Debuggiing unhandled exceptions.

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderators: barthess, RoccoMarco

Posts: 348
Joined: Sat Jul 19, 2014 12:59 pm
Been thanked: 12 times

Debuggiing unhandled exceptions.

Postby rew » Sat Dec 14, 2019 4:23 pm


I've just spent two days debugging a chibios project that seemed to hang after a few seconds. Turns out that I was getting an "unhandled exception". I ended up editing stuff into "vectors.c" to grab some state and put it in variables that the debugger can print. Once I recognized where the "lr" register was pointing, i.e. seeing where it crashed, it took less than 10 seconds to know what the problem was and a further 60 seconds to actually fix the problem.

This is what I added:

Code: Select all

__asm (" \
.section  .text.Reset_Handler  \n \
.weak  HardFault_Handler \n\
.type  HardFault_Handler, %function \n\
HardFault_Handler: \n\
  movs r0,#4 \n\
  movs r1, lr \n\
  tst r0, r1 \n\
  beq _MSP \n\
  mrs r0, psp \n\
  b _HALT \n\
_MSP: \n\
  mrs r0, msp \n\
_HALT: \n\
  ldr r1,[r0,#20] \n\
  b hard_fault_handler_c \n\
  bkpt #0 \n\
 .size  HardFault_Handler, .-HardFault_Handler\n\

extern void HardFault_Handler(void);

struct dbg {
  unsigned long stacked_r0 ;
  unsigned long stacked_r1 ;
  unsigned long stacked_r2 ;
  unsigned long stacked_r3 ;
  unsigned long stacked_r12 ;
  unsigned long stacked_lr ;
  unsigned long stacked_pc ;
  unsigned long stacked_psr ;
  unsigned long _CFSR ;
  unsigned long _HFSR ;
  unsigned long _DFSR ;
  unsigned long _AFSR ;
  unsigned long _BFAR ;
  unsigned long _MMAR ;
  NVIC_Type *nvic;
  SCB_Type  *scb;

static volatile struct dbg d;

void hard_fault_handler_c(unsigned long *hardfault_args)
  d.stacked_r0 = ((unsigned long)hardfault_args[0]) ;
  d.stacked_r1 = ((unsigned long)hardfault_args[1]) ;
  d.stacked_r2 = ((unsigned long)hardfault_args[2]) ;
  d.stacked_r3 = ((unsigned long)hardfault_args[3]) ;
  d.stacked_r12 = ((unsigned long)hardfault_args[4]) ;
  d.stacked_lr = ((unsigned long)hardfault_args[5]) ;
  d.stacked_pc = ((unsigned long)hardfault_args[6]) ;
  d.stacked_psr = ((unsigned long)hardfault_args[7]) ;
  d.nvic = NVIC; = SCB;

  // Configurable Fault Status Register
  // Consists of MMSR, BFSR and UFSR
  d._CFSR = (*((volatile unsigned long *)(0xE000ED28))) ;

  // Hard Fault Status Register
  d._HFSR = (*((volatile unsigned long *)(0xE000ED2C))) ;

  // Debug Fault Status Register
  d._DFSR = (*((volatile unsigned long *)(0xE000ED30))) ;

  // Auxiliary Fault Status Register
  d._AFSR = (*((volatile unsigned long *)(0xE000ED3C))) ;

  // Read the Fault Address Registers. These may not contain valid values.
  // Check BFARVALID/MMARVALID to see if they are valid values
  // MemManage Fault Address Register
  d._MMAR = (*((volatile unsigned long *)(0xE000ED34))) ;
  // Bus Fault Address Register
  d._BFAR = (*((volatile unsigned long *)(0xE000ED38))) ;

  __asm("BKPT #0\n") ; // Break into the debugger

It is not perfect yet. As is: this doesn't seem to work with LTO enabled. And the CFSR etc registers ... might not be available on my M0 processor (STM32F030) as they all end up being zero. And probably somewhere the source of the interrupt/exception should be findable, but I have not been able to find it yet. (I'm really not friends with the ARM documentation site. So in the cortex M0 docs it says to look in the ARM_V6 manual for further information. Well.... they could make that a link. Or easily find-able. But docs for bunches of other arm processor variants are in the menu, but not V6. )

User avatar
Site Admin
Posts: 13125
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 769 times
Been thanked: 653 times

Re: Debuggiing unhandled exceptions.

Postby Giovanni » Sat Dec 14, 2019 4:28 pm


On exception entry the exception number is available in the LSbs of the status register, MSP points to a registers dump (port_extctx structure) where LR/PC are stored.


Posts: 348
Joined: Sat Jul 19, 2014 12:59 pm
Been thanked: 12 times

Re: Debuggiing unhandled exceptions.

Postby rew » Sat Dec 14, 2019 5:36 pm

OK. Thanks.
I can try converting that into code. But by now my bug has been found, and I won't profit from it today.

But if this can be integrated into CHIBIOS in some way then I think it would be useful. The idea would be that you enable a "debug unexpected exceptions" option in the config file and then this extra code would be included.

Another way to handle this is to have something like the minimal code always enabled in chibios and that the user can define a macro with the body of the bigger C-function or simply override the default (weak) function that does "while (1)", and replace it with any custom version, for example, mine...

But because MY current problem is already solved, I would need a goahead from you to make it better for inclusion into the standard Chibios. You will need to coach me a bit by helping me find stuff like the above "cause is in SR" and by making choices like "macro to disable the code completely" or a HOOK that gets called...

Posts: 734
Joined: Fri Nov 09, 2012 2:22 pm
Has thanked: 10 times
Been thanked: 109 times

Re: Debuggiing unhandled exceptions.

Postby steved » Sat Dec 14, 2019 10:17 pm

There are already various threads including helful debugging code. I've found these two:


and there's a third which I haven't managed to find on a quick look.

Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 10 guests