使用GDB调试C ++程序时,“next”命令似乎跳过了源代码行

时间:2013-04-24 05:40:25

标签: c++ debugging gdb

当我调试我的C ++程序时,我在main函数上设置了一个断点。当程序开始运行时,它似乎在它停止的行之前跳过了几行源。有什么问题?

Screenshot illustrating the problem

2 个答案:

答案 0 :(得分:4)

您的程序可能在启用优化的情况下编译,这意味着源代码行不一定按顺序转换为机器代码。在优化下,源代码的不同部分的执行可以重新排序和交错 - 这可能是你所看到的。

如果您希望以简单,顺序的逐行方式逐步执行源代码,则需要进行编译而不进行优化(-O0)。

或者,如果您了解机器代码,则可以使用:

set disassemble-next-line on

将显示调试器停止的代码的反汇编以及它所属的源代码行。

答案 1 :(得分:2)

您似乎有自己的程序符号,因为GDB很乐意阅读它们。但是,您是否在原始位置拥有源代码,或者您是否可以在其他计算机上进行调试?

做什么:

info source

在命令提示符下输入时给你?它应该给你一些东西:

(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.

如果GDB有调试符号和源可用。

然而,从输出中看,这部分应该没问题,所以caf可能是正确的,这与你的编译器的优化级别有关。

请记住,这是调试与发布设置的原因。 在开发过程中如果您正在使用GCC进行编译,那么您可能希望-O0-O1-ggdb -g3结合使用。对于其他编译器,设置可能不同。 对于发布,您可能希望使用最高安全优化值(请参阅this link),-O2用于gcc-O3正在使用一种广泛使用的架构,并不害怕令人讨厌的惊喜。

无论哪种方式,如果您认真对待软件开发并进行调试,您都应该了解目标CPU的汇编语言的基础知识。为什么?因为有时优化器,尤其是GCC中的优化器,即使你告诉它不相信你的代码,例如使用-fno-strict-aliasing,它也会变得愚蠢并做蠢事。我遇到过这样的情况,它会愉快地使用SPARC上的指令,这些指令只能用于对齐的数据,但不能保证我们给它的数据是对齐的。无论如何,这是Gentoo recommends -O2而不是任何更高的优化值的原因。如果你不知道为什么装配说明会做它的功能,或者你的程序为什么会做一些愚蠢的事情而且你不能拿放大镜并下降到装配级别,你就会迷失方向。

如何在GDB中查看汇编代码

作为pointed out by caf,如果您使用的是GDB 7.0或更高版本,则可以使用set disassemble-next-line on查看当前程序计数器的反汇编。在较旧的GDB版本中,您可以使用可靠的旧display command

disp/i $pc

设置程序计数器的自动显示($pc)。也许更好,视觉上更吸引人的选择,特别是如果你有很多屏幕空间,就是在GDB中使用layout asmlayout regs。请参见以下屏幕截图:

layouts asm and regs combined in GDB