调试和测试linux程序的5个阶段
1.测试:找出程序中存在的错误或缺陷
2.固化:让程序的错误可重现
3.定位:确认相关的代码行
4.纠正:修改代码纠正错误
5.验证:确定修改解决了问题
采样法:
在程序中增加打印输出一些相关信息
利用编译器标志可以方便的添加,删除调试代码
例
#define BASIC_DEBUG 1
#define EXTRA_DEBUG 2
#define SUPER_DEBUG 4
#if (DEBUG & EXTRA_DEBUG)
#endifprintf...
C语言预处理器预定义的一些宏,可以帮助确认错误
__LINE__ 代表当前行号的十进制常数
__FILE__ 代表当前文件名的字符串
__DATE__ mmm dd yyy格式的字符串,代表当前日期
__TIME__ hh:mm:ss格式的字符串,代表当前时间
例如printf("compiled: "__DATE__" at " __TIME__"\n");
程序受控执行 GDB
为了能够调试程序,在编译代码时加上一个或多个特殊的编译器选项,其作用是在程序中添加额外的调试信息。这些信息包括各种符号和源代码行号,调试器将利用这些信息向用户显示程序已经执行到到源代码的位置。
-g是一个常用的参数,在编译每个需要调试的源文件时都加上这个选项。它将使用特殊版本的C语言标准库以提供库函数中的调试支持。
调试信息的加入会可执行程序的长度成倍增加,但是程序所需要的内存数量还是一样的。
GDB
内存调试1.在编译时加入-g参数
2.gdb ***
3.run *** *** *** //可以run会将后面所带的参数传递给程序
4.栈跟踪 在发生错误的地方使用backtrace可以知道程序是如何到达这里的
5.检查变量 print a //变量名
输出多个变量print array[0]@5//从数组的0开始输出5个变量
6.列出源码 list,可以提供参数比如行号或者函数名 它将显示指定位置前后的代码
7.设置断点,可用help breakpoint查询帮助,最简单的break + 行号。可以再指定的位置添加断点
8.进入断点后可用cont继续执行命令
9.在进入断点后可使用display a,来设置每次进入断点时自动显示a
10.commands命令可以使程序到达断点时自动执行设置的命令
(gdb) commmands
> cont
> end//用end结束命令
11查看设置的break和display,
(gdb) info display
(gdb) info break
12禁用break和display 禁用 disable 删除 delete 使能 enable
(gdb) disable break 1
(gdb) disable display 1
13用调试器打补丁
(gdb) commands 2
> set variable n = n + 1//在断点处是变量自增一
> cont
> end
1.ElectricFence函数库
在编译时链接上它的函数库libefence.a那么在运行时就会得到响应,用gdb时也可以找出问题所在
gcc -g -o efence efence.c -lefence
2.valgrind工具
使用如valgrind --leak-check=yes -v ./checker 就可以得到问题所在