我们写代码时常常需要调试,Windows我们简单的用鼠标点点点就可以完成。在Linux下是如何使用调试?
首先需要调试器-gdb。(Linux的调试器不只有gdb一个,但是初学者可以先从这个使用学起)
gdb
gdb是UNIX及UNIX-like下的调试工具。
功能:
- 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
- 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
- 当程序被停住时,可以检查此时你的程序中所发生的事。
- 你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG
在使用gdb之前,要先将写好的程序进行编译,已确保程序没有错误和警告,并且要在编译时添加-g选项,生成调试信息,在用gdb调试器打开调试界面。
在使用gdb时有一些必要且方便的命令做已整理:
1)文件清单:
- list 行号:查看源代码,每次列十行,默认从上次接着列出
- list 函数名:查看函数的源代码
2)执行程序
- run:执行程序
- n:单条执行(类似于F10)
- s:进入函数调用(类似F11)
- q:退出调试
3)显示变量
- print 变量名:打印该变量此时的值
4)设置断点
- break 行号: 在该行加入断点
- break 函数名:在该函数处加入断点
- break 行号 表达式:在满足表达式的地方加断点
5)断点管理
- info break(i b):显示当前断点信息
delete 断点号:删除该断点(断点号在i b可查看)不带编号,将删除所有断点
6)函数调用
finish 结束执行当前函数,显示其返回值(如果有的话)
- call 函数名:调用该函数
还有一些复杂的命令,目前初步学习只掌握了这么些。下面具体调试一个例子来说明:
首先我们写一个程序,以斐波那契数列为例:
1
#include <stdio.h>
2 int fib(int n)
3 {
4 int i=0;
5 int ret=0;
6 for(i=0;i<=n;i++)
7 {
8 ret+=i;
9
10 }
11 return ret;
12 }
13 int main()
14 {
15 int arr[10]={0,1};
16 int i=0;
17 for(i=2;i<10;i++)
18 {
19 arr[i]=arr[i-1]+arr[i-2];
20 }
21 printf("arr[9]=%d\n",arr[9]);
22 printf("arr[9]=%d\n",fib(9));
23 return 0;
24 }
接下来,我们编译并生成调式信息,
无错误与警告直接运行看结果:
显然结果有问题,通过代码我们知道是调用的fib函数结果出错。
所以下来进行调试:
进入调试画面,可以在此输入命令,我们首先初步判断是函数出现错误,所以直接在函数出添加断点,并run开始执行,会自动执行停止在端点处。
之后可以执行一步,观察当前变量的值,
观察可以得出,第一和第二个fib应该值是1,显然出错了,所以下来我们quit退出,修改我们的代码。
显然这个求法根本就不对,是错误的思路,所以现在就要重新考虑思路编写代码了。
我在这里使用递归方式编写,顺便复习下求fib数。
现在结果就正确了。虽然Linux下调试不如vs下方便,但是各有各的长处。
实际上,我们经常写代码会遇到程序崩掉的情况,如果碰到这种情况,我们该如何调试呢?
core
比如我们用一段错误的代码来测试
#include <stdio.h>
int main()
{
int i=10;
int *a;
*a=i;
printf("%d\n",*a);
return 0;
}
编译显然通不过:并且报错告诉你是段错误,这些错误其实对于我们初学者非常常见,只要遇到一次积累下来以后就会避免出现错误,也不会在遇到报错时一脸懵逼。
接下来,我们使用ulimit命令查看当前用户进程限制
可以看到core file size的大小是0,此时我们要更改它。
更改成功。在运行,会产生一个core文件,
我们gdb源文件与生成的core文件,就可以观察到与之相关的错误信息。
这样,就能具体的看到是在代码的哪个地址处出现的段错误。
valgrind
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。
用下面一段代码来测试:
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 int fun()
5 {
6 int *p=malloc(sizeof(int));
7 p[10]=100;
8 }
9
10 int main()
11 {
12 fun();
13
14 printf("finish\n");
15 }
显然,我们使用了malloc没有释放,造成了内存泄漏,虽然程序编译没有报错,但内存泄漏多次积累可能会造成运行速度减慢或程序崩溃的情况,所以这种情况一定要避免,valgrind这个工具就是用来检测程序中是否有内存泄漏的情况。
可以看到申请了四个字节,没有释放,地址以及所在行号,非常清晰。总的来说,这个工具非常好用。