What was the optimization level?
It is very hard to say which flaws are in GCC vs. GDB vs. the debugging info formats that they must work with, but the symptoms described by the OP are fairly common and with increasing optimization levels those symptoms become far more common than "correct" behavior.
First, you cannot assume that the actual sequence of operations in the generated code is the same as in the source code. Whenever changing the sequence of operations would not change any defined
behavior of the code, the compiler is free to change that sequence of operations. So the debugger might be showing you the correct source line, meaning the actual operations (or parts of them) occur in the sequence you see with the debugger rather than the sequence of the source code.
Second, actually more common in my experience, the association of ip value to source line understood by the debugger is often simply wrong. I don't know whether that is the fault of the compiler writing debug info or the debugger reading it. Such cases are very obscure situations when all optimizations are disabled, but become common at -O2 or -O3.
If you aren't a skilled asm programmer, you usually would have no way to distinguish operations happening out of source sequence vs. gdb simply wrong about the line number. I am a skilled asm programmer and I debug a lot of optimized code, so I have needed to understand that distinction quite often.
Originally Posted by ta0kira
Blank space shouldn't matter.
I agree. None of the problems I described above involve blank lines. That is a fact I normally use diagnostically as follows:
Frequently, the source line understood by gdb for an ip value is the wrong non blank line. That usually means one of the issues I described above.
Frequently, the source line understood by gdb for an ip value is not just the wrong line, but a blank line. So far as I understand, that universally indicates the source code is out of sync with the debug info (in Linux the debug info typically stays together with the binary, so that means this binary wasn't built from that source). Mistakes, optimizations, etc. in GCC or GDB that miss-associate ip values with source lines do not associate ip values with blank source lines.
So does gdb always point to a non blank line in the source? Or sometimes to a blank line?