调用栈是有控制程序执行流的栈帧的存储位置。当调用函数时,将创建一个栈帧,用于告诉计算机在该函数调用结束时,如何将控制权交给调用函数。栈帧也是局部边变量与函数参数的存储位置。我们可以查看这些栈帧,以确定我们的程序时如何运行的。找出当前栈帧之下的栈帧列表是通过backtrace命令实现的
3.1如何获得栈帧?使用gdb命令backtrace。在下面的栈帧列表中,我们可以看到我们当前位于func2()内,该函数时由func1()调用,而func1()是由main()调用的。
(gdb) backtrace
#0 func2 (x=30) at test.c:5
#1 0x80483e6 in func1 (a=30) at test.c:10
#2 0x8048414 in main (argc=1, argv=0xbffffaf4) at test.c:19
#3 0x40037f5c in __libc_start_main () from /lib/libc.so.6
(gdb)
3.2 如何改变栈帧?使用gdb 命令frame。注意,在上述的栈帧列表中,每一个帧旁边均标识一个数字。将你希望进入的栈帧对应的数字作为frame的参数。
(gdb) frame 2
#2 0x8048414 in main (argc=1, argv=0xbffffaf4) at test.c:19
19 x = func1(x);
(gdb)
3.3如何检查栈帧?为了查看当前栈帧的内容,有三个有用的gdb命令。Info frame命令显示当前栈帧的信息。Infor locals 显示栈帧局部变量列表以及其在当前栈帧的值。Info args显示参数列表的值。
(gdb) info frame
Stack level 2, frame at 0xbffffa8c:
eip = 0x8048414 in main (test.c:19); saved eip 0x40037f5c
called by frame at 0xbffffac8, caller of frame at 0xbffffa5c
source language c.
Arglist at 0xbffffa8c, args: argc=1, argv=0xbffffaf4
Locals at 0xbffffa8c, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffffa8c, eip at 0xbffffa90
(gdb) info locals
x = 30
s = 0x8048484 "Hello World!\n"
(gdb) info args
argc = 1
argv = (char **) 0xbffffaf4