mirror of
https://github.com/beyondx/Notes.git
synced 2026-06-18 09:26:23 +08:00
updated
This commit is contained in:
130
Zim/Utils/gdb/gdb_debugging.txt
Normal file
130
Zim/Utils/gdb/gdb_debugging.txt
Normal file
@@ -0,0 +1,130 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T16:49:56+08:00
|
||||
|
||||
====== gdb debugging ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
[geekard@geekard elf]$ **gdb demo**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
**(gdb) info source **//查看当前使用的source file name
|
||||
|
||||
|
||||
**(gdb) info args **
|
||||
name = 0x80486a3 "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff920
|
||||
**(gdb) info locals**
|
||||
a = -1209680176
|
||||
nm = 0xbffff914 "\027"
|
||||
fr = {0xbffff948 "",
|
||||
0xb7e5beff <printf+47> "\203\304\030[\303f\220f\220f\220f\220f\220f\220S\203\354\030\215D$,\211D$\f\213D$(讷\r",
|
||||
0xb7fb5a00 <_IO_2_1_stdout_> "\204*\255", <incomplete sequence \373>, 0x80486b4 "\tThe globalVarStatic is:%d\n"}
|
||||
//从上面两次的反汇编结果可以得出如下结论:
|
||||
//1. break function-name 设置的断点并不位于function的入口处,而break *function-name才是。
|
||||
//2. break function-name设置的断点位于function的prologue指令之后,auto variable初始化指令之前。
|
||||
//3. 当执行到前面设置的断点时,函数的args已经由caller通过stack传入,但是函数的auto variable还没有被初始化
|
||||
|
||||
**(gdb) bt **//查看函数调用信息,即backtrap。callee的编号小于其caller。
|
||||
#0 greeting (name=0x80486a3 "geekard", age=23, friends=0xbffff920) at demo.c:13
|
||||
#1 0x08048578 in main (argc=5, argv=0xbffff9e4) at demo.c:50
|
||||
**(gdb) info f 1 **//查看stack frame编号为1的函数帧信息
|
||||
Stack frame at 0xbffff950:
|
||||
eip = 0x8048578 in main (demo.c:50); saved eip 0xb7e28605
|
||||
caller of frame at 0xbffff910
|
||||
source language c.
|
||||
Arglist at 0xbffff948, args: argc=5, argv=0xbffff9e4
|
||||
Locals at 0xbffff948, Previous frame's sp is 0xbffff950
|
||||
Saved registers:
|
||||
ebp at 0xbffff948, eip at 0xbffff94c
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0x804842c in greeting (demo.c:13); saved eip 0x8048578
|
||||
called by frame at 0xbffff950
|
||||
source language c.
|
||||
Arglist at 0xbffff908, args: name=0x80486a3 "geekard", age=23, friends=0xbffff920
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers:
|
||||
eip at 0xbffff90c
|
||||
**(gdb) disassemble main **//反汇编main函数
|
||||
Dump of assembler code for function main:
|
||||
//从info f 1的输出可知,call main前esp的值为 0xbffff950。
|
||||
0x080484f0 <+0>: push %ebp
|
||||
0x080484f1 <+1>: mov %esp,%ebp //main函数的prologue指令,break main时停止在下一条指令处。
|
||||
0x080484f3 <+3>: and $0xfffffff0,%esp //SystemV i386 ABI规定esp必须word对齐。
|
||||
0x080484f6 <+6>: sub $0x30,%esp //为main的auto variables预留空间,此后esp的值为0xbffff10。
|
||||
|
||||
0x080484f9 <+9>: mov 0x8049918,%eax
|
||||
0x080484fe <+14>: mov %eax,0x2c(%esp) //int autoVar = globVar;
|
||||
|
||||
0x08048502 <+18>: mov 0x8049924,%eax
|
||||
0x08048507 <+23>: mov %eax,0x28(%esp) //i = externVar;
|
||||
|
||||
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) // char *name = "geekard"
|
||||
|
||||
0x08048513 <+35>: movl $0x17,0x20(%esp) // int age = 23
|
||||
|
||||
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //"Tom"
|
||||
0x08048523 <+51>: movl $0x804863d,0x14(%esp) //"John"
|
||||
0x0804852b <+59>: movl $0x8048642,0x18(%esp) //"Pi"
|
||||
0x08048533 <+67>: movl $0x0,0x1c(%esp) //NULL
|
||||
//char **friends = {x, x, NUU},friends是一个指向字符指针的指针__变量(占有内存单元)__,其指向的数组有4个元素。
|
||||
//变量friends的地址为0xbffff918,即0x8($esp)处,可以用print &friends命令打印出。
|
||||
//变量friends的值为0xbffff920,指向栈上"Tom"所在的内参单元地址。对于指针数组变量friends,有以下调试信息:
|
||||
**(gdb) p &friends **
|
||||
$21 = (char ***) 0xbffff918
|
||||
**(gdb) p friends**
|
||||
$17 = (char **) 0xbffff920
|
||||
**(gdb) p friends@4**
|
||||
$18 = {0xbffff920, 0x80485f2 <__libc_csu_init+82>, 0x8048639, 0x804863d}
|
||||
**(gdb) p *friends@4**
|
||||
$19 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
|
||||
**(gdb) x /4wx friends@4**
|
||||
0xbffff918: 0xbffff920 0x080485f2 0x08048639 0x0804863d
|
||||
**(gdb) x /4wx *friends@4**
|
||||
0xbffff920: 0x08048639 0x0804863d 0x08048642 0x00000000
|
||||
**(gdb) p *friends@4**
|
||||
$20 = {0x8048639 "Tom", 0x804863d "John", 0x8048642 "Pi", 0x0}
|
||||
//从main函数的auto variable初始化指令可以得出如下结论:
|
||||
//1. main函数的auto variable是保存在stack中,其layourt的顺序与定义的顺序一致,即先定义的变量先入栈。
|
||||
//2.static variable定义在全局数据段(.data section)中,而不是stack中(int static staticVar并没有在stack中初始化)。
|
||||
//3.数组的各元素入栈顺序与定义顺序相反,即索引越大越先入栈; 指针数组变量最后入栈。
|
||||
|
||||
//auto variable初始化完成后的main栈分配如下:
|
||||
{{./stack.png?height=544}}
|
||||
|
||||
|
||||
0x0804853b <+75>: movl $0x80486ab,(%esp)
|
||||
0x08048542 <+82>: call 0x8048300 <puts@plt>
|
||||
0x08048547 <+87>: mov 0x804991c,%eax
|
||||
0x0804854c <+92>: mov %eax,0x4(%esp)
|
||||
0x08048550 <+96>: movl $0x80486b4,(%esp)
|
||||
0x08048557 <+103>: call 0x80482f0 <printf@plt>
|
||||
0x0804855c <+108>: lea 0x10(%esp),%eax
|
||||
0x08048560 <+112>: mov %eax,0x8(%esp)
|
||||
0x08048564 <+116>: mov 0x20(%esp),%eax
|
||||
0x08048568 <+120>: mov %eax,0x4(%esp)
|
||||
0x0804856c <+124>: mov 0x24(%esp),%eax
|
||||
0x08048570 <+128>: mov %eax,(%esp)
|
||||
0x08048573 <+131>: call 0x804842c <greeting>
|
||||
__0x08048578__ <+136>: movl $0x3,0x4(%esp)
|
||||
0x08048580 <+144>: movl $0x2,(%esp)
|
||||
0x08048587 <+151>: call 0x8048590 <add>
|
||||
0x0804858c <+156>: leave
|
||||
0x0804858d <+157>: ret
|
||||
End of assembler dump.
|
||||
|
||||
//greeting函数的argumets是由main函数通过栈传入的。下面代码节选至main函数的反汇编输出。
|
||||
//函数的auto variable是保存在其stack中的。下面时main函数的auto variable初始化代码。
|
||||
0x0804850b <+27>: movl $0x80486a3,0x24(%esp) //name
|
||||
0x08048513 <+35>: movl $0x17,0x20(%esp) //age
|
||||
0x0804851b <+43>: movl $0x8048639,0x10(%esp) //friends
|
||||
//将greeting函数的friends参数圧入栈中,注意friends参数的值是main的auto variable,所以它保存在main的stack frame中。
|
||||
0x0804855c <+108>: lea 0x10(%esp),%eax
|
||||
0x08048560 <+112>: mov %eax,0x8(%esp) //frinnds
|
||||
0x08048564 <+116>: mov 0x20(%esp),%eax
|
||||
0x08048568 <+120>: mov %eax,0x4(%esp) //通过栈传入age参数
|
||||
0x0804856c <+124>: mov 0x24(%esp),%eax
|
||||
0x08048570 <+128>: mov %eax,(%esp) //通过栈传入name参数
|
||||
0x08048573 <+131>: call 0x804842c <greeting>
|
||||
174
Zim/Utils/gdb/gdb_debugging/gdb_demo.txt
Normal file
174
Zim/Utils/gdb/gdb_debugging/gdb_demo.txt
Normal file
@@ -0,0 +1,174 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T22:10:21+08:00
|
||||
|
||||
====== gdb demo ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
[geekard@geekard elf]$ **cat demo.c**
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int globalVar = 1;
|
||||
int globalVarUninit;
|
||||
|
||||
static int globalVarStatic = 3;
|
||||
|
||||
extern int externVar;
|
||||
extern int add(int, int);
|
||||
|
||||
void greeting(char *name, int age, char** friends)
|
||||
{
|
||||
|
||||
int a = 23;
|
||||
char *nm = "zhangjun";
|
||||
char *fr[] = {"Tom", "John", "Pi", NULL}; //fr为__数组名称__,它指向一块内存单元,但是本身不咱用内存单元。
|
||||
char **fr = {"Tom", "John", "Pi", NULL}; //fr为__指针变量,指向一个保存有4个字符指针的内存单元(位于greeting的栈中)。__
|
||||
|
||||
if (name == NULL)
|
||||
name = nm;
|
||||
if (age == 0)
|
||||
age = a;
|
||||
if (friends == NULL)
|
||||
friends = fr;
|
||||
|
||||
printf("In greeting:\n");
|
||||
printf("\tHello, %s:\n", name);
|
||||
printf("\tYourt age is:%d.\n", age);
|
||||
printf("\tYourt friends are:\n");
|
||||
while (*friends != NULL) {
|
||||
printf("\t\t%s\n", *friends);
|
||||
friends += 1;
|
||||
}
|
||||
|
||||
printf("Goodbye from greeting.\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int autoVar = globalVar;
|
||||
static int staticVar = 2;
|
||||
int i = externVar;
|
||||
|
||||
char *name = "geekard";
|
||||
int age = 23;
|
||||
char *friends[] = {"Tom", "John", "Pi", NULL};
|
||||
|
||||
printf("In main:\n");
|
||||
printf("\tThe globalVarStatic is:%d\n",globalVarStatic);
|
||||
greeting(name, age, friends);
|
||||
add(2, 3);
|
||||
}
|
||||
[geekard@geekard elf]$ **cat foo.c**
|
||||
int externVar = 1;
|
||||
int static staticVarStatic = 2;
|
||||
|
||||
int add(int a, int b)
|
||||
{
|
||||
return a + b;
|
||||
}
|
||||
[geekard@geekard elf]$ **gcc -g demo.c foo.c -o demo**
|
||||
demo.c: In function ‘greeting’:
|
||||
demo.c:18:3: warning: initialization from incompatible pointer type [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
demo.c:18:3: warning: excess elements in scalar initializer [enabled by default]
|
||||
demo.c:18:3: warning: (near initialization for ‘fr’) [enabled by default]
|
||||
[geekard@geekard elf]$ **gdb demo**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
。。。。。。
|
||||
**(gdb) info source**
|
||||
Current source file is demo.c
|
||||
Compilation directory is /home/geekard/Code/elf
|
||||
Located in /home/geekard/Code/elf/demo.c
|
||||
Contains 53 lines.
|
||||
Source language is c.
|
||||
Compiled with DWARF 2 debugging format.
|
||||
Does not include preprocessor macro info.
|
||||
**(gdb) info sources**
|
||||
Source files for which symbols have been read in:
|
||||
|
||||
/home/geekard/Code/elf/demo.c
|
||||
|
||||
Source files for which symbols will be read in on demand:
|
||||
|
||||
/home/geekard/Code/elf/foo.c
|
||||
|
||||
**(gdb) set args -a aa --bb=bbb ccc ** //设置dmo程序的默认命令行参数,执行run命令时会传入该参数。
|
||||
**(gdb) show args **//查看demo程序的命令行参数
|
||||
Argument list to give program being debugged when it is started is "-a aa --bb=bbb ccc".
|
||||
**(gdb) info args ** //查看当前stack frame对应函数的参数列表信息。
|
||||
No frame selected.
|
||||
(gdb) show env
|
||||
XDG_VTNR=1
|
||||
。。。。。
|
||||
**(gdb) shell clear ** //执行shell命令,这里为clear。
|
||||
**(gdb) info address greeting** //在symbol table中查找greeting函数的入口地址
|
||||
Symbol "greeting" is a function at address 0x804842c.
|
||||
**(gdb) b 0x804842c //在某个地址处设置断点时,地址前应该加星号,否则gdb认为它为函数名称。**
|
||||
Function "0x804842c" not defined.
|
||||
Make breakpoint pending on future shared library load? (y or [n]) n
|
||||
**(gdb) b *0x804842c **
|
||||
Breakpoint 1 at 0x804842c: file demo.c, line 13.
|
||||
**(gdb) b *greeting**
|
||||
Note: breakpoint 1 also set at pc 0x804842c.
|
||||
Breakpoint 2 at 0x804842c: file demo.c, line 13.
|
||||
**(gdb) b greeting** //在greeting函数入口处设一个断点
|
||||
Breakpoint 3 at 0x8048432: file demo.c, line 15.
|
||||
**(gdb) info b**
|
||||
Num Type Disp Enb Address What
|
||||
1 breakpoint keep y 0x0804842c in greeting at demo.c:13
|
||||
2 breakpoint keep y 0x0804842c in greeting at demo.c:13
|
||||
3 breakpoint keep y 0x08048432 in greeting at demo.c:15
|
||||
**(gdb) delete 2 //删除编号为2的断点**
|
||||
**(gdb) list 12,16 //查看当前文件的12至16行。**
|
||||
12 void greeting(char *name, int age, char** friends)
|
||||
13 {
|
||||
14
|
||||
15 int a = 23;
|
||||
16 char *nm = "zhangjun";
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/demo -a aa --bb=bbb ccc //gdb将set args命令的参数传给demo。
|
||||
Breakpoint 1, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:13
|
||||
13 {
|
||||
**(gdb) disassemble greeting** //反汇编greeting函数。如果disassmble没有参数,则默认反汇编当前所执行的函数。
|
||||
Dump of assembler code for function greeting:
|
||||
=> 0x0804842c <+0>: push %ebp //demo停止在greeting函数的入口处,函数的prologue指令还没有执行。
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x28,%esp
|
||||
(gdb) c //继续执行,直到下一个断点处。
|
||||
Continuing.
|
||||
|
||||
Breakpoint 3, greeting (name=0x804868b "geekard", age=23, friends=0xbffff950) at demo.c:15
|
||||
15 int a = 23;
|
||||
**(gdb) disassemble** //反汇编当前执行的函数
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x28,%esp
|
||||
=> 0x08048432 <+6>: movl $0x17,-0xc(%ebp) //指令前的"=>"表示下一条**待执行**的指令位置。
|
||||
//可见greeting的prologue指令已经执行,这意味着greeting的栈帧已经建立。但是greeting的auto variable初始化指令还没有执行。
|
||||
0x08048439 <+13>: movl $0x8048620,-0x10(%ebp)
|
||||
0x08048440 <+20>: movl $0x8048629,-0x14(%ebp)
|
||||
0x08048447 <+27>: cmpl $0x0,0x8(%ebp)
|
||||
0x0804844b <+31>: jne 0x8048453 <greeting+39>
|
||||
0x0804844d <+33>: mov -0x10(%ebp),%eax
|
||||
0x08048450 <+36>: mov %eax,0x8(%ebp)
|
||||
。。。。。
|
||||
**(gdb) info args //查看当前stack frame对应函数的参数列表。**
|
||||
name = 0x804868b "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff950 //传经来的时指针
|
||||
**(gdb) info locals** //greeting函数的auto variables还没有初始化,所以下列为无效值
|
||||
a = -1209680176
|
||||
nm = 0xbffff944 "\027"
|
||||
fr = 0x80486a4 //
|
||||
(gdb)
|
||||
|
||||
|
||||
|
||||
|
||||
82
Zim/Utils/gdb/gdb_debugging/gdb_pointer.txt
Normal file
82
Zim/Utils/gdb/gdb_debugging/gdb_pointer.txt
Normal file
@@ -0,0 +1,82 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T21:45:29+08:00
|
||||
|
||||
====== gdb pointer ======
|
||||
Created Tuesday 25 December 2012
|
||||
[geekard@geekard elf]$ **cat array.c**
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ia[3] = {1,2,3};
|
||||
char *cpa[3] = {"Tom", "John", NULL};
|
||||
char *cpa2[] = {"Tom", "John", NULL};
|
||||
char **cpa3 = {"Tom", "John", NULL};
|
||||
}
|
||||
[geekard@geekard elf]$ **gcc -g array.c -o array**
|
||||
array.c: In function ‘main’:
|
||||
array.c:9:4: warning: initialization from incompatible pointer type [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
array.c:9:4: warning: excess elements in scalar initializer [enabled by default]
|
||||
array.c:9:4: warning: (near initialization for ‘cpa3’) [enabled by default]
|
||||
[geekard@geekard elf]$ **gdb array**
|
||||
GNU gdb (GDB) 7.5.1
|
||||
。。。。。
|
||||
**(gdb) list main**
|
||||
1 #include <stdio.h>
|
||||
2 #include <stdlib.h>
|
||||
3
|
||||
4 int main(void)
|
||||
5 {
|
||||
6 int ia[3] = {1,2,3};
|
||||
7 char *cpa[3] = {"Tom", "John", NULL};
|
||||
8 char *cpa2[] = {"Tom", "John", NULL}; //ia, cpa, cpa2为数组首地址的引用名称,而非变量,不占用
|
||||
9 char **cpa3 = {"Tom", "John", NULL};
|
||||
10 }
|
||||
**(gdb) b 10**
|
||||
Breakpoint 1 at 0x8048418: file array.c, line 10.
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/array
|
||||
warning: Could not load shared library symbols for linux-gate.so.1.
|
||||
Do you need "set solib-search-path" or "set sysroot"?
|
||||
|
||||
Breakpoint 1, main () at array.c:10
|
||||
10 }
|
||||
**(gdb) disassemble main**
|
||||
Dump of assembler code for function main:
|
||||
0x080483cc <+0>: push %ebp
|
||||
0x080483cd <+1>: mov %esp,%ebp
|
||||
0x080483cf <+3>: sub $0x30,%esp
|
||||
0x080483d2 <+6>: movl $0x1,-0x10(%ebp)
|
||||
0x080483d9 <+13>: movl $0x2,-0xc(%ebp)
|
||||
0x080483e0 <+20>: movl $0x3,-0x8(%ebp)
|
||||
0x080483e7 <+27>: movl $0x80484b0,-0x1c(%ebp)
|
||||
0x080483ee <+34>: movl $0x80484b4,-0x18(%ebp)
|
||||
0x080483f5 <+41>: movl $0x0,-0x14(%ebp)
|
||||
0x080483fc <+48>: movl $0x80484b0,-0x28(%ebp)
|
||||
0x08048403 <+55>: movl $0x80484b4,-0x24(%ebp)
|
||||
0x0804840a <+62>: movl $0x0,-0x20(%ebp)
|
||||
0x08048411 <+69>: movl $0x80484b0,-0x4(%ebp)
|
||||
=> 0x08048418 <+76>: leave
|
||||
0x08048419 <+77>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) bt**
|
||||
#0 main () at array.c:10
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff980:
|
||||
eip = 0x8048418 in main (array.c:10); saved eip 0xb7e28605
|
||||
source language c.
|
||||
Arglist at 0xbffff978, args:
|
||||
Locals at 0xbffff978, Previous frame's sp is 0xbffff980
|
||||
Saved registers:
|
||||
ebp at 0xbffff978, eip at 0xbffff97c
|
||||
**(gdb) info locals**
|
||||
ia = {1, 2, 3}
|
||||
cpa = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
|
||||
cpa2 = {0x80484b0 "Tom", 0x80484b4 "John", 0x0}
|
||||
__cpa3 = 0x80484b0__
|
||||
//可见ia, cpa, cpa2为数组名称,而cpa3为一指针变量,其值为0x80484b0。
|
||||
BIN
Zim/Utils/gdb/gdb_debugging/stack.png
Normal file
BIN
Zim/Utils/gdb/gdb_debugging/stack.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 117 KiB |
250
Zim/Utils/gdb/gdb_frame.txt
Normal file
250
Zim/Utils/gdb/gdb_frame.txt
Normal file
@@ -0,0 +1,250 @@
|
||||
Content-Type: text/x-zim-wiki
|
||||
Wiki-Format: zim 0.4
|
||||
Creation-Date: 2012-12-25T10:31:03+08:00
|
||||
|
||||
====== gdb frame ======
|
||||
Created Tuesday 25 December 2012
|
||||
|
||||
char **friends = {"Tom", "John", "Pi", \0};
|
||||
等价于 char *friends[ ] = {"Tom", "John", "Pi", \0};
|
||||
等价于 char *friends[4] = {"Tom", "John", "Pi", \0};
|
||||
|
||||
[geekard@geekard rel]$ gdb rel2
|
||||
GNU gdb (GDB) 7.5.1
|
||||
**(gdb) b greeting**
|
||||
Breakpoint 1 at 0x8048432: file rel2.c, line 8.
|
||||
**(gdb) r**
|
||||
Starting program: /home/geekard/Code/elf/rel/rel2
|
||||
warning: Could not load shared library symbols for linux-gate.so.1.
|
||||
Do you need "set solib-search-path" or "set sysroot"?
|
||||
3
|
||||
Breakpoint 1, greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
8 printf("Hello, %s:\n", name);
|
||||
**(gdb) disassemble**
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x18,%esp
|
||||
上面这三条指令称为prologue,由gcc自动添加。break fuction会在执行完function的prologue后停止,这样
|
||||
=> 0x08048432 <+6>: mov 0x8(%ebp),%eax
|
||||
0x08048435 <+9>: mov %eax,0x4(%esp)
|
||||
0x08048439 <+13>: movl $0x8048590,(%esp)
|
||||
0x08048440 <+20>: call 0x80482f0 <printf@plt>
|
||||
**(gdb) si //多次执行si,直到输出如下字符串**
|
||||
0x080482f0 in printf@plt ()
|
||||
**(gdb) bt**
|
||||
#0 0x080482f0 in printf@plt ()
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
#2 0x080484fd in main () at [[rel2.c:28]]
|
||||
**(gdb) info frame 2**
|
||||
Stack frame at 0xbffff970:
|
||||
eip = 0x80484fd in main (rel2.c:28); saved eip 0xb7e28605
|
||||
caller of frame at 0xbffff930
|
||||
source language c.
|
||||
Arglist at 0xbffff968, args:
|
||||
Locals at 0xbffff968, Previous frame's sp is 0xbffff970
|
||||
Saved registers:
|
||||
ebp at 0xbffff968, eip at 0xbffff96c
|
||||
**(gdb) info frame 1**
|
||||
Stack frame at 0xbffff930:
|
||||
eip = 0x8048445 in greeting (rel2.c:8); saved eip 0x80484fd
|
||||
called by frame at 0xbffff970, caller of frame at 0xbffff910
|
||||
source language c.
|
||||
Arglist at 0xbffff928, args: name=0x80485c9 "geekard", age=23, friends=0xbffff944
|
||||
Locals at 0xbffff928, Previous frame's sp is 0xbffff930
|
||||
Saved registers:
|
||||
ebp at 0xbffff928, eip at 0xbffff92c
|
||||
**(gdb) info frame 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0x80482f0 in printf@plt; saved eip 0x8048445
|
||||
called by frame at 0xbffff930
|
||||
Arglist at 0xbffff908, args:
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers: //没有保存ebp, esi, edi, ebx寄存器的值。
|
||||
eip at 0xbffff90c
|
||||
|
||||
**(gdb) disassemble main**
|
||||
Dump of assembler code for function main:
|
||||
0x0804848a <+0>: push %ebp
|
||||
0x0804848b <+1>: mov %esp,%ebp
|
||||
0x0804848d <+3>: and $0xfffffff0,%esp
|
||||
0x08048490 <+6>: sub $0x30,%esp
|
||||
0x08048493 <+9>: mov 0x8049804,%eax
|
||||
0x08048498 <+14>: mov %eax,0x2c(%esp)
|
||||
0x0804849c <+18>: movl $0x80485c9,0x28(%esp)
|
||||
0x080484a4 <+26>: movl $0x17,0x24(%esp)
|
||||
0x080484ac <+34>: movl $0x80485d1,0x14(%esp)
|
||||
0x080484b4 <+42>: movl $0x80485d5,0x18(%esp)
|
||||
0x080484bc <+50>: movl $0x80485da,0x1c(%esp)
|
||||
0x080484c4 <+58>: movl $0x0,0x20(%esp)
|
||||
0x080484cc <+66>: mov 0x8049808,%eax
|
||||
0x080484d1 <+71>: mov %eax,0x4(%esp)
|
||||
0x080484d5 <+75>: movl $0x80485dd,(%esp)
|
||||
0x080484dc <+82>: call 0x80482f0 <printf@plt>
|
||||
0x080484e1 <+87>: lea 0x14(%esp),%eax
|
||||
0x080484e5 <+91>: mov %eax,0x8(%esp)
|
||||
0x080484e9 <+95>: mov 0x24(%esp),%eax
|
||||
0x080484ed <+99>: mov %eax,0x4(%esp)
|
||||
0x080484f1 <+103>: mov 0x28(%esp),%eax
|
||||
0x080484f5 <+107>: mov %eax,(%esp)
|
||||
0x080484f8 <+110>: call __0x804842c__ <greeting>
|
||||
__0x080484fd__ <+115>: leave
|
||||
0x080484fe <+116>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) disassemble greeting**
|
||||
Dump of assembler code for function greeting:
|
||||
0x0804842c <+0>: push %ebp
|
||||
0x0804842d <+1>: mov %esp,%ebp
|
||||
0x0804842f <+3>: sub $0x18,%esp
|
||||
0x08048432 <+6>: mov 0x8(%ebp),%eax
|
||||
0x08048435 <+9>: mov %eax,0x4(%esp)
|
||||
0x08048439 <+13>: movl $0x8048590,(%esp)
|
||||
0x08048440 <+20>: call __0x80482f0__ <printf@plt>
|
||||
__0x08048445__ <+25>: mov 0xc(%ebp),%eax
|
||||
0x08048448 <+28>: mov %eax,0x4(%esp)
|
||||
0x0804844c <+32>: movl $0x804859c,(%esp)
|
||||
0x08048453 <+39>: call 0x80482f0 <printf@plt>
|
||||
0x08048458 <+44>: movl $0x80485af,(%esp)
|
||||
0x0804845f <+51>: call 0x8048300 <puts@plt>
|
||||
0x08048464 <+56>: jmp 0x804847f <greeting+83>
|
||||
0x08048466 <+58>: mov 0x10(%ebp),%eax
|
||||
0x08048469 <+61>: mov (%eax),%eax
|
||||
0x0804846b <+63>: mov %eax,0x4(%esp)
|
||||
0x0804846f <+67>: movl $0x80485c3,(%esp)
|
||||
0x08048476 <+74>: call 0x80482f0 <printf@plt>
|
||||
0x0804847b <+79>: addl $0x4,0x10(%ebp)
|
||||
0x0804847f <+83>: mov 0x10(%ebp),%eax
|
||||
0x08048482 <+86>: mov (%eax),%eax
|
||||
0x08048484 <+88>: test %eax,%eax
|
||||
0x08048486 <+90>: jne 0x8048466 <greeting+58>
|
||||
0x08048488 <+92>: leave
|
||||
0x08048489 <+93>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) x /8wx 0x80482f0**
|
||||
0x80482f0 <printf@plt>: 0x97ec25ff 0x00680804 0xe9000000 0xffffffe0
|
||||
0x8048300 <puts@plt>: 0x97f025ff 0x08680804 0xe9000000 0xffffffd0
|
||||
**(gdb) x /8wi 0x80482f0**
|
||||
__0x80482f0__ <printf@plt>: jmp *__0x80497ec__
|
||||
0x80482f6 <printf@plt+6>: push $0x0
|
||||
0x80482fb <printf@plt+11>: jmp 0x80482e0
|
||||
0x8048300 <puts@plt>: jmp *0x80497f0
|
||||
0x8048306 <puts@plt+6>: push $0x8
|
||||
0x804830b <puts@plt+11>: jmp 0x80482e0
|
||||
0x8048310 <__gmon_start__@plt>: jmp *0x80497f4
|
||||
0x8048316 <__gmon_start__@plt+6>: push $0x10
|
||||
**(gdb) x /wx 0x80497ec**
|
||||
0x80497ec <printf@got.plt>: 0xb7e5bed0
|
||||
**(gdb) si**
|
||||
0xb7e5bed0 in printf () from [[/usr/lib/libc.so.6]]
|
||||
**(gdb) disassemble *0x80497ec**
|
||||
Dump of assembler code for function __printf__:
|
||||
=> __0xb7e5bed0__ <+0>: push %ebx
|
||||
0xb7e5bed1 <+1>: sub $0x18,%esp
|
||||
0xb7e5bed4 <+4>: call 0xb7f376d3 <__x86.get_pc_thunk.bx>
|
||||
0xb7e5bed9 <+9>: add $0x159127,%ebx
|
||||
0xb7e5bedf <+15>: lea 0x24(%esp),%eax
|
||||
0xb7e5bee3 <+19>: mov %eax,0x8(%esp)
|
||||
0xb7e5bee7 <+23>: mov 0x20(%esp),%eax
|
||||
0xb7e5beeb <+27>: mov %eax,0x4(%esp)
|
||||
0xb7e5beef <+31>: mov -0x68(%ebx),%eax
|
||||
0xb7e5bef5 <+37>: mov (%eax),%eax
|
||||
0xb7e5bef7 <+39>: mov %eax,(%esp)
|
||||
0xb7e5befa <+42>: call 0xb7e520f0 <vfprintf>
|
||||
0xb7e5beff <+47>: add $0x18,%esp
|
||||
0xb7e5bf02 <+50>: pop %ebx
|
||||
0xb7e5bf03 <+51>: ret
|
||||
End of assembler dump.
|
||||
**(gdb) bt**
|
||||
#0 0xb7e5bed0 in printf () from /usr/lib/libc.so.6
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
#2 0x080484fd in main () at rel2.c:28
|
||||
**(gdb) info f 0**
|
||||
Stack frame at 0xbffff910:
|
||||
eip = 0xb7e5bed0 in printf; saved eip 0x8048445
|
||||
called by frame at 0xbffff930
|
||||
Arglist at 0xbffff908, args:
|
||||
Locals at 0xbffff908, Previous frame's sp is 0xbffff910
|
||||
Saved registers:
|
||||
eip at 0xbffff90c
|
||||
没有保存ebp, esi, edi, ebx等寄存器的值,所以它们的值与frame 1中的相等。在编译时如果指定-fomit-frame-pointer选项,则
|
||||
编译器为函数调用生成栈帧时不会圧入ebp寄存器的值,而且对arguments和auto variables的引用是通过esp进行的。这样可以将
|
||||
ebp寄存器节省出来,用作其它用途。但缺点是无法对函数调用进行frame backtrace(如果目标文件中有.eh_frame section则gdb可以
|
||||
从中提取出frame backtrace信息)。
|
||||
|
||||
**(gdb) info registers**
|
||||
eax 0x80485c9 134514121
|
||||
ecx 0x0 0
|
||||
edx 0x0 0
|
||||
ebx 0xb7fb5000 -1208266752 //继续保存的是frame 1中的值
|
||||
esp 0xbffff90c 0xbffff90c
|
||||
ebp 0xbffff928 0xbffff928 //继续保存的是frame 1中的值
|
||||
esi 0x0 0
|
||||
edi 0x0 0
|
||||
eip 0xb7e5bed0 0xb7e5bed0 <printf>
|
||||
eflags 0x200282 [ SF IF ID ]
|
||||
cs 0x73 115
|
||||
ss 0x7b 123
|
||||
ds 0x7b 123
|
||||
es 0x7b 123
|
||||
fs 0x0 0
|
||||
gs 0x33 51
|
||||
**(gdb) f 1 //切换frame到#1, 这样可以查看greeting函数的参数和自动变量值。**
|
||||
#1 0x08048445 in greeting (name=0x80485c9 "geekard", age=23, friends=0xbffff944) at rel2.c:8
|
||||
8 printf("Hello, %s:\n", name);
|
||||
**(gdb) info registers** //打印frame 1的寄存器
|
||||
eax 0x80485c9 134514121
|
||||
ecx 0x0 0
|
||||
edx 0x0 0
|
||||
ebx **0xb7fb5000** -1208266752
|
||||
esp 0xbffff910 0xbffff910
|
||||
ebp **0xbffff928** 0xbffff928
|
||||
esi 0x0 0
|
||||
edi 0x0 0
|
||||
eip 0x8048445 0x8048445 <greeting+25>
|
||||
eflags 0x200282 [ SF IF ID ]
|
||||
cs 0x73 115
|
||||
ss 0x7b 123
|
||||
ds 0x7b 123
|
||||
es 0x7b 123
|
||||
fs 0x0 0
|
||||
gs 0x33 51
|
||||
(gdb)
|
||||
|
||||
|
||||
(gdb)
|
||||
**(gdb) info args**
|
||||
name = 0x80485c9 "geekard"
|
||||
age = 23
|
||||
friends = 0xbffff944
|
||||
**(gdb) ptype friends**
|
||||
type = char **
|
||||
|
||||
**(gdb) p friends**
|
||||
$1 = (char **) 0xbffff944
|
||||
**(gdb) p *friends**
|
||||
$6 = 0x80485d1 "Tom"
|
||||
**(gdb) p friends+1**
|
||||
$2 = (char **) 0xbffff948
|
||||
**(gdb) x /4wx friends**
|
||||
0xbffff944: 0x080485d1 0x080485d5 0x080485da 0x00000000
|
||||
**(gdb) p *friends@4**
|
||||
$4 = {0x80485d1 "Tom", 0x80485d5 "John", 0x80485da "Pi", 0x0}
|
||||
|
||||
**(gdb) p &friends**
|
||||
$5 = (char ***) 0xbffff938
|
||||
|
||||
(**gdb) x /4wx friends+1**
|
||||
0xbffff948: 0x080485d5 0x080485da 0x00000000 0x00000017
|
||||
**(gdb) x /4wx &friends**
|
||||
0xbffff938: 0xbffff944 0x08048552 0x00000001 0x080485d1
|
||||
**(gdb) p friends@4**
|
||||
$3 = {0xbffff944, 0x8048552 <__libc_csu_init+82>, 0x1, 0x80485d1}
|
||||
|
||||
**(gdb) x /wx friends**
|
||||
0xbffff944: 0x080485d1
|
||||
**(gdb) x /wx friends+1**
|
||||
0xbffff948: 0x080485d5
|
||||
**(gdb) x /wx &friends**
|
||||
0xbffff938: 0xbffff944
|
||||
**(gdb) x /wx *friends**
|
||||
0x80485d1: 0x006d6f54
|
||||
Reference in New Issue
Block a user