C语言——实用调试技巧

一、为什么漏洞叫bug

为什么漏洞的英文是bug,众所周知bug有虫子的意思,这其实有一个很有名的故事。

1947年,计算机科学的先驱格蕾丝·霍普(Grace Hopper)和她的团队在使用哈佛大学的马克二电脑时,发现了一个故障。他们检查机器时,在其中一个继电器里找到了一只飞蛾,这只飞蛾卡在了机器的部件中,导致电脑出错。他们将这只飞蛾移除,并在日志中记录了这个事件,写下了"bug"这个词。

Grace Hopper
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

创建断点和取消断点。

在程序中设置断点是调试过程的一个基本而强大的功能。断点的作用主要包括:

  1. 暂停执行:断点允许程序员指定一个特定的代码位置,当程序执行到这个位置时,它会暂停运行。这意味着可以在代码执行到某一行时立即停下来,而不是等到程序完全运行结束或者出现错误后才停止。

  2. 检查程序状态:一旦程序暂停,程序员可以检查和评估程序的当前状态,包括变量的值、内存状态、调用栈和其他重要的调试信息。这有助于了解程序的行为和查找可能出错的原因。

  3. 控制执行流程:通过设置断点,程序员可以控制程序执行的流程,逐步执行(stepping)代码来观察程序的每一步行为,这有助于识别出问题发生的确切位置。

  4. 条件调试:许多调试工具允许设置条件断点,即只有当满足特定条件时,程序才会在断点处暂停。这使得调试工作更加高效,尤其是在处理需要在特定情况下才出现的错误时。

  5. 减少调试时间:通过合理地放置断点,程序员可以快速跳过他们确定没有问题的代码部分,直接关注可能出现问题的区域,这样可以节省寻找bug的时间。

设置断点是一种无需在代码中添加临时调试代码(例如打印语句)的调试方法。它提供了一种干净、可控且不非常侵入性的方式来观察程序的内部工作,使调

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值