前言
程序中除了一目了然的bug之外都需要借助一定的调试手段来分析到底错在哪里。到目前为止,我调试php代码只有一种方法:根据程序出错时的现象假设出错原因,然后在代码中适当的位置插入printf或者echo,执行程序并分析打印结果。(这里声明一下php的代码出错类型:我单纯只得代码执行逻辑和我预期的不符合,而不是说语法上的error错误,那种低级错误直接查日志即可)。
这里介绍一种很强大的调试工具gdb,可以完全操控程序的运行,并且随时可以查看程序中所有的内部状态,比如各变量的值,传给函数的参数,当前执行的代码等
单步执行和跟踪函数调用
老实说,会了这个基本上就可以用gdb调试90%以上的acm代码了
gdb基本命令1
start:开始执行程序,停在main函数第一行语句前面等待命令
list:列出源代码,接着上次的位置往下列,每次列10行
next(或n):执行下一行语句
print(或p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
display 变量名:跟踪某个变量,每次停下来都显示它的值
undisplay 跟踪显示号:取消跟踪显示
step(或s):执行下一行语句,如果有函数调用则进入到函数中
finish:连续运行到当前函数返回为止,然后停下来等待命令
quit(或q):退出gdb调试环境
函数调用实例
#include <stdio.h>
int add_rang(int low, int high)
{
int i, sum;
for (i = low; i <= high; i ++) {
sum += i;
}
return sum;
}
int main()
{
int num1, num2;
num1 = add_rang(1, 10);
num2 = add_rang(1, 100);
printf("num1=%d\n num2=%d\n", num1, num2);
return 0;
}
很简单的代码,num1计算从1加到10,num2计算从1加到100
运行结果:
很诡异的结果,如果c功底稍微强一点的人都能看出上面代码是有问题的,但是这里我们用gdb调试运行一下
在编译时要加上-g选项,生成的可执行文件才能用gdb进行源码级调试:
gcc -Wall -g -o 2 2.c
下面是我gdb调试的过程:
很明显的错误出来了,sum变量没有赋初值0
断点
这里断点可不是张敬轩唱那首断点,而是程序调试的精髓所在
gdb基本命令2
break(或b)行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
continue(或c):从当前位置开始连续运行程序
delete breakpoints 断点号:删除断点
info:查看当前设置了哪些断点
断点调试实例
#include <stdio.h>
int main()
{
int i;
char input[5];
scanf("%s", input);
for (i = 0; i < 100000;) {
i += 1;
}
printf("%s\n", input);
return 0;
}
程序作用:只是为了联系gdb的断点设置,我调试代码的时候如果想跳过多余for循环怎么办,很简单,断点
好的,下面是gdb断点调试过程:
我一个简单的break和continue跳过了恶心无用的for循环,呵呵
查看设置的断点:
参考书籍
Linux c编程一站式学习 http://learn.akae.cn/media/index.html