我有一个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优化的足够详细信息,以确定实际存储的中间体/编译器如何决定使用每个寄存器?是否有一些超级详细的多兆字节调试信息格式,我可以指示GCC生成?是否有另一个编译器/调试器对可以更好地处理这个?
如果我花费20分钟跟踪整个功能的程序集,请注意thing1
和thing2
进来的位置以及何时从中获取的内容符合{{1}的地址},我可以手动解决这个问题。但我希望调试器为我做这件事,因为编译器必须首先跟踪所有这些内容以进行优化。
答案 0 :(得分:2)
如果我问gdb到p thing1 + thing2,是否足够聪明才能意识到该中间件当前存储在寄存器中?
不,它会尝试天真的事情而失败。
如何获得执行中任何给定点实际可用的表达式 - 评估中间体列表?
你不能。
但是我希望调试器为我做这件事,因为编译器必须首先跟踪所有这些内容以进行优化。
编译器 跟踪所有这些内容,但在生成程序集后丢弃了信息。没有该信息,调试器可能无法重建它。 (嗯,理论上它可以做到,但在实践中,任何充分优化的代码都很难。)
让编译器不丢弃信息在理论上是可行的,但是不实用:产生的二进制文件太大了,我不相信当前的调试格式支持&#34;这个值复杂的表达式存储在该寄存器中。描述很好(如果有的话)。