一、为什么漏洞叫bug
为什么漏洞的英文是bug,众所周知bug有虫子的意思,这其实有一个很有名的故事。
1947年,计算机科学的先驱格蕾丝·霍普(Grace Hopper)和她的团队在使用哈佛大学的马克二电脑时,发现了一个故障。他们检查机器时,在其中一个继电器里找到了一只飞蛾,这只飞蛾卡在了机器的部件中,导致电脑出错。他们将这只飞蛾移除,并在日志中记录了这个事件,写下了"bug"这个词。


因此,这个词就被用来形象地描述导致技术设备或软件出现问题的缺陷。
然而,值得注意的是,"bug"这个词作为故障的隐喻使用,其实早在电脑和电子设备之前就已经存在了。例如,19世纪的发明家托马斯·爱迪生就在他的通信中使用了"bug"这个词来描述一些技术上的难题或者故障。因此,虽然霍普的故事让这个词变得更加知名,但它作为技术故障的同义词在电脑产生之前就已经被使用了。
对应的debug就变成了调试。
有趣的是在许多编程编辑器和编译器中,调试(debugging)功能的图标常常采用一只虫子的形象。由于“debugging”字面意思就是“除虫”,因此使用虫子作为图标既幽默又形象地反映了这一过程——即检测并修复编程代码中的bug。
二、调试是什么
调试(debug/debugging)是软件开发中的一个关键过程,它涉及识别、检查、定位和修正软件程序中的错误或称为“bug”的缺陷。调试的目的是确保程序按照期望正确运行,并且解决任何可能导致程序崩溃、产生不正确结果或者表现出不预期行为的问题。
调试是一个可能既复杂又耗时的过程,它需要程序员有良好的逻辑思维能力、对代码的深入理解以及对可能出现问题的系统部分有敏锐的洞察力。通过调试,开发者能够确保软件的质量,提升用户体验,减少未来可能出现的问题。
程序员在进行代码调试的时候可以被比喻为侦探。每一段代码都像是一个潜在的线索,每一个异常都可能是犯罪现场的蛛丝马迹。当程序不按预期运行时,程序员就要开始他们的侦探工作,仔细检查代码库,寻找导致问题的源头。
他们会审查变量、跟踪函数调用、监视内存使用情况,并且利用断点来逐步执行代码,就像侦探在犯罪现场搜集证据一样。他们需要逻辑推理和细致观察,推敲每一个逻辑分支,解读每一行代码背后的意图,以期揭开导致软件故障的秘密。
调试的过程充满了挑战,它要求程序员不仅要有深厚的技术知识,还要有像侦探一样的耐心和洞察力,以便能够解决那些最棘手的编程之谜。
是否曾有过长时间埋首于代码,却苦于无法定位那个狡猾的错误?是否曾经用尽目力审视每一行代码,试图捕捉那个潜藏的bug?是否因为无法追踪到问题的根源而感到挫败?让我们一起尝试这种更好用的调试方法吧!
三、调试
这里用的编译器是Visual Studio 2022
1、调试基本步骤
(1)发现程序错误
(2)以隔离、消除等方式对错误进行定位
(3)确定错误产生的原因
(4)提出纠正错误的解决方法
(5)对程序错误予以改正、重新测试
2、debug和release的区别
debug称为调试版本,它包含调试信息,并且不做任何优化,以便程序员调试程序。
release称为发布版本,它通常是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
在选择debug版本后运行程序,对应的路径下就会产生debug文件夹:
debug文件夹中有相关可执行程序:
在选择release版本后运行程序,对应的路径下就会产生release文件夹:
release文件夹中有相关可执行程序:
可以看到release版本的可执行程序内存大小更小,因为它没有包含各种包含调试信息。所以在release版本下是没法正常调试的。
#include <stdio.h>
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", i);
}
return 0;
}
如果选择release版本,再进行调试,监视局部变量时会发现:
如果选择debug版本,再进行调试,监视局部变量时是正常的:
而且在release版本下是无法进行逐步调试的,程序会直接运行跳过很大一个代码块。不只有这些区别,在反汇编等方面也有一些区别。
所以我们在进行调试时要选择debug版本。
3、调试相关的快捷键
F5
启动调试,经常是用来直接跳到下一个断点处。
F9
创建断点和取消断点。
在程序中设置断点是调试过程的一个基本而强大的功能。断点的作用主要包括:
-
暂停执行:断点允许程序员指定一个特定的代码位置,当程序执行到这个位置时,它会暂停运行。这意味着可以在代码执行到某一行时立即停下来,而不是等到程序完全运行结束或者出现错误后才停止。
-
检查程序状态:一旦程序暂停,程序员可以检查和评估程序的当前状态,包括变量的值、内存状态、调用栈和其他重要的调试信息。这有助于了解程序的行为和查找可能出错的原因。
-
控制执行流程:通过设置断点,程序员可以控制程序执行的流程,逐步执行(stepping)代码来观察程序的每一步行为,这有助于识别出问题发生的确切位置。
-
条件调试:许多调试工具允许设置条件断点,即只有当满足特定条件时,程序才会在断点处暂停。这使得调试工作更加高效,尤其是在处理需要在特定情况下才出现的错误时。
-
减少调试时间:通过合理地放置断点,程序员可以快速跳过他们确定没有问题的代码部分,直接关注可能出现问题的区域,这样可以节省寻找bug的时间。
设置断点是一种无需在代码中添加临时调试代码(例如打印语句)的调试方法。它提供了一种干净、可控且不非常侵入性的方式来观察程序的内部工作,使调