【问题标题】:How do I view the value of an <optimized out> variable in C++?如何在 C++ 中查看 <optimized out> 变量的值?
【发布时间】:2012-02-25 18:39:15
【问题描述】:

我正在使用 gdb 调试 C++ 程序。

我有这个代码:

int x = floor(sqrt(3));

我想查看 x 的值。但是,gdb 声称 x 是“”。如何查看 x 的值?我应该更改我的编译器标志吗?

【问题讨论】:

标签: c++ gdb g++


【解决方案1】:

在高优化级别上,编译器可以消除中间值,正如您在此处看到的。有多种选择:

  • 您可以降低优化级别,使调试器更容易跟踪事物。 -O0 肯定可以工作(但会慢很多),-O1 也可以工作。
  • 您可以添加一些显式打印语句来记录输出值。
  • 您通常也可以强制编译器保留此特定值,方法是将其设为 volatile(但请记住,完成后不要将其设为 volatile!)。但是请注意,由于控制流在优化代码中也会发生变化,即使您可以看到变量的值,当您查看有问题的变量。

【讨论】:

  • 您通常还可以反汇编函数并推断“优化输出”变量真正驻留在哪个寄存器中,然后打印该变量。正在进行开发工作以使 GCC 发出足够详细的调试信息,以便 GDB 将来能够为您执行此操作。
  • @EmployedRussian,如果变量确实存在,这可以工作,但计算变量的实际工作可能会被消除,所以它不适用于所有情况。
  • 局部变量也可以只存在于寄存器中。 gcc 可以以这种方式优化您的代码 - 另一个可能导致无法查看变量的原因。有关如何查看寄存器变量的信息,请参阅此答案:stackoverflow.com/a/1354762/350875
  • 即使使用-O0,几乎每个变量都对我使用 g++ / gdb 进行了“优化”。使用-g -fcoroutines -fno-inline -O0 -pthread -std=gnu++2a编译。
【解决方案2】:

如果您不能或不想禁用优化,则可以尝试将变量声明为 volatile。 这通常足以让您的编译器在最终代码中保留变量。

或者,在最近的 GCC 版本中,您可以仅对一个函数禁用优化,如下所示:

void my_function() __attribute__((optimize(0)))
{
  int x = floor(sqrt(3));
}

【讨论】:

  • 对我来说,这个属性是未定义的。当我改用optnone 时,变量无论如何都得到了优化(clang 3.8)。
【解决方案3】:

创建您自己的“全局变量”并将优化后的变量打印到此全局变量中。确保在完成调试后删除这些由您创建的全局变量!

【讨论】:

    【解决方案4】:

    使用逆向调试时,尽量往后退一步靠近变量的定义点

    如图所示:What does <value optimized out> mean in gdb? 在函数内部经常出现这样的情况:

    • 在函数开始时,可​​以观察变量的值
    • 然而,在函数接近尾声时,变量越来越有可能变成&lt;optimized out&gt;,因为由于优化,它只存储在寄存器中,而不是存储在堆栈上的内存中。所以当不再需要它时,寄存器很可能会被另一个变量重用和覆盖,然后调试元数据会通知 GDB。

    因此,如果您使用某种reverse debugging such as Mozilla rr,一旦您尝试一次,您就会一直这样做,那么一个不错的选择是尝试退回到更接近定义/上次使用的点reverse-finish + reverse-next 的变量,看看你是否可以在那里观察到它。

    这可以通过What does <value optimized out> mean in gdb? 中显示的示例代码具体观察到,并为我节省了几次,尤其是当运行未优化的程序导致到达兴趣点需要很长时间时(考虑到效率极低,这并不奇怪由-O0 生成的程序集,如该答案所示)。

    【讨论】:

      猜你喜欢
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-24
      • 2012-08-15
      • 1970-01-01
      • 2017-06-07
      相关资源
      最近更新 更多