1.什么是GDB?
GDB全称是GNU Project Debugger,当程序执行时,让你可以进入到另一个程序的内部查看,或者当一个程序崩溃的时候它在做什么。
GDB可以帮助你做如下四种主要的方面,来帮助你捕捉到bug:
1.启动你的程序,指定可能影响你行为的事情(设定初始的一些变量)
2.在特殊的条件的时候暂停你的程序执行(在端点的时候可以暂停,或者说是条件的暂停)
3.当程序暂停的时候,可以查看这个时候发生了什么(查询堆栈,变量)
4.通过改变程序中的参数,你可以通过实验得出某一个bug所产生的影响,然后继续执行(通过不同的设定,来得到不同的结果,本人理解为测试)
这个调试程序,可以由Ada, C, C++, Objective-C, Pascal(或者其他语言写成)。这个程序可以执行在一个相同的机器或者是一个远程的机器上。
2.使用GDB进行调试(快捷键ctrl+d可以退出GDB)
1.首先当然是一言不合就安装GDB:
1 sudo apt-get install gdb
2.接下来本文围绕着一个c语言文件开始调试
废话不说贴代码来看
#include<stdio.h> int add(int a,int b) { return a+b; } int main() { int i =0; int c =0; while(i<100) { c=add (i,c); printf("c %d",c); i++; } return c; }
$ gcc -g gdbtest.c -o mytest
生mytest文件,接下来进行调试
$ gdb mytest
在main处传入端点,运行到main,调试,其中breakpoint是break的全程,run是r的全程
(gdb) break main (gdb) r
运行到main处暂停
之后可以单步跟一下,s(step)
(gdb)s
单步了之后可以查看剩下的代码 l(list)
(gdb) l 4 return a+b; 5 } 6 int main() 7 { 8 int i =0; 9 int c =0; 10 while(i<100) 11 { 12 c=add (i,c); 13 printf("c %d",c);
之后单步进入到函数中,可以查看堆栈
(gdb) bt
#0 add (a=0, b=0) at gdbtest.c:4
#1 0x0000000000400568 in main () at gdbtest.c:12
可以通过print来打印变量的值
(gdb) print c
$1 = 1
保存断点(文件名为fig.dp)
(gdb)save breakpoint fig.dp
3.更近一步
断点可以通过函数名,文件内的行号来设置,也可以先指定文件名再指定行号,还可以指定与暂停位置的偏移量,或者用地址来设置。
(gdb) break 函数名
(gdb) break 行号
(gdb) break 文件名:行号
(gdb) break 文件名:函数名
(gdb) break +偏移量
(gdb) break -偏移量
(gdb) break *地址
如果不指定位置,则在当前行的下一行下断点
(gdb) break 11 //在十一行下端点 Breakpoint 2 at 0x400559: file gdbtest.c, line 11. //端点2的信息 (gdb) s //单步 10 while(i<100) //执行的语句 (gdb) c //continue,直接进行运行,到达断点停下 Continuing. Breakpoint 2, main () at gdbtest.c:12 12 c=add (i,c); (gdb) break +2 //在当前运行处下两行下断点 Breakpoint 3 at 0x40057f: file gdbtest.c, line 14. (gdb) break -1 //在当前行的前一行进行下断点 Note: breakpoint 2 also set at pc 0x400559. Breakpoint 4 at 0x400559: file gdbtest.c, line 11. (gdb) break *2 //在地址为0x2处下断 Breakpoint 5 at 0x2
接下来介绍一些条件断点
条件断点 (gdb) break 断点 if 条件 (gdb) break 14 if c>4 //当变量c大于4的时候,才在14行处断点停止仅在特定条件下中断。对于已存在的断点,可使用condition为其添加条件。 (gdb) break 断点编号 条件 而删除指定编号断点的触发条件同样使用condition。 (gdb) condition 断点编号 (gdb) condition 2 Breakpoint 2 now unconditional 查询断点(gdb) info break
监视点
要想找到变量在何处被改变,可以使用 watch 命令(监视点, watchpoint)。
(gdb) watch <表达式>
<表达式>发生变化时暂停运行。<表达式>的意思是常量或变量等。
(gdb) awatch <表达式>
<表达式>被访问、改变时暂停运行。
(gdb) rwatch <表达式>
<表达式>被访问时暂停运行。
(gdb) watch i >10 Hardware watchpoint 4: i >10 (gdb) c Continuing. Hardware watchpoint 4: i >10 Old value = 0 New value = 1 main () at gdbtest.c:10 10 while(i<100) (gdb) print i $1 = 11
1 (gdb) awatch i 2 Hardware access (read/write) watchpoint 5: i 3 (gdb) c 4 Continuing. 5 Hardware access (read/write) watchpoint 5: i 6 7 Old value = 11 8 New value = 12 9 main () at gdbtest.c:10 10 10 while(i<100)
删除断点和监视点
用 delete 命令删除断点和监视点。
(gdb) delete <编号>
显示栈帧
backtrace 命令可以在遇到断点而暂停执行时显示栈帧。此外,backtrace 的别名还有 where 和 info stack。
(gdb) backtrace
显示所有栈帧。
(gdb) backtrace N
只显示开头 N 个栈帧。
(gdb) backtrace -N
只显示最后 N 个栈帧。
(gdb) backtrace full
(gdb) backtrace full N
(gdb) backtrace full -N
不仅显示backtrace,还有显示局部变量。
显示栈帧之后,就可以看出程序在何处停止(即断点的位置),以及程序的调用路径。
显示寄存器
info registers可以显示寄存器。
(gdb) info registers
单步执行
单步执行指的是代码一行行的执行,有两种组成部分s和n,其中s是单步,可以进入函数,而n也是单步,但不进入函数内部。
调试的时候读取保存的断点
gdb hello2 -x fig.dp
要记住加上参数 -x
然后再去查看是否有断点
调试的时候设置参数
1 (gdb) set args a b c 2 (gdb) r
四.上图总结
五.参考文章
http://blog.csdn.net/u011068702/article/details/53931648
http://blog.csdn.net/hzhsan/article/details/7554328