GDB cannot step over empty while(1) loop

Bug #1401565 reported by Liviu Ionescu on 2014-12-11
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
GNU ARM Embedded Toolchain
Undecided
Terry Guo

Bug Description

Probably related to https://bugs.launchpad.net/gcc-arm-embedded/+bug/1395077

Attempts to single step an empty loop always fail, the loop is entered but not exited after one iteration.

NB: The same scenario works perfectly well with the 386 GCC on Linux, single stepping empty loops behave as expected.

I tried with 4.8 and the latest 4.9, and the problem is the same. I also tried with -O0 vs -Og, -g3, -dwarf-4 vs toolchain default and no difference.

I encountered the problem when using Eclipse, but manually starting the GDB client and entering 's' or 'n' showed the same behaviour (entering the infinite loop).

Switching Eclipse to assembly mode works, only the C debug information seem not appropriate.

When you test be sure you have some code between the beginning of main and before the loop, otherwise if you place a breakpoint at main, this will be in fact a breakpoint inside the loop, and single stepping will halt due to the breakpoint. A more general rule would be to do not place a breakpoint on the instruction before the empty loop.

If you need more details on how to reproduce the problem, please let me know.

Regards,

Liviu

p.s. In case you wonder why someone would single step an empty loop, please be aware that most project templates generate such constructs, where people should fill in the actions. Most people try a debug session with the empty loop, and are very confused by the debugger not single stepping properly.

Alexander Graf (alibabashack) wrote :

Could you add code of the working linux PC scenario, please? Sorry, but I do not believe it is working. GDB will not change the program flow by stepping. "step over" means it will halt when the instruction at the line you step over has finished and the control flow reaches the next line. Since a line with an infinite loop is never done, step over will simply not work.

As a workaround you could use a boolean guard, which you modify while debugging to break out of the loop.

Changed in gcc-arm-embedded:
status: New → Opinion
Liviu Ionescu (ilg) wrote :

> Sorry, but I do not believe it is working.

hmmm... you are right, I retested (both on Ubuntu and OS X) and indeed it is not working, it is looping continuously.

the sequence used was:

int main()
{
  int i=1;
  while(1)
  {
  }
}

I'll check tomorrow with my colleague who conducted the initial tests on Linux, to see his configuration.

Terry Guo (terry.guo) on 2014-12-15
Changed in gcc-arm-embedded:
assignee: nobody → Terry Guo (terry.guo)
Liviu Ionescu (ilg) wrote :
Download full text (8.4 KiB)

I checked with my friend and he made a mistake in the initial tests, he placed a breakpoint in the loop, and this changed step behaviour.

Without breakpoint, the problem affects Ubuntu too.

---

However, we conducted some more tests on ARM (using a STM32F103RB), and during what appears to be an endless loop entered after issuing the 's' command, is in fact a lot of activity between the GDB client and the GDB server.

Below is an excerpt from the J-Link GDB server log:

03-00000000-00-00055137-0019: Performing single step...
02-00000000-00-00055137-0080: TDD3F9700 055:137 JLINK_Step() -- Read from flash cache (2 bytes @ 0x080006BC) -- Simulated returns 0x00 (0000ms, 1574ms total)
02-00000000-00-00055137-0047: TDD3F9700 055:137 JLINK_IsHalted() returns TRUE (0000ms, 1574ms total)
02-00000000-00-00055137-0054: TDD3F9700 055:137 JLINK_ReadReg(R15 (PC)) returns 0x080006BC (0000ms, 1574ms total)
02-00000000-00-00055137-00A2: TDD3F9700 055:137 JLINK_ReadMem (0x080006BC, 0x0002 Bytes, ...) -- Read from flash cache (2 bytes @ 0x080006BC) - Data: FE E7 returns 0x00 (0000ms, 1574ms total)
02-00000000-00-00055137-005C: TDD3F9700 055:137 JLINK_FindBP(Addr = 0x080006BC) returns 0x00000000 (0000ms, 1574ms total)
02-00000000-00-00055137-0048: TDD3F9700 055:137 JLINK_GetNumWPs() returns 0x00 (0000ms, 1574ms total)
03-00000000-00-00055137-0022: ...Target halted (PC = 0x080006BC)
01-0000000F-00-00055137-0007: $T05#b9
00-0000000F-00-00055137-0005: $g#67
03-00000000-00-00055137-0015: Reading all registers
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R0) returns 0x00000001 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R1) returns 0x080006D4 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R2) returns 0x080006D4 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R3) returns 0x00000001 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R4) returns 0x200006B4 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R5) returns 0x2000070C (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R6) returns 0x2000070C (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R7) returns 0x20004FA8 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R8) returns 0x00000000 (0000ms, 1574ms total)
02-00000000-00-00055137-004E: TDD3F9700 055:137 JLINK_ReadReg(R9) returns 0x00000000 (0000ms, 1574ms total)
02-00000000-00-00055137-004F: TDD3F9700 055:137 JLINK_ReadReg(R10) returns 0x00000000 (0000ms, 1574ms total)
02-00000000-00-00055137-004F: TDD3F9700 055:137 JLINK_ReadReg(R11) returns 0x00000000 (0000ms, 1574ms total)
02-00000000-00-00055137-004F: TDD3F9700 055:137 JLINK_ReadReg(R12) returns 0x20000628 (0000ms, 1574ms total)
02-00000000-00-00055137-0054: TDD3F9700 055:137 JLINK_ReadReg(R13 (SP)) returns 0x20004FA8 (0000ms, 1574ms total)
02-00000000-00-00055137-004F: TDD3F9700 055:137 JLINK_ReadReg(R14) returns 0x08000357 (0000ms, 1574ms total)
02-00000000-00-00055137-0054: TDD3F97...

Read more...

Vojtech Musil (st.renegade) wrote :

Hello,

I would like to vote for a bug fix, as I was facing exactly the same issue. It took me two days to find out, whether the issue is in my compiler, debugger, source code etc. after I found this thread, which confirmed my concerns.

Never faced similar behaviour on IAR or Keil. This does not happen just on an infinite loop, but also on finite empty loop. My source code:

<code>
void main (void)
{
  /* Some initialization here */
  ...

  while (1)
  {
    GPIO_TogglePin(...);

    for (uint32_t i = 0U; i < 0xFFFFFU; i++)
    {
      ;
    }
  }
}
</code>

I would expect after stepping on the for loop to perform one iteration and end on the for loop again, however this is not the case and the gdb gets crazy. Luckily it was possible to stop it with ctrl+c, however not always. Sometimes I had to stop the gdb server.

After putting an empty instruction into the loop:

<code>
for (uint32_t i = 0U; i < 0xFFFFFU; i++)
{
  __asm("NOP");
}
</code>

the debugger was able to perform a step/next and stopped on the __asm("NOP") instruction.

I'm using openSDA v2.2 with a J-link debugger atop of this.

I hope it will be fixes, as there is no indication why this is happening.

Thanks and have a nice day,
ST Renegade

Liviu Ionescu (ilg) wrote :

Thank you @st.renegade, perhaps if there are multiple voices, there will be someone listening.

Vojtech Musil (st.renegade) wrote :

You are welcome! In my opinion, it's a major issue as there is absolutely no indication, what is causing such behavior! And also continuing and stepping behaves differently. However it's very easy to get into such a situation and the only possibility is to ctrl-c or even stop the server! As said before, sometimes I was not able to stop the gdb!

I'm wondering no one takes care and honestly I'm a bit pessimistic as you reported it two years ago and since then there was no action, which is sad.

ST Renegade

Hi,

Speaking as one of the developer of this toolchain I would like to make it clear that we do care about bug reports people submit and we try our best to solve them. In this case we appear to have dropped the ball at some point and I appreciate the ping together with a confirmation that people are still encountering this bug.

One important point I would like to make is that given our limited resources we have to prioritize the bug report we make based on (i) how serious it is, (ii) how many people are affected (ie. is it an edge case?) and (iii) how complex is the bug fix. For instance the compiler generating wrong code would be deemed more critical but a bug like this would almost certainly take priority over better optimization.

Best regards.

Liviu Ionescu (ilg) wrote :

Thank you Thomas for your comments.

I understand the need to prioritize actions. As Vojtech said, this bug, although apparently benign, has a large impact, during early development lots of projects reach such loops, and for beginners the behaviour is absolutely confusing.

Can you estimate when it is reasonably to expect a fix?

Hi Liviu,

I'm afraid I cannot. We are already working on a few tickets at the moment and we usually try to complete ongoing tickets before moving on to new ones so as not to loose too much time in the context switch. Note that I've opened a ticket internally today so it should be given the appropriate consideration now.

As usual, we will update the status of this bug report as we start working on it.

Best regards.

Prakhar Bahuguna (prakhar) wrote :

Hi Liviu, as this bug appears in an upstream trunk build of gdb and can be reproduced on the x86 platform as well, I have opened a ticket on the upstream bug tracker for you: https://sourceware.org/bugzilla/show_bug.cgi?id=21221

Changed in gcc-arm-embedded:
status: Opinion → Won't Fix
Liviu Ionescu (ilg) wrote :

Thank you, Prakhar.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.