1、什么是bug?
第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。
感兴趣的小伙伴可以看一下下面这篇文章,链接放下面了。
注:
2、调试是什么?有多重要?
所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧,
就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径。
顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。
一名优秀的程序员是一名出色的侦探。
每一次调试都是尝试破案的过程。
我们是如何写代码的?
又是如何排查出现的问题的呢?
拒绝-迷信式调试!!!!
2.1 调试是什么?
调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序
错误的一个过程。
2.2 调试的基本步骤
发现程序错误的存在
以隔离、消除等方式对错误进行定位
确定错误产生的原因
提出纠正错误的解决办法
对程序错误予以改正,重新测试
2.3 Debug和Release的介绍。
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优
的,以便用户很好地使用。
1. #include <stdio.h> 2. int main() 3. { 4. char *p = "hello bit."; 5. printf("%s\n", p); 6. return 0; 7. }
上述代码在Debug环境的结果展示:
上述代码在Release环境的结果展示:
Debug和Release反汇编展示对比:
所以我们说调试就是在Debug版本的环境中,找代码中潜伏的问题的一个过程。
那编译器进行了哪些优化呢?
请看如下代码:
1. #include <stdio.h> 2. int main() 3. { 4. int i = 0; 5. int arr[10] = { 0 }; 6. for (i = 0; i <= 12; i++) 7. { 8. arr[i] = 0; 9. printf("hehe\n"); 10. } 11. return 0; 12. }
如果是 debug 模式去编译,程序的结果是死循环。
如果是 release 模式去编译,程序没有死循环。
那他们之间有什么区别呢?
就是因为优化导致的。
首先我们先看看在Debug中为什么会出现死循环:
1. #include <stdio.h> 2. int main() 3. { 4. int i = 0; 5. int arr[10] = { 0 }; 6. for (i = 0; i <= 12; i++) 7. { 8. arr[i] = 0; 9. printf("hehe\n"); 10. } 11. return 0; 12. }
从这段代码我们可以看到,数组会发生越界访问,这就导致了地址的不确定性。
通过调试我们发现:
在越界访问的过程中,arr[12]的值一直和i的值一样,说明了它们两个共用了同一个地址,所以在arr[12]=0的时候i又等于0了,循环重新开始,也就出现了死循环!!!
那么,在Release中则是对代码进行了优化。看它们两个的大小就可以看出来不同。
Release中是对代码中的变量的地址进行了更换,我们可以通过看i和arr[12]的地址得到:
经过Release 的优化后,两者的地址不一样了,就不会出现死循环了。