代码:
1 #include <stdio.h>
2 void show3()
3 {
4 puts("show3");
5 }
6
7 void show2()
8 {
9 puts("show2");
10 show3();
11 }
12
13 void show1()
14 {
15 puts("show1");
16 show2();
17 }
18
19
20 int main()
21 {
22 show1();
23 return 0;
24 }
$gcc -o main main.c -g
$gdb main
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) break 4
Breakpoint 1 at 0x80483ca: file main.c, line 4.
(gdb) run
Starting program: /home/xiayu/lab/main
show1
show2
Breakpoint 1, show3 () at main.c:4
4 puts("show3");
(gdb) backtrace
#0 show3 () at main.c:4
#1 0x080483ef in show2 () at main.c:10
#2 0x08048408 in show1 () at main.c:16
#3 0x08048420 in main () at main.c:22
(gdb) info frame
Stack level 0, frame at 0xbffd0cd0:
eip = 0x80483ca in show3 (main.c:4); saved eip 0x80483ef
called by frame at 0xbffd0ce0
source language c.
Arglist at 0xbffd0cc8, args:
Locals at 0xbffd0cc8, Previous frame's sp is 0xbffd0cd0
Saved registers:
ebp at 0xbffd0cc8, eip at 0xbffd0ccc
解读info frame命令产生的信息:
Stack level 0, frame at 0xbffd0cd0:
当前栈的起始地址0xbffd0cd0
eip = 0x80483ca in show3 (main.c:4); saved eip 0x80483ef
0x80483ca表示当前的eip寄存器的值(main.c:4)
0x80483ef:表示调用本函数(当前调用函数为show3)的指令的地址
即0x80483ef应该表示的是源程序第10行翻译成汇编后的地址
called by frame at 0xbffd0ce0
这个表示上一个栈帧的地址,因为当前函数是show3,所以这个地址表示show2的栈的地址,可以用命令查看一下show2的栈地址
(gdb) backtrace
#0 show3 () at main.c:4
#1 0x080483ef in show2 () at main.c:10
#2 0x08048408 in show1 () at main.c:16
#3 0x08048420 in main () at main.c:22
(gdb) select-frame 1
(gdb) info frame
Stack level 1, frame at 0xbffd0ce0:
eip = 0x80483ef in show2 (main.c:10); saved eip 0x8048408
called by frame at 0xbffd0cf0, caller of frame at 0xbffd0cd0
source language c.
Arglist at 0xbffd0cd8, args:
Locals at 0xbffd0cd8, Previous frame's sp is 0xbffd0ce0
Saved registers:
ebp at 0xbffd0cd8, eip at 0xbffd0cdc
可以看到红色字体部分,两个地址是一样的
继续解读上上一个info frame命令的信息
source language c
源程序是c语言,没什么说的
Arglist at 0xbffd0cc8, args:
存放函数参数的地址从0xbffd0cc8开始
Locals at 0xbffd0cc8, Previous frame's sp is 0xbffd0cd0
存放函数局部变量的地址从0xbffd0cd8开始
0xbffd0cd0:上面已经解释过了
Saved registers:
ebp at 0xbffd0cc8, eip at 0xbffd0ccc
调用函数的过程中,压栈时保存的相关寄存器的值
完毕。