Reputation: 51
When I debug my C++ program, I set a breakpoint on the main
function. When the program starts running, it seems to have skipped several lines of source before the line at which it stops. What's the problem?
Upvotes: 1
Views: 1739
Reputation: 21269
You seem to have symbols for your program, as GDB happily reads them. However, do you have the source in the original place or are you perhaps debugging on a different machine?
What does:
info source
give you when you enter it on the command prompt? It should give you something along the lines of:
(gdb) info source
Current source file is hello.c
Compilation directory is /home/username/source
Located in /home/username/source/hello.c
Contains 7 lines.
Source language is c.
Compiled with DWARF 2 debugging format.
Includes preprocessor macro info.
if GDB has debug symbols and source available.
From the output, however, it looks like this part should be fine, so caf is likely right that this is about the optimization level of your compiler.
Keep in mind that this is the very reason for debug versus release settings. During development you'll perhaps want -O0
or -O1
combined with -ggdb -g3
if you're using GCC to compile. For other compilers the settings may be different. For a release you'll probably want to use the highest safe optimization value (see this link), -O2
for gcc
or -O3
if you are using one of the widely used architectures and aren't afraid of nasty surprises.
Either way if you are serious about software development and consequently debugging, you should learn the very basics of the assembly language for your target CPUs. Why? Because sometimes the optimizer, especially in GCC, goes haywire and does stupid things even when you tell it to not trust your code, such as with -fno-strict-aliasing
. I've encountered cases where it would happily use instructions on a SPARC which are supposed to be used only on aligned data, but there was no guarantee that the data we gave it was aligned. Anyway, it's the very reason Gentoo recommends -O2
instead of any higher value for optimization. If you don't know why an assembly instruction does what it does or why your program does something silly and you can't take the magnifying glass and step down to the assembly level, you'll be lost.
As pointed out by caf you can use set disassemble-next-line on
to see the disassembly at the current program counter if you are using GDB 7.0 or newer. On older GDB versions you may resort to the trusty old display
command:
disp/i $pc
which sets an automatic display for the program counter ($pc
). Perhaps a better and visually more appealing alternative, especially if you have a lot of screen estate, is to use layout asm
and layout regs
combined in GDB. See the following screen shot:
Upvotes: 2
Reputation: 239041
Your program is probably compiled with optimisation enabled, which means that the lines of source are not necessarily sequentially translated into machine code. Under optimisation, the execution of different parts of the source code can be re-ordered and interleaved - this is likely what you're seeing.
If you want to step through your source code in a simple, sequential line-by-line manner you will need to compile with no optimisation (-O0
).
Alternatively, if you understand machine code you can use:
set disassemble-next-line on
which will show you the disassembly of the code that the debugger is stopped on alongside the source code line it belongs to.
Upvotes: 4