1序言:
通过前面一节第六课 GDB调试 (下)文章,可以掌握理解了gdb调试:怎么启动、运行,打断点、查看变量、甚至改变变量等的知识,今天来大概讲解下调试bug的类型。
2知识点:
2.1 就像之前所说的没有任何一个程序员敢打包票自己写的代码是没任何bug,bug总会有意无意的出现在我们眼前,当程序运行结果于我们预期结果不一样的时候这时候我们就应该调试,总的来说bug分为:语法错误、逻辑错误、硬件异常;
3原理:
3.1 语法错误:一般情况下出现在编译的时候会有提示编译错误这时候我们就可以马上定位查看并解决;
3.2 逻辑错误:这种情况比较复杂有时候的逻辑错误是肉眼能看出来的,有时候是需要调试就可以出来的,还有时候要经过多次调试找到bug产生环境的时候才出来,也就是说正式环境跟调试环境差别而增加调试难度。
3.3 硬件异常:这种问题在一般的设备是比较容易调试,特别是在高级语言中可以异常捕获,但是在低级语言是比较难点的!
接下来看看这几种情况的调试。
4实践:
4.1 语法错误
4.1.1 新建如下test.c文件,并输入:
#include <stdio.h> int main(void) { int a = 10; printf("a:%f",a); return 0; }
4.1.2 编译将会产生错误,提示在main函数中找不到print函数,修正下即可:
4.2 逻辑错误
4.2.1 重新编写test.c文件,输入如下:
#include <stdio.h> int main(void) { int i; char str[6] = "hello"; char reverse_str[6] = ""; printf("%s\n",str); for(i = 0;i < 5;i++) { reverse_str[5-i] = str[i]; } printf("%s\n",reverse_str); return 0; }
4.2.2 编译后执行查看结果没有任何输出:
4.2.3 调试程序:gdb test.c,并查看行好打断点,我们在第13行打断点:
4.2.4 经过上面打印变量输出“\000olleh",大家就可以想到,原因是由于字符串结尾\0引起的,此时我们在str最大下标处不要5开始就可以解决,修改后编译运行如下:
4.3 段错误
4.3.1 重新编辑test.c文件,输入如下:
#include <stdio.h> void test(){ int *p = NULL; *p = 100;} int main(void) { test(); return 0;
}
4.3.2 编译运行报错,提示段错误。接下来进行调试跟踪,这里可以直接加载文件运行,在段错误的地方会暂停,此时我们打印相关信息查看即可。
4.3.4 修改*p初始值即可,特别注意:有时段错误可能不在当前报错会在以后代码运行中导致错误。
4.4 core文件调试
4.4.1 查看当前是否有core文件,file size为0说明没有:
4.4.2 此时没就需要设置core文件:
ulimit -c unlimited #设置
4.4.3 直接运行程序回报段错误(core dumped),此时也会在当前目录生成core文件。开始调试:gdb test core.268181
这个core文件很有用,它会保存之前的环境更有利于调试,接近真实。这里注意知识点core的查看以及设置、加载调试。