常用的调试技巧(如何检测bug)(一)

简介: 常用的调试技巧(如何检测bug)

1. 什么是bug?

7d1f75ad62e74ce196fd9bb0304823f0.png 第一次被发现的导致计算机错误的飞蛾,也是第一个计算机程序错误。


1944年世界上第一台计算机马克1号诞生,在世界上第一位女程序员格蕾丝-霍普接手下,顺利改造成马克二号,


1946年的一天,霍普敲代码的时候发现计算机发生了故障,就在马克二号的继电器触点里,找到了一只被夹扁的小飞蛾。


正是这只小虫子卡住了机器的运行。


霍普顺手将飞蛾夹在工作笔记里,而备注的意思是臭虫,正是这一奇怪的称呼,奠定了Bug这个词在计算机世界的地位,bug也变成无数苦逼工程师的噩梦。这就是第一个bug的诞生。


2. 调试是什么?有多重要?


所有发生的事情都一定有迹可循,如果问心无愧,就不需要掩盖也就没有迹象了,如果问心有愧, 就必然需要掩盖,那就一定会有迹象,迹象越多就越容易顺藤而上,这就是推理的途径。 顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。

一名优秀的程序员是一名出色的侦探。

       每一次调试都是尝试破案的过程

我们是如何写代码的?

76bfa4d82d0d446b938d6fe5b93be9e3.png

又是如何排查出现的问题的呢?

4e860b9d331d4281abfadf028c6673a0.png

拒绝-迷信式调试!!!!


2.1 调试是什么?

调试(英语:Debugging / Debug),又称除错,是发现和减少计算机程序或电子仪器设备中程序 错误的一个过程


2.2 调试的基本步骤

发现程序错误的存在

以隔离、消除等方式对错误进行定位

确定错误产生的原因

提出纠正错误的解决办法

对程序错误予以改正,重新测试

2.3 Debug和Release的介绍。

Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。 Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优 的,以便用户很好地使用。


代码:

#include <stdio.h>
int main()
{
 char *p = "hello bit.";
 printf("%s\n", p);
 return 0;
}

上述代码在Debug环境的结果展示:

0c84807b88424b57b5d24154c9bce8ae.png

上述代码在Release环境的结果展示

78b2dbc36dac49849e7e6b0d3b3fbfbe.pngDebug和Release反汇编展示对比:

7a9dd6b866d141f2bca2a646cc47901e.png

所以我们说调试就是在Debug版本的环境中,找代码中潜伏的问题的一个过程。

那编译器进行了哪些优化呢?

请看如下代码:

#include <stdio.h>
int main()
{
    int i = 0;
    int arr[10] = {0};
    for(i=0; i<=12; i++)
   {
        arr[i] = 0;
        printf("hehe\n");
   }
    return 0;
}

如果是 debug 模式去编译,程序的结果是死循环。

如果是 release 模式去编译,程序没有死循环。

那他们之间有什么区别呢?

就是因为优化导致的。

25289a42d236492cb8bb7a7cbbf948e5.png

变量在内存中开辟的顺序发生了变化,影响到了程序执行的结果。

3. Windows环境调试介绍

       注:linux开发环境调试工具是gdb,后期课程会介绍。

3.1 调试环境的准备

867bfa05efe445819c27e4523c1986d6.png

在环境中选择 debug 选项,才能使代码正常调试。

3.2 学会快捷键

1fb9a6bba2df44babe0122d214fa2b9f.png

最常使用的几个快捷键:


F5 启动调试,经常用来直接跳到下一个断点处。

F9 创建断点和取消断点 断点的重要作用,可以在程序的任意位置设置断点。 这样就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

F10 逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。

F11 逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部(这是最 长用的)。

CTRL + F5 开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。


想知道更多快捷键?点击我哟


3.3 调试的时候查看程序当前信息

3.3.1 查看临时变量的值 在调试开始之后,用于观察变量的值。

在调试开始之后,用于观察变量的值

2ad4fcca1a664b4d8b8a6d04ed09dfd2.png

3.3.2 查看内存信息

在调试开始之后,用于观察内存信息

f98164e0fff044258128fe726f43eca4.png

3.3.3 查看调用堆栈

4ac9fa0e2249477cb6aab9fd32f64d29.png

通过调用堆栈,可以清晰的反应函数的调用关系以及当前调用所处的位置

3.3.4 查看汇编信息

在调试开始之后,有两种方式转到汇编:

(1)第一种方式:右击鼠标,选择【转到反汇编】:

e6de1cbe48b54f0cbc735a4194e5591d.png

(2)第二种方式:

0104c9d29ef14cb5a754a8f7690180c3.png

可以切换到汇编代码。

3.3.5 查看寄存器信息

a110fb6f32b34de28ea7dbf936b1b20d.png

可以查看当前运行环境的寄存器的使用信息

相关文章
|
4月前
|
编译器
你正在调试XXX的发布版本,如果在启用 仅我的代码 的同时,使用通过编译器优化的发布版本
你正在调试XXX的发布版本,如果在启用 仅我的代码 的同时,使用通过编译器优化的发布版本
46 0
|
7月前
|
安全 程序员 C++
bug的定义以及VS调试方法
bug的定义以及VS调试方法
167 1
|
小程序 Android开发 iOS开发
小程序 | 小程序修复了一些bug
前段时间,有朋友反应小程序的今天吃个啥有bug,不能正常使用。
146 0
|
IDE 编译器 程序员
该学会是自己找bug了(vs调试技巧)
该学会是自己找bug了(vs调试技巧)
123 0
|
NoSQL 安全 开发工具
乐动ld06激光雷达sdk改bug记录分享
乐动ld06激光雷达sdk改bug记录分享
235 0
乐动ld06激光雷达sdk改bug记录分享
|
程序员
常用的调试技巧(如何检测bug)(二)
常用的调试技巧(如何检测bug)