Debug hard fault (stm32) in VScode / platform io

I am having hard faults in my project (STM32, FreeRTOS, lwip). I can work around it by putting delays in a thread, but I don’t want to. I am trying to understand how to debug hard faults instead by following this guide.

I am working in VScode, I do not master gdb. So I hope I can do the work from vscode/pio.

I added something that causes a hard fault:

uint illegal_instruction_execution(void) {
  uint * i = (uint*)0xFFFFFFFF;
  *i = 0;
  return *i;

When I call that function from my int main() my program immediately crashes and ends up in HardFault_Handler.

From the guide:

Regardless, the hardware will always push the same core set of registers to the very top of the stack which was active prior to entering the exception. ARM Cortex-M devices have two stack pointers, msp & psp . Upon exception entry, the active stack pointer is encoded in bit 2 of the EXC_RETURN value pushed to the link register. If the bit is set, the psp was active prior to exception entry, else the msp was active.

I can see msp and psp in vscode:

  • msp = 0x2001ffb0
  • psp = 0x00000000

So looks like msp is the only valid one. I double checked anyway, the 2nd bit in link register is 0, thus msp is active.

So I think I learned now that the source of the error originates from the msp stack, at 0x2001ffb0.

But the last vital step in the guide I can’t seem to get right. In the guide I think he pulls out the active stack from msp. I tried to load the address in the memory section in pio and just load any amount of bytes (200 e.g.) but all I read back are zeroes. And, reading the memory doesn’t give me a stacktrace either.

Any advice how to proceed is greatly appreciated.

Figured it out, super easy of course. I can issue gdb commands in the debug terminal. So I can follow the guide step by step.

My hard fault was caused by using std::vector which reallocs memory on the heap. I guess I suffered from heap fragmentation. Moving away from using stl solved my issue.