Wor*_*eek 6 c optimization gdb dwarf
在gdb中,我如何发现显示为优化输出的变量的值?大概该值存储在一个寄存器中,我如何找出哪个?给出这个简单的程序(从下面的网站复制)。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int foo = rand();
printf("foo is %d\n", foo++);
return foo;
}
Run Code Online (Sandbox Code Playgroud)
进行优化编译。
gcc -O3 -g optimized.c
gdb a.out
Run Code Online (Sandbox Code Playgroud)
运行GDB
(gdb) print foo
$1 = <optimized out>
Run Code Online (Sandbox Code Playgroud)
到底是怎么回事?该变量foo必须存在于某处,但如何找到它的值或将其存储在何处?
我找到了一个页面,该页面详细说明了DWARF调试信息如何用于优化代码https://undo.io/resources/gdb-watchpoint/build-for-debug-in-gdb。使用那里的建议,我最终可以找到分配给foo它的寄存器,但是这很痛苦。
如何让gdb告诉我要观看哪个寄存器?
我尝试使用-g3进行编译,但这没有帮助。
我在gdb中尝试了一些命令也没有帮助。
ptype foo
info locals
print &foo
Run Code Online (Sandbox Code Playgroud)
变量 foo 必须存在于某处
不必要。如果方便的话,编译器可以存储从变量派生的foo+1一些值(例如或)。foo-23
在这种特殊情况下,由于foo被传递给printf,如果您知道特定平台的调用约定,您可以在寄存器或堆栈中发现它。
但我如何找到它的值或它存储在哪里?
目前,调试优化代码需要大量技能、ABI 知识以及所使用的汇编指令。
问题在于,出于调试目的,编译器很少通过寄存器内和内存中的位置准确跟踪值,因为这样做非常困难。
调试器还必须正确解释编译器生成的调试信息,这也不是一个简单或没有错误的过程。
GCC 最近在该领域取得了很大进步。在 Linux x86_64 上使用gcc (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)Fedora 31,我观察到:
(gdb) start
Temporary breakpoint 1 at 0x401050: file t.c, line 6.
Starting program: /tmp/a.out
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.30-5.fc31.x86_64
Temporary breakpoint 1, main () at t.c:6
6 int foo = rand();
(gdb) n
7 printf("foo is %d\n", foo++);
(gdb) p foo
$1 = 1804289384
(gdb) p &foo
Can't take address of "foo" which isn't an lvalue.
(gdb) c
Continuing.
foo is 1804289383
[Inferior 1 (process 2696) exited with code 0150]
(gdb) q
Run Code Online (Sandbox Code Playgroud)
在这里您可以看到gcc描述了寄存器中的位置foo(或非内存的其他位置),并且GDB能够打印几乎的值foo。
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |