重点命令:display /i $pc
gdb 命令
- file <文件名>加载被调试的可执行程序文件。
- r Run的简写,运行被调试的程序。
- c Continue的简写,继续执行被调试程序, 直至下一个断点或程序结束。
- b <行号>
- b <函数名称>
- b *<函数名称>
- b *<代码地址>
- b: Breakpoint的简写,设置断点。两可以使用“行号”“函数名称”“执行地址”等方式指定断点位置。
其中在函数名称前面加“*”符号表示将断点设置在“由编译器生成的prolog代码处”。 - d [编号] Delete breakpoint的简写,删除指定编号的某个断点,或删除所有断点。断点编号从1开始递增。
- s: 执行一行源程序代码,如果此行代码中有函数调用,则进入该函数;
s 相当于其它调试器中的“Step Into (单步跟踪进入)”; - n: 执行一行源程序代码,此行代码中的函数调用也一并执行。
n 相当于其它调试器中的“Step Over (单步跟踪)”。 - si命令类似于s命令,ni命令类似于n命令。 所不同的是,这两个命令(si/ni)所针对的是汇编指令,而s/n针对的是源代码。
- p <变量名称>Print的简写,显示指定变量(临时变量或全 局变量)的值。
- display,设置程序中断后欲显示的数据及 其格式。
例如,如果希望每次程序中断后可以看到即将被执行的下一条汇编指令,可以使用命令
“display /i $pc”
其中 $pc 代表当前汇编指令,/i 表示以十六进行显示。当需要关心汇编代码时,此命令相当有用。 - undispaly,取消先前的display设 置,编号从1开始递增。
- i Info的简写,用于显示各类信息,详情请查阅 “help i”。
- q Quit的简写,退出GDB调试环境。
- help [命令名称]GDB帮助命令,提供对GDB名种命令的解释说明。
如果指定了“命令名称”参数,则显示该命令的详细说明;如果没有指定参数,则分类显示所有GDB命令,供用户进一步浏览和查询。
反汇编调试
显示汇编命令 display /i $pc
(gdb) display /i $pc
(gdb) si
20 n++;
1: x/i $pc 0x8048363 <main+23>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x08048366 20 n++;
1: x/i $pc 0x8048366 <main+26>: incl (%eax)
(gdb) si
21 n--;
1: x/i $pc 0x8048368 <main+28>: lea 0xfffffffc(%ebp),%eax
(gdb) si
0x0804836b 21 n--;
1: x/i $pc 0x804836b <main+31>: decl (%eax)
(gdb) si
23 nGlobalVar += 100;
1: x/i $pc 0x804836d <main+33>: addl $0x64,0x80494fc
汇编断点设置
使用命令“b *main”在 main 函数的 prolog 代码处设置断点
(prolog、epilog,分别表示编译器在每个函数的开头和结尾自行插入的代码):
(gdb) b *main
Breakpoint 4 at 0x804834c: file gdb-sample.c, line 17.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/liigo/temp/test_jmp/test_jmp/gdb-sample
Breakpoint 4, main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834c <main>: push %ebp
(gdb) si
0x0804834d 17 {
1: x/i $pc 0x804834d <main+1>: mov %esp,%ebp
(gdb) si
0x0804834f in main () at gdb-sample.c:17
17 {
1: x/i $pc 0x804834f <main+3>: sub $0x8,%esp
(gdb) si
0x08048352 17 {
1: x/i $pc 0x8048352 <main+6>: and $0xfffffff0,%esp
(gdb) si
0x08048355 17 {
1: x/i $pc 0x8048355 <main+9>: mov $0x0,%eax
(gdb) si
0x0804835a 17 {
1: x/i $pc 0x804835a <main+14>: sub %eax,%esp
(gdb) si
19 n = 1;
1: x/i $pc 0x804835c <main+16>: movl $0x1,0xfffffffc(%ebp)
此时可以使用“i r”命令显示寄存器中的当前值———“i r”即“Infomation Register”:
(gdb) i r
eax 0xbffff6a4 -1073744220
ecx 0x42015554 1107383636
edx 0x40016bc8 1073834952
ebx 0x42130a14 1108544020
esp 0xbffff6a0 0xbffff6a0
ebp 0xbffff6a8 0xbffff6a8
esi 0x40015360 1073828704
edi 0x80483f0 134513648
eip 0x8048366 0x8048366
eflags 0x386 902
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x33 51
当然也可以显示任意一个指定的寄存器值:
(gdb) i r eax
eax 0xbffff6a4 -1073744220
1.gdb中汇编调试