Table of Contents:

debug的策略

调试心理学
去解决问题,而不是责备
不要恐慌bug,永远去发掘问题的根本原因,而不仅仅停留在问题的表面现象

理解系统
即在调试之前,需要先搞明白系统的运作方式。包括并不限于阅读文档,阅读源码,寻找熟悉系统的同事交流。

理解了你自己的系统后,还会获得一个额外的好处。当你找到bug时,必须在不破坏其他地方的前提下修复它们。理解系统行为是不破坏系统的第一步。理解了系统之后,你会明白什么是对的,什么是错的——

稳定复现bug
为了修复 bug,我们需要找到引发 bug 的条件,确保可以有规律的重现 bug,接下来才是修复:
当问题没有修复时,如果你执行 X 操作,失败率为100%;在修复问题后,再执行 X 操作,如果失败率为0,那么你知道bug确实已被修复。
为了有规律的重现 bug,我们应该想办法制造/增加 bug 出现的条件。如果车胎漏气,我们可以把车胎放在肥皂水里,寻找气泡。

分而治之,缩小范围
通过反复地把问题分成好的一半和坏的一半,来缩小搜索范围,然后进一步研究有问题的那一半。

控制变量法,一次只改一个地方
1.这叫控制变量法,每次只控制一个变量才能确定次变量对系统的影响
2.如果你所做的更改没有起到预期的作用,那么就把它改回来。它们可能会产生无法预料的影响。

检查插头(Check the Plug)
当电器出现问题的时候,应该问自己一个古老的、看似愚蠢的问题:“插头插上了吗?”虽然这个问题看上去很愚蠢,但它经常发生。
它的核心思想是:在花几个小时研究复杂问题之前,先排查那些最简单、最容易被忽略的原因。
很多经验丰富的工程师遇到问题时,第一步往往不是看代码,而是先问:
1. 服务启动了吗?
2. 请求发出去了吗?
3. 请求到达了吗?
4. 参数对吗?
5. 配置对吗?
6. 环境对吗?
7. 日志对吗?
8. 数据真的存在吗?

80% 的 Bug 都不是算法错了,而是“插头没插好”——配置、环境、权限、路径、参数、缓存、拼写等基础问题出了错。

寻求他人帮助
与其自己与 bug 死扛,不如去寻求同事的帮助:

别人寻求帮助至少有3个原因(还不算把整个问题甩给别人):获得全新观点、专业知识和经验。而且,人们通常很愿意帮忙,因为这给了他们一个证明自己很聪明的机会。

我们按照自己老一套的思路是很难看清全局的。我们都是普通人,对任何事情都有偏见,包括对bug隐藏在哪里的看法。这些偏见可能导致我们无法看清实际情况。而其他人则会从另一个角度来看问题,这可能会给我们很大的启发,帮助找到新的方法。

即使无法从他们那里得到帮助,他们也可以安慰你一下,告诉你这个问题真是一个非常棘手的问题,也可以借给你肩膀靠一靠。

无论你想要获得什么样的帮助,在向别人描述问题的时候,一定要记住一件事:报告症状,而不要讲你的理论。之所以要从别人那里获得全新的观点,就是因为你的理论起不到任何作用。如果你找了一个人,把你的理论告诉他,那么也会把他拉到你原来的思维定式中。

如果你不修复bug,它将依然存在
当你认为你已经修复了一个设计问题时,取消这个修复,确定系统再次失败。然后再应用这个修复,再次验证问题已修复。

调试技术

log("last login time : %d", last_login_time);

查程序崩溃
Qt下程序崩溃,但是没有崩溃时的堆栈
若出现崩溃错误,一定要消灭在萌芽中,不可放任不管,因为在刚发现时,往往知道是修改那个功能出现的崩溃,拖得越久,越难以确定崩溃的范围

查找步骤:
1. 查找稳定复现的方法
2. 在代码中加打印,从大范围,到小范围确定出问题的代码段
3. 锁定可疑的代码,如系统调用,容器越界,容器删除等操作
4. 修改可疑代码,验证是否解决