如何用gdb读取局部变量?
我知道您可以通过使用 gdb 查看 $ebp 的正偏移量来找到任何参数:
(gdb) x/4wx $ebp
然后,我将使用 x/s
查看第三个和第四个地址,因为它们将是第一个和第二个地址范围。那么对于局部变量呢?我如何查看与 $ebp 负偏移处的值? 另外,有没有办法查看 $eax 的值? 每当我尝试使用 x/s $eax 打印 $eax 的值时,地址超出范围或值为 0,我确信这不是因为我只是输入了一个常量寄存器中的值。
我尝试了 info locals
但收到消息“没有可用的符号表信息”。
I know that you can find any parameters by looking at a positive offset from $ebp using gdb:
(gdb) x/4wx $ebp
Then, I would look at the 3rd and 4th addresses using x/s
because they would be the first and second parameter. What about for local variables? How would I look at the values at a negative offset from $ebp?
Also, is there anyway to look at the value of $eax?
Whenever I try to print the value of $eax using x/s $eax
, the address is out of bound or the value is 0, which I am sure that it is not because I just put a constant value in the register.
I tried info locals
but I get the message "No symbol table info available".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,您需要将调试符号编译到二进制文件中。将 gcc 上的 -g 选项与当前命令一起使用来执行此操作。如果您使用不同的编译器,则需要查阅其文档。此后,“info locals”和打印命令将起作用。
要查看任何局部变量,您所需要做的就是使用“print”命令。例如,要查看局部变量“i”,就像“print i”一样简单。
您应该能够以与 $ebp 相同的方式处理 $eax。我怀疑你有问题,因为你使用的是 x/s。 x/s 将尝试打印出一个字符串,因此它将继续,直到遇到空字符。如果这种情况长时间不发生,则字符串的长度将超出范围。尝试“x/d $eax”。您甚至可以执行“print $eax”。您还可以使用“信息寄存器”来获取所有寄存器数据。
First you need to compile debugging the symbols into your binary. Use the -g option on gcc with your current command to do this. If you're using a different compiler you will need to consult its documentation. After this, 'info locals' and the print command will work.
To look at any local variable all you need to do is use the 'print' command. For example to look at the local variable 'i' it's as easy as 'print i'.
You should be able to handle $eax in the same way as $ebp. I suspect you have problems because you're using x/s. x/s will try and print out a string, and so it will continue until it hits a null character. If this doesn't happen for a long time then the length of the string will go out of bounds. Try 'x/d $eax'. You can even do 'print $eax'. You can also use 'info registers' to get all the register data.
这仅适用于某些处理器和某些调用约定,并且绝不是通用的。
假设您只关心 x86,并且您的代码是使用帧指针编译的(这曾经是默认值,但不再是 opt 模式下 GCC 4.6 的默认值),则局部变量将分配在距
固定的负偏移处%ebp。
显然,如果您可以使用调试符号(使用
-g
)重建代码,那么 GDB 将能够仅打印它们的值,并且您不需要关心 GDB 如何找到它们。如果你不能(例如因为代码来自第三方),你将不得不仔细查看反汇编并猜测。如果您猜测某个值存储在
%ebp-8
中,则可以使用 GDB 检查该值,就像检查正偏移量一样:(gdb) x/wx $ebp-8
。请注意:编译器可以自由地以任何它想要的方式进行本地布局,因此如果您声明
编译器可以自由地将
x
存储在%ebp-16
、y
位于%ebp-20
,z
位于%ebp-12
。This only works for some processors and some calling conventions, and is by no means universal.
Assuming you only care about x86, and that your code is compiled with frame pointers (which used to be the default, but no longer is the default for GCC 4.6 in opt mode), locals are allocated at a fixed negative offset from
%ebp
.Obviously if you can rebuild your code with debug symbols (with
-g
), then GDB will be able to just print their values, and you don't need to care how GDB finds them.If you can't (e.g. because the code came from third party), you'll have to carefully look at disassembly, and guess. If you guess that some value is stored at
%ebp-8
, you can examine that value with GDB exactly the same way you examine positive offsets:(gdb) x/wx $ebp-8
.Beware: the compiler is free to lay out local any way it wants, so if you declare
the compiler is free to store
x
at%ebp-16
,y
at%ebp-20
, andz
at%ebp-12
.