[工具总结]浅析VS下的调试技巧(上篇)

3,778 阅读6分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

前言

        对于一个程序员来说,写代码固然重要,但其实熟悉调试更重要,本文旨在分享一波VS下调试技巧,以提高防范bug、调试纠错的意识与能力。

        笔者水平有限,难免存在纰漏,欢迎指正交流。

bug与调试

什么是bug

        计算机程序或电子仪器中的错误。

        想想自己在写代码的时候遇到过的bug,自己又是如何对待这些bug的呢?

当写的程序出现bug时:

调试是什么?有多重要?

        有些人可能还真就是这样写代码的: 

image.png

        要是盲干迟早💊,只会写bug不会调试,老板分分钟把你开了。

调试是什么?

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

image.png

        千万不要迷信式修改代码,以为这样就能解决掉bug,这样做只能一知半解,压根找不到问题根源所在,可能一时来看代码好像能跑了,但是遗留的问题如滚雪球一般只会越积越大,最后势如雪崩般摧毁一切,而其中没有一片雪花是无辜的(没有一个程序猿是无辜的)。 

1541405861-5374-img.png

调试的基本步骤

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

        顺着这条途径顺流而下就是犯罪,逆流而上,就是真相。

        一名优秀的程序员是一名出色的侦探。每一次调试都是尝试破案的过程。

1.发现程序错误的存在

(知道程序有错误)

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

(在觉得有可能的地方进行隔离或消除的方式测试是否有错误)

3.确定错误产生的原因

4.提出纠正错误的解决办法

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

        尽量不要直接删除你觉得没用的代码,最好先注释掉。

OIP-C (2).jfif

Debug和Release的介绍

        Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。

        Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。

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

VS环境调试介绍

最常使用的几个快捷键:

F5

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

        如果没有中断会一直执行到程序结束,一般需要与断点配合使用。

        注意一下,遇到scanf()的话也会停下来等待用户键入值,这时候就老老实实输入,别想着跳过scanf,不然你设计的时候为什么要加上scanf啊,况且要是忽略scanf很可能后面的代码就出问题了。

F9

创建断点(F9)和取消断点(ctrl + F9)

        可以在程序的任意位置设置断点,就可以使得程序在想要的位置随意停止执行,继而一步步执行下去。

        实际上,当确定某一处可能有问题,那么该处前面的代码应该没有问题,这时候就可以设置断点,直接到达目标处调试,如果还是逐步调试的话是不现实的,几十行代码尚可,然而数千行呢?

条件断点

        只有在满足预先设定的条件的时候断点生效,其余时候不生效。

比如,下面的断点只有在i == 8的时候才会让程序停止。

image.png

F10

        逐过程,通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句,比如遇到函数直接执行完跳到下一过程,不会让用户进入函数里调试。

F11

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

CTRL + F5

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

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

常用调试窗口如下

image.png

查看临时变量的值

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

自动窗口

        会根据上下文信息自动显示变量的值,进入调用函数后只显示当前函数内的变量。

局部变量窗口

        和自动窗口基本一致,不过只显示局部变量。

        实际上都不太灵活,更多时候用的是监视窗口。

        在监视窗口内可以按需求搜索查看变量的值与类型,甚至寄存器的值也可以查看,并且不受上下文信息限制,在被调函数中也能观察到主调函数中的变量。

image.png

        在查看数组内元素的时候可以用“,”+ 数字,数字是多少就能查看到数组多少个元素。可以用在函数传参传数组名的时候。

image.png

查看内存信息

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

image.png

查看调用堆栈

比如:

void test3()
{
    printf("haha");
}

void test2()
{
    test3();
}

void test1()
{
    test2();
}

int main()
{
    test1();
    return 0;
}

从下往上呈现调用关系。

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

image.png

image.png

查看汇编信息

进入调试后点开反汇编窗口即可观察汇编代码。

image.png

查看寄存器信息

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

image.png

多多动手,尝试调试,才能有进步

        一定要熟练掌握基础的调试技巧。

        初学者可能80%的时间在写代码,20%的时间在调试。

        但是一个程序员可能20%的时间在写程序,而80%的时间在调试。

        这里所讲的都是一些简单的调试。以后可能会遇到很复杂调试场景:比如多线程程序的调试等。

        所以需要多多使用快捷键,以提升效率。

        如若诸君不嫌弃的话,在下有篇讲解VS快捷技巧的小文章不知可否对您胃口,此处转移:


以上就是本文全部内容,感谢观看,你的支持就是对我最大的鼓励~

src=http___c-ssl.duitang.com_uploads_item_201708_07_20170807082850_kGsQF.thumb.400_0.gif&refer=http___c-ssl.duitang.gif