c++ - 在 GDB 中查看 GCC 优化中间体?

标签 c++ debugging gcc optimization gdb

我有一个 C++ 程序,正在尝试使用 GDB 进行调试。我正在通过优化来构建它,并且经常遇到我想要调试类似以下内容的情况:

int newVar = someArray[thing1 + thing2];

但是,GCC 很聪明,并且对代码进行了大量优化。也许那时只是中间thing1 + thing2被存储,与个人thing1thing2已被覆盖。当我要求 GDB 打印 thing1 时,我得到<value optimized out>thing2 相同.

所以我有两个问题:

  1. 如果我要求 gdb p thing1 + thing2 ,它是否足够聪明,能够意识到该中间体当前存储在寄存器中?或者它只是尝试天真地评估表达式,意识到它使用的两个变量都已优化,然后失败?

  2. 如何获取执行中任何给定点实际可用的表达式求值中间体的列表?如果它正在存储&someArray + sizeof(int) * thing2作为中间人,我想知道这一点。 GCC 是否没有包含足够详细的有关 GDB 优化的信息,以弄清楚实际存储了哪些中间体/编译器如何决定使用每个寄存器?是否有一些 super 详细的多兆字节调试信息格式可以指示 GCC 生成?是否有另一个编译器/调试器对可以更好地处理这个问题?

如果我花 20 分钟跟踪该函数的程序集,并记下 thing1 的位置和thing2进来,当从它们派生的任何东西与 someArray 的地址相遇时,我可以手动解决这个问题。但我希望调试器为我做这件事,因为编译器必须首先跟踪所有这些东西才能进行优化。

最佳答案

If I ask gdb to p thing1 + thing2, is it smart enough to realize that that intermediate is currently stored in a register?

不,它会尝试幼稚的事情并失败。

How can I get a listing of what expression-evaluation intermediates are actually available at any given point in an execution?

你不能。

But I want the debugger to do it for me, since the compiler had to track all this stuff to do the optimization in the first place.

编译器确实跟踪了所有这些内容,但在生成程序集后丢弃了这些信息。如果没有这些信息,调试器就不可能重建它。 (嗯,理论上这是可以做到的,但实际上对于任何充分积极优化的代码来说这是非常困难的。)

让编译器不丢弃信息在理论上是可能的,但不切实际:生成的二进制文件会太大,而且我不相信当前的调试格式支持“这个复杂表达式的值存储在注册”的描述很好(如果有的话)。

关于c++ - 在 GDB 中查看 GCC 优化中间体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27003610/

相关文章:

javascript - 如何默默地记录东西而不干扰正常开发,直到我需要它

c++ - C/C++ 行的人类可读优化版本

c++ - 使用 clang 时需要自己安装所有头文件和库吗?

c++ - boost::asio signal_set 处理程序仅在捕获到第一个信号后执行,并忽略相同类型的连续信号

c++ - 将类静态成员定义放入 cpp 文件——技术限制?

c++ - 连分数

c - 为什么 Linux 中的所有系统调用都使用 "call by reference"将参数传递给内核?

c++ - 如何使用 Boost Program Options 提取已解析选项的序列?

c++ - 为什么我的 IWMPEvents 函数从未被调用?

c++ - VS2010SP1 : Project always out of date when debugging