GDB调试及其调试脚本的使用
2013年04月29日 22:07:20 i龙家小少
请点原文链接:
https://blog.youkuaiyun.com/longerzone/article/details/8867790
一、GDB调试
1.1. GDB 概述
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX/Linux平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。
一般来说,GDB主要帮忙你完成下面四个方面的功能:
1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、动态的改变你程序的执行环境。
从上面看来,GDB和一般的调试工具没有什么两样,基本上也是完成这些功能,不过在细节上,你会发现GDB这个调试工具的强大,大家可能比较习惯了图形化的调试工具,但有时候,命令行的调试工具却有着图形化工具所不能完成的功能。让我们一一看来。
1.2.GDB 使用示例
使用一个简单的判断来测试一下:文件名gdbtest.c
-
#include "stdio.h" -
int main() -
{ -
int x=3; -
if(x<4) -
printf("x is less than 4\n"); -
else -
printf("x is biger than 4\n"); -
}
程序很简单,设置x=3,然后判断x是否比4小,若比4小则输出”x is less than 4“,若比4大,则输出”x is biger than 4“ ,程序很无聊,但是我们可以用来做GDB的测试!
注: 编译的时候需要使用-g选项,我使用的是: gdb -g3 gdbtest.c -o gdbtest
使用GDB调试:
-
#gdb gdbtest <------- 启动GDB -
GNU gdb (GDB) 7.5-ubuntu -
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://www.gnu.org/software/gdb/bugs/>... -
Reading symbols from /home/long/gdbtest...done. -
(gdb) l <------- l命令相当于list,从第一行开始例出原 -
码 -
1 #include "stdio.h" -
2 int main() -
3 { -
4 int x=3; -
5 if(x<4) -
6 printf("x is less than 4\n"); -
7 else -
8 printf("x is biger than 4\n"); -
9 } -
(gdb) break 5 <------- 设置断点,在源程序第5行处。 -
Breakpoint 1 at 0x8048935: file gdbtest.c, line 5. -
(gdb) run <------- 运行程序,也可以用简写r -
Starting program: /home/long/gdbtest -
Breakpoint 1, main () at gdbtest.c:5 <------- 其实停在第一个断点,在第5行 -
5 if(x<4) -
(gdb) info break <------- 查看断点的信息 -
Num Type Disp Enb Address What -
1 breakpoint keep y 0x08048935 in main at gdbtest.c:5 -
breakpoint already hit 1 time -
(gdb) print x <------- 打印x的值(print 也可以用其简写p)>,这时候x等于上面赋值的3 -
$1 = 3 -
(gdb) print &x <------- 打印x的地址 -
$2 = (int *) 0xbffff21c -
(gdb) x/4x 0xbffff21c <------- 查看从0xbffff21c开始的4*4个字节的值 -
0xbffff21c: 0x00000003 0x0804a000 0x00000000 0x00000000 <------- x为int值,为4个字节 -
,所以x的值等于0x00000003,我们可以看到此时x等于3 -
(gdb) set x=5 <------- 我们设置x=5 -
(gdb) print x <------- 打印x的值,可以看到x已经被改成5了 -
$3 = 5 -
(gdb) x/4x 0xbffff21c -
0xbffff21c: 0x00000005 0x0804a000 0x00000000 0x00000000 -
(gdb) n <------- 单条语句执行,next命令简写。 -
8 printf("x is biger than 4\n"); -
(gdb) c <------- 继续运行程序,continue命令简写。 -
Continuing. -
profiling:/home/zhouyl:Cannot create directory -
profiling:/home/zhouyl/NicholClass/error_test/gdb/gdbtest.gcda:Skip -
x is biger than 4[Inferior 1 (process 9265) exited with code 01] <------- 程序输出x is biger than 4,因为此时x已经被改为5了 -
(gdb) q <------- 退出gdb -
#
在上述GDB调试测试中,我们可以将x的值改为5,然后程序的输出变为 x is biger than 4 。很有趣又很强大是不?
1.3.GDB 更多知识点总结(不断搜集)
1.3.1 GDB 调试如何传参数?
我们仍然使用示例来演示:
示例的代码很简单:test.c
-
#include <stdio.h> -
int main(int argc, char **argv) -
{ -
int i=0; -
i=atoi(argv[1]); -
i = i + 1; -
printf("The value after add the first arg is : %d\n",i); -
i=atoi(argv[2]); -
i = i - 1; -
printf("The value after minus the second arg is : %d\n",i); -
return 0; -
}
示例中我们分别打印第一个参数加1和第二个参数减1 的值。
我们使用gdb调试,在进入调试后 使用set args 111 1的方法设置参数
-
#gcc -g3 test.c -o test -
#gdb test <------- 正常开始调剂程序 -
GNU gdb (GDB) 7.5-ubuntu -
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://www.gnu.org/software/gdb/bugs/>... -
Reading symbols from /tmp/test...done. -
(gdb) set args 111 1 <------- 在调试时给程序传入参数 -
(gdb) run -
Starting program: /tmp/test 111 1 -
The value after add the first arg is : 112 -
The value after minus the second arg is : 0 -
[Inferior 1 (process 9667) exited normally] -
(gdb) q -
#
或者我们可以使用 gdb --args ./test 111 1的方法
-
gdb --args ./test 111 1 -
GNU gdb (GDB) 7.5-ubuntu -
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://www.gnu.org/software/gdb/bugs/>... -
Reading symbols from /tmp/test...done. -
(gdb) run -
Starting program: /tmp/test 111 1 -
The value after add the first arg is : 112 -
The value after minus the second arg is : 0 -
[Inferior 1 (process 10784) exited normally] -
(gdb) q
二、GDB调试脚本的使用
下面我们对第一章中的gdbtest.c文件使用gdb脚本调试,其实很简单我们只要把需要的操作放到一个文件中,比如叫做 gdbtest.sh
-
break 5 -
run -
set x=5 -
c -
q
那么我们如何使用?其实很简单,我们在使用时,不用直接gdb gdbtest ,而使用 gdb ./gdbtest -command=gdbtest.sh
其实还有种方法,我们直接在脚本中添加所要调试的文件信息,此时的 gdbtest.sh内容为:
-
file gdbtest <----- 制定目标文件为gdbtest -
break 5 -
run -
set x=5 -
c -
q
而我们调试使用的命令就简单了,直接使用gdb -x gdbtest.sh 即可!
三、GCOV的使用
3.1 gcov是什么?
- Gcov is GCC Coverage
- 是一个测试代码覆盖率的工具
- 是一个命令行方式的控制台程序
- 伴随GCC发布,配合GCC共同实现对C/C++文件的语句覆盖和分支覆盖测试;
- 与程序概要分析工具(profiling tool,例如gprof)一起工作,可以估计程序中哪一段代码最耗时;
注:程序概要分析工具是分析代码性能的工具。
3.2 gcov能做什么?
gcov可以统计:
- 每一行代码的执行频率
- 实际上哪些代码确实被执行了
- 每一段代码(section code)的耗时(执行时间)
因此,gcov可以帮你优化代码,当然这个优化动作还是应该有开发者完成。
3.3 gcov 使用
我们继续使用第一章中的gdbtest.c文件,使用gcov时候,在编译时使用 gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c
-
#ls -
gdbtest.c gdbtest.sh -
#gcc -g3 -fprofile-arcs -ftest-coverage gdbtest.c <-------- 使用-fprofile-arcs -ftest-coverage 参数添加gcov信息,其实可以不使用-g参数,我示例中需要使用gdb调试,所以添加了 -
#./a.out -
x is less than 4 -
#gcov gdbtest -
File‘gdbtest.c’ -
已执行的行数:83.33% (共 6 行) -
Creating 'gdbtest.c.gcov' -
# cat gdbtest.c.gcov -
-: 0:Source:gdbtest.c -
-: 0:Graph:gdbtest.gcno -
-: 0:Data:gdbtest.gcda -
-: 0:Runs:1 -
-: 0:Programs:1 -
-: 1:#include "stdio.h" -
1: 2:int main() <----------- "1"为本行运行次数 -
-: 3:{ -
1: 4: int x=3; -
1: 5: if(x<4) -
1: 6: printf("x is less than 4\n"); -
-: 7: else -
#####: 8: printf("x is biger than 4\n"); <-----------"#####"代表此行未运>行 -
1: 9:} -
# -
#gdb ./a.out -command=gdbtest.sh <-------- 使用上面的脚本调试,其 -
实我们的目的是运行 else ,然后看区别! -
GNU gdb (GDB) 7.5-ubuntu -
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://www.gnu.org/software/gdb/bugs/>... -
Reading symbols from /home/long/gcovtest/a.out...done. -
Breakpoint 1 at 0x80489dd: file gdbtest.c, line 5. -
Breakpoint 1, main () at gdbtest.c:5 -
5 if(x<4) -
x is biger than 4 -
[Inferior 1 (process 10165) exited with code 01] -
#gcov gdbtest <----------- 多运行几次a.out或者 -
使用脚本,后想重新看看最新的测试代码覆盖率,需要重新 gcov gdbtest -
File‘gdbtest.c’ -
已执行的行数:100.00% (共 6 行) -
Creating 'gdbtest.c.gcov' -
#cat gdbtest.c.gcov -
-: 0:Source:gdbtest.c -
-: 0:Graph:gdbtest.gcno -
-: 0:Data:gdbtest.gcda -
-: 0:Runs:2 -
-: 0:Programs:1 -
-: 1:#include "stdio.h" -
2: 2:int main() -
-: 3:{ -
2: 4: int x=3; -
2: 5: if(x<4) -
1: 6: printf("x is less than 4\n"); <----------- 使用脚本运行时,此>行未执行,所以还是运行了1次 -
-: 7: else <----------- 其实本行else是运行>过一次的,但是gcov 统计时把本行与下一行打印放在一起计时的! -
1: 8: printf("x is biger than 4\n"); -
2: 9:} -
#
注:
【1】陈浩专栏: "用GDB调试工具"
一、 http://blog.youkuaiyun.com/haoel/article/details/2879
二、http://blog.youkuaiyun.com/haoel/article/details/2880
三、http://blog.youkuaiyun.com/haoel/article/details/2881
四、http://blog.youkuaiyun.com/haoel/article/details/2882
五、http://blog.youkuaiyun.com/haoel/article/details/2883
六、http://blog.youkuaiyun.com/haoel/article/details/2884
七、http://blog.youkuaiyun.com/haoel/article/details/2885
【2】http://blog.youkuaiyun.com/zhujinghao09/article/details/8461543
【3】http://blog.youkuaiyun.com/ganggexiongqi/article/details/8846001
【4】http://blog.youkuaiyun.com/yukin_xue/article/details/7653482
本文介绍了GDB调试及其调试脚本的使用,以及GCOV的使用。GDB是UNIX下强大的程序调试工具,可完成启动程序、设置断点等功能,还能通过脚本调试。GCOV是测试代码覆盖率的工具,可统计代码执行频率、耗时等,帮助优化代码。
606

被折叠的 条评论
为什么被折叠?



