一.什么是bug
bug本意是"昆虫"或"虫子],现在一般是指在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题,简称程序漏洞。“Bug"的创始人格蕾丝.赫柏(Grace Murray Hopper),她是一位为美国海军工作的电脑专家,1947年9月9日,格蕾丝.赫柏对Harvard Mark II设置好17000个继电器进行编程后,技术人员正在进行整机运行时,它突然停止了工作。于是他们爬上去找原因,发现这台巨大的计算机内部一组继电器的触点之间有一只飞蛾,这显然是由于飞蛾受光和热的吸引,飞到了触点上,然后被高电压击死。所以在报告中,赫柏用胶条贴上飞蛾,并把"bug"来表示"一个在电脑程序里的错误”,"Bug"这个说法一直沿用到今天。
那我们发现程序漏洞的时候,该怎么解决呢?接下来我们先讲调试。
二.什么是调试
当我们发现程序中存在的问题的时候,那下一步就是找到问题,并修复问题。
这个找问题的过程叫称为调试,英文叫debug(消灭bug)的意思。
调试一个程序,首先是承认出现了问题,然后通过各种手段去定位问题的位置,可能是逐过程的调试,也可能是隔离和屏蔽代码的方式,找到问题所的位置,然后确定错误产生的原因,再修复代码,重新测试。
调试是一个动作,找问题的过程,找到这个问题之后解决问题,消灭这个问题。当我们准备调试的时候我们了解一下Debug和 Release。
三.Debug 和Release
在VS上编写代码的时候,就能看到有 debug和 release 两个选项,分别是什么意思呢?
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序;程序员在写代码的时候,需要经常性的调试代码,就将这里设置为debug,这样编译产生的是debug 版本的可执行程序,其中包含调试信息,是可以直接调试的。
Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。当程序员写完代码,测试再对程序进行测试,直到程序的质量符合交付给用户使用的标准,这个时候就会设置为 release,编译产生的就是 release版本的可执行程序,这个版本是用户使用的,无需包含调试信息等。
我们来写代码感受一下什么意思,当我们改成Debug版本的时候。
打开所在的文件夹
这里面存放的是编译出的Debug版本的程序。
当我们改成Release
打开所在的文件夹
Release文件里存放的是编译出的release版本的程序。
点开 Debug
点开Release
从中我们可以看到Debug版本文件大小要比Release版本大,这是因为我们上面说过Debug中含有调试信息。
我们来说一下它两个的区别:Debug版本当我们按F10调试的时候,比如循环会一步一步走,每一步都清清楚楚可以去观察,所有细节都可以看到,而Release版本不会对循环一步一步的走,会直接一趟出结果。
一般我们测试人员测试的是Release版本,而不是Debug版本。那我们到底该如何调试代码呢?请看下面。
四.VS调试快捷键
首先是环境的准备,需要一个支持调试的开发环境,我们使用的是VS,应该把VS上设置为Debug。
调试快捷键
我们先简单介绍一下调试最常使用的几个快捷键:
断点的作用是可以在程序的任意位置设置断点,打上断点就可以使得程序执行到想要的位置暂停执行,接下来我们
F9:创建断点和取消断点
就可以使用F10,F11这些快捷键,观察代码的执行细节。
条件断点:满足这个条件,才触发断点
F5:启动调试,经常用来直接跳到下一个断点处,一般是 和F9配合使用。
F10:逐过程◇通常用来处理一个过程,一个过程可以是一次函数调用,或者是一条语句。
F11:逐语句,就是每次都执行一条语句,但是这个快捷键可以使我们的执行逻辑进入函数内部。在函数调用的地
方,想进入函数观察细节,必须使用F11,如果使用F10,直接完成函数调用。
CTRL+F5:开始执行不调试,如果你想让程序直接运行起来而不调试就可以直接使用。
VS更多快捷键了解:http://blog.csdn.net/mrlisky/article/details/72622009
要熟练的使用它们,一般F9和F5配合使用的。我们先来看F9,当我们将鼠标按到哪一行,再按一下F9,左边会出现一个红点,如果再按一下F9就取消了,这就是设置断点和取消断点。
我们看上面的代码,当我们知道该代码出现Bug的时候,同时也知道不是第一个循环的问题,是第二个循环的问题,我们一般用F10进行调试一步一步的走,但是如果第一个循环要循环一万次呢?那我们岂不是要累死了才能一步一步走到第二个循环,所以我们直接在第二个循环处放置断点,当程序运行的时候直接跳到断点第二循环开始。
那怎么跳到断点呢?这个时候我们要用到F5快捷键,所以当我们按F9设置好断点之后,再按F5跳到断点处进行调试,这个时候我们就可以用F10一步一步观察细节了,前面的代码直接跳过,但是也都做完了,我们不观察。
从上面我们已经介绍过了F10和F11的定义,我们来看一下F10与F11的差异,其实它们两个的差异是谁调试细节更细。
例子
F10会直接执行函数调用,一步过,不会观察函数里面细节是什么。
当我们执行到函数语句的时候,按F11会进入函数内部,观察细节,它观察的力度会更细一些。
当我们设置两个断点的时候会出现什么情况呢?
当我们设置好断点之后,按F5它会它会跳到第一个断点,说明它是根据程序从上往下运行到第一个断点处,当我们再按一次F5它会来到第二个断点吗?
当我们多次按F5它不会跳到下一个断点,它会跟着循环回到第一个断点,说明F5是让它跳到执行逻辑上的下一个断点,并不是物理上的下一个断点。如果不想要再循环,可以去掉第一个断点,再按F5直接跳到第二个断点。
F10和F11仅仅只是遇到函数有区别,其他情况没有区别,想要进入函数内部观察要用F11,在函数内部一步一步观察的时候,用F10或者F11都可以。
我们也可以设置条件断点,比如想要观察循环第六次是否出现了问题,我们设置条件断点,条件为i == 5,当按下F5的时候,会直接跳到第六次循环开始。
这样我们调试会更加快捷,不用再循环很多次才到我们认为出现问题的循环次数。
五.监视和内存观察
在调试的过程中我们,如果要观察代码执行过程中,上下文环境中的变量的值,有哪些方法呢?这些观察的前提条件一定是开始调试后观察,我们来看个例子。
监视
我们按F10一步一步的走,通过监视窗口观察变量,这种过程我们就可以很好的观察变量的值是如何变化的。监视你给它一个合法的表达式也可以帮你计算出结果来。它可以让你很好的观察代码执行过程的变化。
内存
如果监视窗口看的不够仔细,也是可以观察变量在内存中的存储情况,还是在:调试 --> 窗口 --> 内存。打开内存窗口:
打开内存窗口后,要在地址栏输入:arr,&num,&c,这类地址,就能观察到该地址处的数据。输入的一定要是有效的地址。
我们打开内存窗口之后,把列设置为4,是为了更好观察变量它们里面的值。
我们来简单介绍一下:中间是它们在内存中的值,虽然在内存中值是以二进制存储的,但是为了方便观察,它是以16进制的形式展示的,左边是它们的地址,右边是对内存中的值进行解析,这解析具有非常少的参考意义。
除此之外,在调试的窗口中还有:自动窗口,局部变量,反汇编,寄存器等窗口,可以自行验证使用一下。
六.编程常见错误归类
编译错误就是语法错误
链接错误
这些都是链接错误,就是找不到这个符号,但是用了这个符号。
我们来总结一下:编译型错误一般是语法错误,这类错误一般看错误信息就能找到一些蛛丝马迹的,双击错误信息也能初步的跳转到代码错误的地方或者附近。编译错误,随着语言的熟练掌握,会越来越少,也容易解决。
链接型错误:看错误信息,主要在代码中找到错误信息中的标识符,然后定位问题所在,一般是因为:标识符不存在,拼写错误,头文件没包含,引用的库不存在等。
最后还有一个是运行时错误。运行时错误,是千变万化的,需要借助调试,逐步定位问题,调试解决的是运行时问题。记住:只有运行时错误能用调试来解决。
最后的最后感谢观看,如果对你有帮助的话,留下你的赞赞吧!!!