c++ - 如何查看 GDB 中自动变量的内存地址?

标签 c++ gdb

跟进

嗯,我不确定我做的是否正确。 感谢迄今为止的所有帮助

我之前的话题: Is this really the address

我正在制作新线程,因为这确实是一个单独的问题,而且是核心问题。

请多多包涵,谢谢。


让我重申一下我的目标:

我希望能够查看每个变量的内存地址(我们知道程序的入口地址,并且我们知道在读取汇编代码时预留了多少字节)。假设我们有以下源代码:

源代码

int main()
{ 
   int a = 15;
   int b;
   int c;
   b = c;
   c = c+1;
return 0;   
}

我们应该可以找出变量a和c的地址,以及这些内存地址中的值。

使用 gdb layout asm 我得到了这个

│0x80483f4 <main()>      push   %ebp                                              │
   │0x80483f5 <main()+1>    mov    %esp,%ebp                                         │
   │0x80483f7 <main()+3>    sub    $0x10,%esp                                        │
   │0x80483fa <main()+6>    movl   $0xf,-0x4(%ebp)                                   │
   │0x8048401 <main()+13>   mov    -0x8(%ebp),%eax                                   │
   │0x8048404 <main()+16>   mov    %eax,-0xc(%ebp)                                   │
   │0x8048407 <main()+19>   addl   $0x1,-0x8(%ebp)                                   │
   │0x804840b <main()+23>   mov    $0x0,%eax                                         │
   │0x8048410 <main()+28>   leave                                                    │
   │0x8048411 <main()+29>   ret                                                      │
   │0x8048412               nop      


// the statement int a = 15 is in the address 0x80483fa
// I want to get the value 15
x/w 0x80483fd     <== this will print 15

但这对我来说没有意义,因为根据我的记忆,变量应该在 ebp - 0x10 中,对吗?

// the starting address of the program is 0x80483f4
// minus 0x10 we get 0x80483E4
x/w 0x80483E4    <== will print a big number

// Since b = c, I should be able to get that as I decrement, but no luck

我不认为我知道我在做什么...?一方面,自动变量在程序终止后立即被销毁......

PS:调试的时候真的不会用cout,printf,断点,watcher。

所以执行 print $ebp 将不起作用,因为没有事件寄存器(记住程序终止 - 没有断点!)。所以诸如 info locals、info registers 之类的命令不可用。

我一整天都在试图弄清楚发生了什么。我真的很感谢所有的帮助,我期待得到更多。谢谢。

我该怎么办??我需要查看变量 a、b、c 的值。如何才能做到这一点?

非常感谢。


不是真正的家庭作业,而是类讨论。

最佳答案

这些变量没有一个特定的内存位置。它们是堆栈变量。所以你不能依赖它们在程序终止后在内存中,因为它们在创建它们的函数返回后被认为超出范围,允许它们所在的地址被重新用于存储其他内容。

假设您有一个函数,其源代码如下所示:

int foo(int x) {
    int y = x;
    if (y == 0) {
        return 0;
    }
    return foo(x-1)+1;
}

如果调用 foo(1),变量 y 将存在于两个不同的内存地址,一个对应为两个嵌套调用创建的两个堆栈帧中的每一个foo(foo(1)foo(0))。如果您调用 foo(10),将有 11 个 y 实例,每个实例拥有不同的值并位于不同的内存地址。

如果不使用断点,那么所有意图和目的的变量都不存在。它们仅在程序运行时分配存储空间,并且当前堆栈包含来自它们所在函数的帧。您无法在事后抓取它们(核心转储除外,这实际上是一种断点形式)。

总结:如果您不在程序运行时对其进行分析,无论是通过中断调试器还是通过添加一些将打印/预留值的代码,您都无法检查堆栈变量。这些是堆栈变量。如果您必须让它们成为单实例,则应通过将它们移到函数范围之外来使它们成为堆分配的全局变量。

关于c++ - 如何查看 GDB 中自动变量的内存地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7624246/

相关文章:

c++ - 数组与 0 个元素对齐

arrays - 如何在 gdb 中检查这个数组的这个切片?

emacs - 在 Emacs 远程使用 GDB 进行调试

python - 无法在 macOS 上使用 gdb 调试 tensorflow

使用 GDB 远程调试器时,linux 系统调用永远不会返回

c++ - 如何用Ceres解决大规模非线性优化问题?

C++从左向右重载[]

c++ - 使用 C++ boost 库的按位运算

C++ QList 常量正确性

gdb - 为什么我的 GDB 批处理模式退出状态总是 0?