Strange behaviour debugging STM32F411

Sysprogs forums Forums VisualGDB Strange behaviour debugging STM32F411

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #28922
    DonMilne
    Participant

    I have been using VisualGDB with several STM32F103 variants for a few years now, I’m very happy with it. I recently got myself an STM32F411 “WeAct Black Pill V2.0” board to play with, thinking I would check out more advanced versions of the STM32. I’ve started by porting my own basic template “led blink” app to the new MCU.

    I’m come across an odd behaviour while debugging, see this code:

    /*................................................................*/
    
    #define ON_TIME_MS  450
    #define OFF_TIME_MS 50
    
    static UI16 LED_override,LEDstate;
    
    static void
    LED_Blink_Func(void)
    {
       static BYTE lstate;
       UI16 ms = OFF_TIME_MS;
       lstate ^= 1;
       if (lstate&1) {
          /* BREAKPOINT 1 SET HERE */ PIO_ClearOutput(PIN_LED);
       } else {
          /* BREAKPOINT 2 SET HERE */ PIO_SetOutput(PIN_LED);
          ms = ON_TIME_MS;
       }
       Thread_Sleep(ms);
    }
    
    /*....................................................................*/

    Inside the debugger I was trying to verify that both branches of the “if…” statement were being exercised on alternate calls to the function.

    Sure enough, the debugger first halt on breakpoint 1, so I clicked on F10 to skip over the PIO_ClearOutput(), and I saw the LED turn on. To my astonishment however, the debugger had now stopped at breakpoint 2! And this wasn’t just a display artifact, when I pressed F10 to step over the PIO_SetOutput() call, the LED turned off again, so this looks like the debugger changed the execution path of the program. I did some more investigation and, happily, it only does this inside the debugger: it isn’t that the compiler failed to generate code for a branch where the “else” is.

    I found that if I remove breakpoint2 then stepping over the first PIO_xxx call makes control jump to the Thread_Sleep() call, which is what is supposed to happen always.

    Any idea what’s going on, and how to fix it? My own guess is that maybe the STF32F4 has a longer pipeline, perhaps the debugger “sees” the dead branch with the breakpoint and somehow thinks it has to resume execution there.

    I’m using the OpenOCD debugger, SWD(HLA) interface, genuine ST-Link v2 debug dongle. Code was built in debug mode.

    Using VisualGDB v5.5 Preview 7. Support expires on 19th Jan 2021 (amazing how the renewal date always seems to race toward me!).

    Let me know if I forgot anything.

    • This topic was modified 3 years, 8 months ago by DonMilne.
    #28924
    support
    Keymaster

    Hi,

    This can be caused by optimization, or the way gcc handles debug symbols. Please make sure the optimization is set to -O0 (and not -Og). You can also try adding asm(“nop”) in the empty if() branch. If this changes the behavior, it is a side effect of the way gcc emits symbols for empty branches.

    #28925
    DonMilne
    Participant

    Hi. Thanks for the reply.

    Optimization is indeed set to -O0 for debug builds, which this is.

    None of the branches is empty – not sure what you mean there.

    AFAICS this problem has nothing to do with the emitted code – the same code runs fine outside the debugger – the problem seems to be the debugger and how it handles breakpoints, though I’m open to being persuaded otherwise.

    • This reply was modified 3 years, 8 months ago by DonMilne.
    #28927
    support
    Keymaster

    Sorry, the line looked a bit confusing due to the comment before code.

    It’s generally hard to say what would cause this, as VisualGDB would simply pass the breakpoint commands to the underlying low-level tools and would not directly control which of the breakpoints get hit.

    If the optimization level is already set to -O0, our best advice would be to try switching to the disassembly mode, and experimenting with setting breakpoints there.

    Also the “pill” boards often come with the Chinese clones of the STM32 chips, that do often behave unpredictably. If the problem does not happen on the regular STM32 boards, it is very likely the glitch of the chip.

    • This reply was modified 3 years, 8 months ago by support. Reason: updated link
Viewing 4 posts - 1 through 4 (of 4 total)
  • You must be logged in to reply to this topic.