我有一个 C++ 程序,正在尝试使用 GDB 进行调试。我正在通过优化来构建它,并且经常遇到我想要调试类似以下内容的情况:
int newVar = someArray[thing1 + thing2];
但是,GCC 很聪明,并且对代码进行了大量优化。也许那时只是中间thing1 + thing2
被存储,与个人thing1
和thing2
已被覆盖。当我要求 GDB 打印 thing1
时,我得到<value optimized out>
。 thing2
相同.
所以我有两个问题:
如果我要求 gdb
p thing1 + thing2
,它是否足够聪明,能够意识到该中间体当前存储在寄存器中?或者它只是尝试天真地评估表达式,意识到它使用的两个变量都已优化,然后失败?如何获取执行中任何给定点实际可用的表达式求值中间体的列表?如果它正在存储
&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/