像 GDB 这样的调试器如何处理像 ICC/GCC 这样的编译器所做的代码优化?
How does a debugger like GDB handle code optimizations made by compilers like ICC/GCC?
假设我们正在编译程序以使用 ICC 创建一个进程二进制文件.. 稍后当它在机器上执行时我们想要调试它..(非常常见的进程.. 对于如此琐碎的解释感到抱歉)。 . GDB 如何处理 ICC 执行的代码优化?
在编译器优化方面,gdb 通常遵循 GIGO 原则。也就是说,编译器将它所做的描述发送到调试信息中,gdb 读取并解释它们。因此 gdb 受编译器的支配;事实上,不同编译器生成的调试信息之间存在真正的质量差异。
用户 运行 加入了其中的一些。这不是一个详尽的列表,但我认为它涵盖了常见的列表。
有时打印一个变量会得到 <optimized out>
。这通常发生在局部变量上,这意味着编译器发出了调试信息,指出变量存在,但没有关于如何恢复变量值的调试信息。自 "VTA" 补丁发布以来,GCC 已更加努力地在这些情况下发出巧妙的调试信息,但即使有了这些补丁,也并非总能做到。
有时内联意味着回溯看起来很奇怪。这里 GCC 发出 DWARF 很好地描述了内联决策;但还有其他情况,如部分内联,可能会造成混淆。
优化通常会导致 gdb 中的非线性步进。当属于一行的指令在属于其他行的指令之前或之后移动时,就会发生这种情况。据我所知,没有人真正努力解决这个问题,用户的答案只是调试优化代码时必须习惯的事情。
我不知道你的编译器在这些情况下做了什么。如果您对 DWARF 有一些了解,编写小测试用例并检查生成的调试信息并不难。
假设我们正在编译程序以使用 ICC 创建一个进程二进制文件.. 稍后当它在机器上执行时我们想要调试它..(非常常见的进程.. 对于如此琐碎的解释感到抱歉)。 . GDB 如何处理 ICC 执行的代码优化?
在编译器优化方面,gdb 通常遵循 GIGO 原则。也就是说,编译器将它所做的描述发送到调试信息中,gdb 读取并解释它们。因此 gdb 受编译器的支配;事实上,不同编译器生成的调试信息之间存在真正的质量差异。
用户 运行 加入了其中的一些。这不是一个详尽的列表,但我认为它涵盖了常见的列表。
有时打印一个变量会得到
<optimized out>
。这通常发生在局部变量上,这意味着编译器发出了调试信息,指出变量存在,但没有关于如何恢复变量值的调试信息。自 "VTA" 补丁发布以来,GCC 已更加努力地在这些情况下发出巧妙的调试信息,但即使有了这些补丁,也并非总能做到。有时内联意味着回溯看起来很奇怪。这里 GCC 发出 DWARF 很好地描述了内联决策;但还有其他情况,如部分内联,可能会造成混淆。
优化通常会导致 gdb 中的非线性步进。当属于一行的指令在属于其他行的指令之前或之后移动时,就会发生这种情况。据我所知,没有人真正努力解决这个问题,用户的答案只是调试优化代码时必须习惯的事情。
我不知道你的编译器在这些情况下做了什么。如果您对 DWARF 有一些了解,编写小测试用例并检查生成的调试信息并不难。