使用gcc的-g选项生成调试信息:
注意:-O2的'O'是大写字母,不是零。
启动GDB :
寄存器前面加上$可以显示寄存器的内容:
$ gcc -Wall -O2 -g sourcefile |
注意:-O2的'O'是大写字母,不是零。
编译:
$ gcc -Wall -O2 -g -o TestStrcpy TestStrcpy.c |
其中源文件为:
/* filename: TestStrcpy.c
* description: Used to test the function "Strcpy"
* author: Howard
* date: 2013-11-22
* version: v1.0
*/
#ifndef DE
#define DE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
int main(void)
{
char * p;
char arr[6] = "hello";
p = arr;
strcpy(p,arr);
printf("%s\n",arr);
printf("%s\n",p);
return 0;
}
启动GDB :
gdb 可执行文件
$ gdb TestStrcpy
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04 Copyright (C) 2012 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 "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/<username>/CLan/TestStrcpy...done.
(gdb)
|
设置断点:
断点设置格式:
break 函数名
break 行号
break 文件名:行号
break 文件名:函数名
break +偏移量
break -偏移量
break *地址
其中break可以用b代替:
(gdb) b main Breakpoint 1 at 0x80483d0: file TestStrcpy.c, line 16. (gdb) b TestStrcpy.c:19 Breakpoint 2 at 0x8048405: file TestStrcpy.c, line 19. (gdb) b +22 No line 29 in the current file. Make breakpoint pending on future shared library load? (y or [n]) n (gdb) b +16 Breakpoint 3 at 0x804840d: file TestStrcpy.c, line 23. (gdb) b *0x804840f Breakpoint 4 at 0x804840f: file TestStrcpy.c, line 23. (gdb) b No default breakpoint address now. |
使用info break查看中断设置信息:
(gdb) info break Num Type Disp Enb Address What 1 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16 2 breakpoint keep y 0x08048405 in main at TestStrcpy.c:19 3 breakpoint keep y 0x0804840d in main at TestStrcpy.c:23 4 breakpoint keep y 0x0804840f in main at TestStrcpy.c:23 (gdb) |
运行
使用run命令运行,也可以简写成r,运行到第一个断点处停止,使用start能达到相同的效果:
(gdb) r Starting program: /home/shuaihua/CLan/TestStrcpy Breakpoint 1, main () at TestStrcpy.c:16 16 { (gdb) |
使用next执行到下一个断点处(简称n),使用step单步执行。
(gdb) n
21 strcpy(p,arr);
(gdb)
21 strcpy(p,arr);
(gdb)
显示栈帧
backtrace命令可以在遇到断点而暂停执行时显示栈帧,可简写为bt,它的别名有where和info stack——简称info s
格式:
显示所有栈帧:
backtrace
bt
只显示开头N个栈帧:
backtrace N
bt N
只显示洗后N个栈帧:
backtrace -N
bt -N
不仅显示栈帧,还显示局部变量:
backtrace full
bt full
backtrace full N
bt full N
backtrace full -N
bt full -N
例如:
(gdb) bt #0 main () at TestStrcpy.c:21 (gdb) bt 3 #0 main () at TestStrcpy.c:21 (gdb) bt full #0 main () at TestStrcpy.c:21 p = <optimized out> arr = "\000\000\371\204\004\b" (gdb) |
显示变量
print命令可以显示变量,可简写为p
(gdb) p p
$1 = <optimized out> (gdb) p arr $2 = "\000\000\371\204\004\b" (gdb) p *arr $3 = 0 '\000' (gdb) p arr[0] $4 = 0 '\000' (gdb) p arr[1] $5 = 0 '\000' (gdb) p arr[2] $6 = -7 '\371' (gdb) p arr[3] $7 = -124 '\204' (gdb) p arr[4] $8 = 4 '\004'
(gdb) p arr[5] $9 = 8 '\b' (gdb) |
显示寄存器
使用info reg命令显示寄存器的值:
(gdb) info reg eax 0x1 1 ecx 0xbffff314 -1073745132 edx 0xbffff2a4 -1073745244 ebx 0x2d7ff4 2981876 esp 0xbffff250 0xbffff250 ebp 0xbffff278 0xbffff278 esi 0x0 0 edi 0x0 0 eip 0x80483da 0x80483da <main+10> eflags 0x286 [ PF SF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51 |
寄存器前面加上$可以显示寄存器的内容:
(gdb) p $eax
$10 = 1
$10 = 1
p/格式 变量
格式 | 说明 |
x | 显示为十六进制 |
d | 显示为十进制 |
u | 显示为无符号十进制 |
o | 显示为八进制 |
t | 显示为二进制,two |
a | 地址 |
c | 显示为字符 |
f | 浮点数 |
s | 字符串 |
i | 机器语言 |
(gdb) p/c $eax $11 = 1 '\001' (gdb) p $pc $12 = (void (*)()) 0x80483da <main+10> (gdb) p $eip $13 = (void (*)()) 0x80483da <main+10> |
用x命令可以显示内存内容:
x/i意为显示汇编指令。
(gdb) x $pc 0x80483da <main+10>: -115 '\215' (gdb) x/i $pc => 0x80483da <main+10>: lea 0x16(%esp),%ebx |
x/i意为显示汇编指令。
反汇编指令disassemble,简写为disas
格式:
(1)disassemble
(2)disassemble 程序计数器
(3)disassemble 开始地址 结束地址
(1)反汇编当前整个函数,(2)反汇编程序计数器所在的整个函数,(3)反汇编两个地址之间的部分。
(gdb) disassemble $pc
Dump of assembler code for function main:
0x080483d0 <+0>: push %ebp
0x080483d1 <+1>: mov %esp,%ebp
0x080483d3 <+3>: push %ebx
0x080483d4 <+4>: and $0xfffffff0,%esp
0x080483d7 <+7>: sub $0x20,%esp
=> 0x080483da <+10>: lea 0x16(%esp),%ebx
0x080483de <+14>: mov %gs:0x14,%eax
0x080483e4 <+20>: mov %eax,0x1c(%esp)
0x080483e8 <+24>: xor %eax,%eax
0x080483ea <+26>: movl $0x6c6c6568,0x16(%esp)
0x080483f2 <+34>: movw $0x6f,0x1a(%esp)
0x080483f9 <+41>: movl $0x6,0x8(%esp)
0x08048401 <+49>: mov %ebx,0x4(%esp)
0x08048405 <+53>: mov %ebx,(%esp)
0x08048408 <+56>: call 0x80483c0 <__strcpy_chk@plt>
0x0804840d <+61>: mov %ebx,(%esp)
0x08048410 <+64>: call 0x8048390 <puts@plt>
0x08048415 <+69>: mov %ebx,(%esp)
0x08048418 <+72>: call 0x8048390 <puts@plt>
0x0804841d <+77>: xor %eax,%eax
0x0804841f <+79>: mov 0x1c(%esp),%edx
0x08048423 <+83>: xor %gs:0x14,%edx
0x0804842a <+90>: jne 0x8048431 <main+97>
0x0804842c <+92>: mov -0x4(%ebp),%ebx
0x0804842f <+95>: leave
0x08048430 <+96>: ret
0x08048431 <+97>: call 0x8048380 <__stack_chk_fail@plt>
Dump of assembler code for function main:
0x080483d0 <+0>: push %ebp
0x080483d1 <+1>: mov %esp,%ebp
0x080483d3 <+3>: push %ebx
0x080483d4 <+4>: and $0xfffffff0,%esp
0x080483d7 <+7>: sub $0x20,%esp
=> 0x080483da <+10>: lea 0x16(%esp),%ebx
0x080483de <+14>: mov %gs:0x14,%eax
0x080483e4 <+20>: mov %eax,0x1c(%esp)
0x080483e8 <+24>: xor %eax,%eax
0x080483ea <+26>: movl $0x6c6c6568,0x16(%esp)
0x080483f2 <+34>: movw $0x6f,0x1a(%esp)
0x080483f9 <+41>: movl $0x6,0x8(%esp)
0x08048401 <+49>: mov %ebx,0x4(%esp)
0x08048405 <+53>: mov %ebx,(%esp)
0x08048408 <+56>: call 0x80483c0 <__strcpy_chk@plt>
0x0804840d <+61>: mov %ebx,(%esp)
0x08048410 <+64>: call 0x8048390 <puts@plt>
0x08048415 <+69>: mov %ebx,(%esp)
0x08048418 <+72>: call 0x8048390 <puts@plt>
0x0804841d <+77>: xor %eax,%eax
0x0804841f <+79>: mov 0x1c(%esp),%edx
0x08048423 <+83>: xor %gs:0x14,%edx
0x0804842a <+90>: jne 0x8048431 <main+97>
0x0804842c <+92>: mov -0x4(%ebp),%ebx
0x0804842f <+95>: leave
0x08048430 <+96>: ret
0x08048431 <+97>: call 0x8048380 <__stack_chk_fail@plt>
继续运行
continue
continue 次数
次数为可以忽略断点的次数。
监视点
watch <表达式>
<表达书>发生变化是暂停运行,此处<表达式>的意识是常量或变量等。
awatch <表达式>
<表达式>被访问、改变是暂停运行。
rwatch <表达式>
<表达式>被访问时暂停运行。
(gdb) rwatch strcpy
Hardware read watchpoint 5: strcpy
Hardware read watchpoint 5: strcpy
删除断点和监视点
(gdb) delete 2
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
3 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
4 breakpoint keep y 0x0804840f in main at TestStrcpy.c:23
5 read watchpoint keep y strcpy
(gdb) delete 5
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
3 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
4 breakpoint keep y 0x0804840f in main at TestStrcpy.c:23
(gdb)
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
3 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
4 breakpoint keep y 0x0804840f in main at TestStrcpy.c:23
5 read watchpoint keep y strcpy
(gdb) delete 5
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
3 breakpoint keep y 0x080483d0 in main at TestStrcpy.c:16
breakpoint already hit 1 time
4 breakpoint keep y 0x0804840f in main at TestStrcpy.c:23
(gdb)
改变变量的值
set variable <变量>=<值>
(gdb) p arr
$14 = "\000\000\371\204\004\b"
(gdb) p *arr
$15 = 0 '\000'
(gdb) p arr[0]
$16 = 0 '\000'
(gdb) set variable arr[1] = 23
(gdb) p arr[1]
$17 = 23 '\027'
(gdb) set variable arr[0] = 100
(gdb) p arr[0]
$18 = 100 'd'
(gdb) set variable arr[0] = 0
(gdb) p arr[0]
$19 = 0 '\000'
$14 = "\000\000\371\204\004\b"
(gdb) p *arr
$15 = 0 '\000'
(gdb) p arr[0]
$16 = 0 '\000'
(gdb) set variable arr[1] = 23
(gdb) p arr[1]
$17 = 23 '\027'
(gdb) set variable arr[0] = 100
(gdb) p arr[0]
$18 = 100 'd'
(gdb) set variable arr[0] = 0
(gdb) p arr[0]
$19 = 0 '\000'
生成内核转储文件
(gdb) generate-core-file
Saved corefile core.4063
Saved corefile core.4063