Besides hardware breakpoints, software breakpoints can be used to break into the debugger. The debugger supports this only if the code is placed in RAM. This is often not at all practical.
As a life-hack, what can be done instead is to make breakpoint()
function which contains a hardware breakpoint. Now wherever this function is called, the breakpoint is activated:
void __attribute__ ((noinline)) breakpoint()
{
__asm("NOP"); // <---- set a hardware breakpoint here!
// hello, please Step Out to go to caller location (ex: press Shift-F11)
}
void main()
{
int x = 1;
breakpoint(); // break into the debugger
printf("%d\n", x);
x += 2;
breakpoint(); // break into the debugger, again
printf("%d\n", x);
}
The debugger will now stop within breakpoint()
. To see the actual location of the breakpoint, one must Step Out.
This technique frees up the hardware breakpoints for interactions like single stepping, and the 4 breakpoints available would often be enough.
Notes:
- an alternative for the
breakpoint()
function would be to use __asm("BKPT #0")
, which enters the debugger. Unfortunately there is no way to Step Over this instruction (tested on STM32/GDB), so it effectively acts like a HALT instruction. It can be used to place breakpoints inside fault conditions or unused interrupts.
- the
breakpoint()
function seem to work only once when the __asm("NOP");
is omitted
- with regard to the STM8, it exceptionally has a flash memory that supports byte updates, so it can act in a way very similar to RAM. A debugger can use this to insert soft breakpoints, and as much as needed.
- the STM8 has only 2 breakpoint registers, though, which are probably used exclusively for single stepping.
- other, more powerful, ARM Cortex MCU's can have 6 or 8 hardware breakpoints.
- GDB (and other debuggers) could probably be a bit smarter in the way they deal with breakpoints. For example when you have several breakpoints in a function, it would often be impossible to hit some breakpoint before hitting the breakpoint above it. This could go a long way in certain common debugging scenarios.