如何用gdb读取局部变量?

时间:2011-05-11 05:04:11

标签: c assembly gdb

我知道你可以通过使用gdb查看$ ebp的正偏移来找到任何参数:

(gdb) x/4wx $ebp

然后,我会使用x/s查看第3和第4个地址,因为它们将是第一个和第二个参数。局部变量怎么样?我如何看待$ ebp的负偏移值? 还有,无论如何看看$ eax的价值? 每当我尝试使用x/s $eax打印$ eax的值时,地址超出范围或值为0,我确信这不是因为我只是在寄存器中放入一个常量值。

我尝试info locals,但收到消息“没有符号表信息可用”。

2 个答案:

答案 0 :(得分:6)

首先,您需要将符号编译到二进制文件中。使用gcc上的-g选项和当前命令执行此操作。如果您使用的是其他编译器,则需要查阅其文档。在此之后,'info locals'和print命令将起作用。

要查看任何局部变量,您只需使用'print'命令即可。例如,查看局部变量'i'就像'print i'一样简单。

您应该能够以与$ ebp相同的方式处理$ eax。我怀疑你有问题,因为你正在使用x / s。 x / s将尝试打印出一个字符串,因此它将一直持续到达到空字符。如果长时间没有发生这种情况,那么字符串的长度将超出范围。试试'x / d $ eax'。你甚至可以'打印$ eax'。您还可以使用'info registers'来获取所有寄存器数据。

答案 1 :(得分:0)

  

我知道你可以通过使用gdb

查看$ ebp的正偏移量来找到任何参数

这仅适用于某些处理器和某些调用约定,并不是通用的。

假设您只关心x86,并且您的代码是使用帧指针编译的(曾经是默认值,但不再是选择模式下GCC 4.6的默认值),则本地分配在固定的负偏移处。 %ebp

显然,如果您可以使用调试符号(使用-g)重建代码,那么GDB将只能打印它们的值,而您无需关心GDB如何找到它们。

如果你不能(例如因为代码来自第三方),你将不得不仔细查看反汇编和猜测。如果您猜测某些值存储在%ebp-8,则可以使用GDB检查该值,与检查正偏移的方式完全相同:(gdb) x/wx $ebp-8

注意:编译器可以按照自己想要的方式自由布局,所以如果你声明

int x, y, z;

编译器可以x %ebp-16y %ebp-20z %ebp-12存储。