This is one of the reasons I prefer to run the code from RAM if possible rather than FLASH when debugging - GDB supports software breakpoints in RAM but not FLASH. It also loads faster and doesn't wear the FLASH, though that shouldn't be much of a problem these days.
It does mean you need to select a device with enough RAM which obviously won't always be possible, but often I find that I tend to make heaviest use of the debugger for relatively small programs such as when trying to get to grips with a new peripheral or trying to understand example or third party code. In the case of ST's Nucleo boards there isn't even much, if any, premium for selecting a higher spec part in a product line than a more basic one.
For example, when debugging an STM32F334 ADC example using DMA ('ADC_SingleConversion_TriggerSW_DMA') , I ended up using quite a lot of breakpoints when it didn't work consistently, to cover all the error condition tests etc. The code sets up the ADC and DMA but only starts the ADC when a user input button is pressed - within an interrupt routine triggered by the switch input going low. The particular fault turned out to be due to switch bounce causing a second switch input interrupt trying to start the ADC but the LL HAL code checked to see if the ADC was already running - which it was as the first interrupt had started it.
It's obvious now, but it took me quite a while, and lots of breakponts, to get to the slaphead moment of realisation. In mitigation I suppose I was rather naively expecting the ST example code to work properly.
You don't need as many breakpoints when the program execution is consistent allowing you to keep moving the breakpoint(s) to find the problem.