【问题标题】:How does GDB know optimized out local variable values?GDB 如何知道优化的局部变量值?
【发布时间】:2022-07-02 07:36:42
【问题描述】:

当我用gcc -g -O1 t.c编译以下代码时

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 4;

    return 0;
}

GCC 优化所有未使用的局部变量。这可以通过 GDB disassemble 命令看到,只剩下return 0 的指令:

(gdb) disassemble main 
Dump of assembler code for function main:
   0x0000000000401106 <+0>: mov    $0x0,%eax
   0x000000000040110b <+5>: ret    
End of assembler dump.

但是,GDB 不知何故知道 C 代码中的变量值

(gdb) info locals 
a = 1
b = 2
c = 3
d = 4

如果生成的汇编代码中不存在这些值,GDB 如何知道这些值?

【问题讨论】:

  • 调试符号包含在可执行文件中,除非它们在构建过程中被删除。这就是 GDB 了解任何符号的方式。当您编译 C 时,所有符号(函数名、变量等)都会消失,因为它们只是为了帮助您编程。任何调试器都知道的唯一方法是它们包含在可执行文件的调试信息中。
  • @siride 您可以将其发布为问题的答案。
  • 如果您通过gcc -S 或在 godbolt.org 上查看生成的汇编代码,您会看到类似.section .debug_info,"",@progbits 的内容,并且在该部分中,虽然通常不是人类可读的,但您可以发现信息。
  • @ks1322:有什么意义?如果你的程序不是那么简单,而是包含了一个像arr[ i + a ] 这样的表达式。您可以将该表达式复制粘贴到 GDB 中,如果它具有来自调试符号的 a 的值,以及有关 iarr 在运行时位于程序内存中的位置的实际信息,则可以对其进行正确评估。
  • @ikegami 这就是彼得所说的。这些优化的变量可能是表达式的一部分,如果它们没有被优化出来,了解它们会是什么是很有用的。

标签: c assembly gdb x86-64


【解决方案1】:

值已优化的消息并不意味着变量已优化。这意味着确定变量值所需的信息,可能是因为它被覆盖或重用以保存不同的变量。这是发生这种情况的一个例子:

#include <stdio.h>

int main(int argc, char **argv) {
    int x = argc + 42;
    getchar();
    return 0;
}

gcc -g -O3 编译它。如果您执行start,然后执行step,您将能够执行print x 并查看它的值,即使它从未由程序实际计算过,因为调试信息说明了该值是如何计算的。但是,如果您随后执行next 并按Enter 额外时间让getchar 返回,现在print x 将告诉您该值已优化。这是因为程序可以访问的argc 的唯一副本是在rdi 中,它被getchar 破坏了,并且编译器没有费心先保存它的旧值,因为程序之后不需要它.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多