GDB概述
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。如果你是在UNIX平台下做软件,你会用GDB这个调试工具来调试你的软件。
编译时选项
一般来说GDB主要调试的是C/C++的程序。要调试C/C++的程序,在编译时,就必须要把调试信息加到可执行文件中。使用编译器(cc/gcc/g++)的 -g 参数可以做到这一点。如:
> cc -g hello.c -o hello (C)
> g++ -g hello.cpp -o hello (C++)
如果没有-g,你将看不见程序的函数名、变量名,所代替的全是运行时的内存地址.
启动GDB
1、gdb <program>
program也就是你的执行文件,可以带全路径。
2、gdb <program> core
用gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump 后产生的文件。后面会专门介绍调试core。
3、gdb <program> <PID>
如果你的程序是一个服务程序,那么你可以指定这个服务程序运行时的进程ID。gdb会自动attach上去,并调试他。program应该在PATH环境变量中搜索得到。后面会专门介绍调试运行中的程序。
GDB启动时,可以加上一些GDB的启动开关
-symbols <file>
-s <file>
从指定文件中读取符号表。
-se file
从指定文件中读取符号表信息,并把他用在可执行文件中。
-core <file>
-c <file>
调试时core dump的core文件。
-directory <directory>
-d <directory>
加入一个源文件的搜索路径。默认搜索路径是环境变量中PATH所定义的路径。
设置GDB到环境变量
1、设置程序运行参数
set args 可指定运行时参数。(如:set args 10 20 30 40 50)
show args 命令可以查看设置好的运行参数。
2、运行环境
path <dir> 可设定程序的运行路径。
show paths 查看程序的运行路径。
set environment varname [=value] 设置环境变量。
如:set env USER=hchen
show environment [varname] 查看环境变量。
GDB常用命令
1、显示源代码行号: list/l
几种用法:
默认表示显示当前行号开始的程序
list <linenum>:显示程序第linenum行的周围的源程序。
list <linenum>:显示函数名为function的函数的源程序。
list -:显示当前行前面的源程序。
list <first>, <last>:显示从first行到last行之间的源代码。
list , <last>:显示从当前行到last行之间的源代码。
list +:往后显示源代码。
(gdb) list
11 static void sub()
12 {
13 int *p=NULL;
14 int i;
15 for(i=0;i<10;i++);
16
17 add(p);
18 }
一般默认是显示10行,使用下面命令可以设置一次显示源程序的行数。
set listsize <count>
show listsize:查看当前listsize的设置。
(gdb) set listsize 15
(gdb) show listsize
Number of source lines gdb will list by default is 15.
2、设置断点:break/b <function>;b <filenam>:<line>
break <function>
到指定函数停住
break <filenam>:<line>
到指定文件的line行停住
break <...> if <condition>
<...>可以是上述的参数: <function> or <line>等,condition表示条件,在条件成立时停住。
(gdb) b sub
Breakpoint 1 at 0x80483ee: file debug_core.c, line 13.
(gdb) b debug_core.c:17
Breakpoint 2 at 0x8048408: file debug_core.c, line 17.
(gdb) b if aaa=50
Breakpoint 3 at 0x8048422: file debug_core.c, line 18.
查看断点:info b
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x080483ee in sub at debug_core.c:13
2 breakpoint keep y 0x08048408 in sub at debug_core.c:17
3、设置观察点:watch
watch <expr>
为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。
rwatch <expr>
当表达式(变量)expr被读时,停住程序。
awatch <expr>
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前所设置了的所有观察点。
(gdb) watch aaa
Hardware watchpoint 1: aaa
4、指定源文件的路径: directory/dir
dir:清除所有的自定义的源文件搜索路径信息。
dir <dirname>:加一个源文件路径到当前路径的前面。指定多个路径,可以使用”:”
show dir:显示定义了的源文件搜索路径。
(gdb) dir /opt:/usr/include/
Source directories searched: /opt:/usr/include:$cdir:$cwd
(gdb) show dir
Source directories searched: /opt:/usr/include:$cdir:$cwd
5、搜索源代码
GDB还提供了源代码搜索的命令:
forward-search <regexp>
search <regexp>
向前面搜索。
reverse-search <regexp>
全部搜索。
其中,<regexp>就是正则表达式,也主一个字符串的匹配模式
6、查看源代码内存:info line
info line后面可以跟”行号”,”函数名”,”文件名:行号”,”文件名:函数名”,这个命令会打印出所指定的源码在运行时的内存地址。
(gdb) info line debug_core.c:sub
Line 12 of "debug_core.c" starts at address 0x80483e8 <sub> and ends at 0x80483ee <sub+6>.
7、查看源程序的当前执行码:disassemble
这个命令会把目前内存中的指令dump出来。
(gdb) disassemble sub
Dump of assembler code for function sub:
0x080483e8 <sub+0>: push %ebp
0x080483e9 <sub+1>: mov %esp,%ebp
0x080483eb <sub+3>: sub $0x18,%esp
0x080483ee <sub+6>: movl $0x0,-0x8(%ebp)
0x080483f5 <sub+13>: movl $0x0,-0x4(%ebp)
0x080483fc <sub+20>: jmp 0x8048402 <sub+26>
0x080483fe <sub+22>: addl $0x1,-0x4(%ebp)
0x08048402 <sub+26>: cmpl $0x9,-0x4(%ebp)
0x08048406 <sub+30>: jle 0x80483fe <sub+22>
0x08048408 <sub+32>: mov -0x8(%ebp),%eax
0x0804840b <sub+35>: mov %eax,(%esp)
0x0804840e <sub+38>: call 0x8048415 <add>
0x08048413 <sub+43>: leave
0x08048414 <sub+44>: ret
End of assembler dump.
8、维护断点:clear、delete、disable、enable
清除所有的已定义的停止点。
clear <function>
clear <filename:function>
清除所有设置在函数上的停止点。
clear <linenum>
clear <filename:linenum>
清除所有设置在指定行上的停止点。
delete [breakpoints] [range...]
删除指定的断点,breakpoints为断点号。如果不指定断点号,则表示删除所有的断点。range 表示断点号的范围(如:3-7)。其简写命令为d。
比删除更好的一种方法是disable停止点,disable了的停止点,GDB不会删除,当你还需要时,enable即可,就好像回收站一样。
disable [breakpoints] [range...]
disable所指定的停止点,breakpoints为停止点号。什么都不指定,表示disable所有的停止点。简写命令是dis.
enable [breakpoints] [range...]
enable所指定的停止点,breakpoints为停止点号。
enable [breakpoints] once range...
enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动disable。
enable [breakpoints] delete range...
enable所指定的停止点一次,当程序停止后,该停止点马上被GDB自动删除。
9、停止条件维护:condition和ignore
condition <bnum> <expression>
修改断点号为bnum的停止条件为expression。
condition <bnum>
清除断点号为bnum的停止条件。
ignore <bnum> <count>
表示忽略断点号为bnum的停止条件count次。
在GDB中运行shell命令
在gdb环境中,你可以执行shell命令,使用gdb的shell命令来完成:
shell <command string>
调用UNIX的shell来执行<command string>,环境变量SHELL中定义的UNIX的shell将会被用来执行<command string>,如果SHELL没有定义,那就使用UNIX的标准shell:/bin/sh。