我正在64位Linux CentOS 5.7服务器上用gcc44和gdb调试一些ANSI C代码。
在我的一个函数的中间,我有一个循环,循环192次(循环中有2行代码)。如果我在for循环的开始处设置了带断点的gdb,我可以遍历for循环所有192次并退出for循环并继续进入for循环之后的下一行代码。这都是使用“s”或“n”逐步执行gdb中的代码。一切正常。
现在,我没有使用“s”或“n”单步执行for循环来获取for循环后的下一行代码,而是启动gdb,然后在结束后的行中设置断点。 for循环。如果我然后在gdb中按“c”,它会给我“程序正常退出”。我希望gdb在for循环之后停在位于代码行上的这个断点处。 (!?)
作为另一个实验,我了解到gdb在紧跟在for循环之后的代码行之后成功停止在任何行上设置的断点。
也许其他人已经通过这样的问题来判断这个经验(其中还有2个附加参考文献):
gdb error "Program exited normally"
它在gdb中是可重复的。如果没有深入研究相关代码,任何人在此之前都会看到这种行为和/或知道我能检查什么?
编辑1
如果我在断点行上包含printf("\n");
以解决上述问题,将该行上的内容移动到此printf代码下面的一行,那么一切正常(例如gdb在printf行停止) 。
我甚至可以在之前有问题的代码行上成功设置断点,现在是printf行之后的下一行。怪异!
答案 0 :(得分:1)
你的编译器正在玩弄你。
嗯,不是真的,但它并没有完全符合您的怀疑。
编译器的第一个主要概念是顺序地将C的每一行转换为一个或多个汇编指令,并以与C代码相同的顺序执行汇编。
实际上,编译器将重组事物以优化速度或空间。如果一条指令被认为对程序状态没有净影响,则可以完全删除它。因此,当你告诉GDB在该行上中断时,那么......没有汇编指令,调试信息指向C行。