如何查看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布局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或设置断点或监视器。
因此,打印$ ebp不会工作,因为没有活动的寄存器(记住程序终止 - 没有断点!)。所以像info locals,info寄存器这样的命令不可用。
我花了整整一天的时间试图弄清楚发生了什么事情。我非常感谢所有的帮助,我期待着获得更多。谢谢。
我该怎么办?我需要看看变量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
,每个实例都拥有不同的值并位于不同的内存地址。
如果您不使用断点,则所有意图和目的的变量都不存在。它们只有在程序运行时才分配存储空间,当前栈中包含它们驻留的函数的一个框架。你不能抓取他们postmortem(除了核心转储,这是一种形式的断点)。总结:如果在程序运行时不分析程序,可以通过中断调试程序或添加一些代码来打印/设置值,但不能检查堆栈变量。这些是堆栈变量。如果你必须让它们成为单实例,你应该通过将它们移到函数作用域之外来让它们堆分配全局变量。
感谢您的意见。我的天啊。是。你非常正确。但是从解密代码中,我们知道程序的入口地址。我们不能只减少4个字节吗?如果我们仍在运行程序,它应该是第一个局部变量的地址,int a。请更正我的术语:当我们谈论$ ebp - 0x4时,我们仍然可以使用“地址”作为“位置”的别名,对吧? – CppLearner
@JohnWong程序的入口地址是'main'函数的地址。这与'main'的堆栈帧的位置无关。 *代码*在内存中的一个地方,它使用的* data *在另一个地方(在这种情况下,在堆栈顶部)。事实并非如此,特定的函数总是将其堆栈帧放置在同一个点上;如果这是真的,则递归函数不可能存在。堆栈变量的实例不在构成函数的指令所在的位置附近。 – Borealid
@JohnWong想象一下食谱书 - “main”是饼干的食谱。 'a','b'和'c'是成分。你不会把蛋糕存放在**食谱书中。每次想要制作食谱时,都可以将它们从冰箱中取出并放在柜台上的新空间中。入口点是食谱书中的书签。计数器空间是堆栈。完成烹饪和清理后,柜台是空的,食谱书中仍然有相同的东西 - 但没有鸡蛋! – Borealid