1

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

说明问题的屏幕截图

4

2 回答 2

4

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

如果您想以简单的、顺序的逐行方式逐步执行源代码,则需要在不进行优化的情况下进行编译 ( -O0)。

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

set disassemble-next-line on

这将向您显示调试器在其所属的源代码行旁边停止的代码的反汇编。

于 2013-04-24T05:53:46.217 回答
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对于其他编译器,设置可能不同。对于一个版本,您可能希望使用最高的安全优化值(请参阅此链接),-O2或者gcc如果-O3您正在使用一种广泛使用的架构并且不害怕令人讨厌的意外。

无论哪种方式,如果您认真对待软件开发并因此进行调试,您应该为您的目标 CPU 学习汇编语言的基础知识。为什么?因为有时优化器,尤其是在 GCC 中,即使你告诉它不信任你的代码,也会出现问题并做一些愚蠢的事情,例如使用-fno-strict-aliasing. 我遇到过这样的情况,它很乐意在 SPARC 上使用指令,这些指令应该只用于对齐的数据,但不能保证我们给它的数据是对齐的。无论如何,这正是Gentoo 推荐-O2的原因,而不是任何更高的优化价值。如果你不知道为什么汇编指令会做它所做的事情,或者为什么你的程序会做一些愚蠢的事情,并且你不能拿着放大镜并降级到汇编级别,那么你'

如何在 GDB 中查看汇编代码

正如caf 所指出的,set disassemble-next-line on如果您使用的是 GDB 7.0 或更高版本,您可以使用在当前程序计数器处查看反汇编。在较旧的 GDB 版本上,您可以使用可信赖的旧display命令

disp/i $pc

它设置程序计数器 ( $pc) 的自动显示。也许一个更好、视觉上更吸引人的替代方案,特别是如果你有很多屏幕空间,是在 GDB中使用layout asm和组合。layout regs请参阅以下屏幕截图:

布局 asm 和 regs 在 GDB 中组合

于 2013-04-24T15:35:21.007 回答