×少量的预防措施要比大量的治疗措施有价值的多。。。
1.故障从哪里来
为了寻找有缺陷的代码,你必须以这个故障作为起点回溯追踪起因。
1.2从缺陷到故障
通常缺陷是通过以下四个阶段产生的:
1.程序员制造了一个缺陷:所有代码都是程序员写的,写错了。
2.缺陷造成了错误状态的感染:正确的代码段,被错误的代码感染。这时候代码已经不可控。
3.错误状态不断的传播:大多数程序由于不正确的输入而返回错误,当后面的程序访问该状态时,会把错误扩散到后续的程序状态中。(正确情况应该是不会持续传播的,应该会被后续某个模块覆盖或者修正)
4.错误状态引发的故障:外部程序应为感知到了程序的错误状态而故障
×错误只能程序有缺陷,不能证明程序没有缺陷。。。
1.3迷失在时空之中
调试过程可以分解成七个步骤:
1.track the problem
2.reproduce the failure
3.automate and simplify
4.find infection origins
5.focus on likely origins
6.isolate the infection chain
7.correct the defect
在很大程度上,调试就是一个搜索问题,主要是如下两个原则:
×从错误状态中分离出正确状态:如果一个状态是错误的,它可能就是从缺陷到故障的传播链中的一部分;如果一个状态是正确的,他就基本不可能有错误被传播。
×从不相关状态中分离出相关状态:一个变量的值取决于一小部分早期变量的值。因此,只有一部分早期状态是和程序故障相关的。
1.4从故障到修正
×跟踪问题:
×重现故障:
×自动化和简化测试用例:如果是一个复杂的程序,就必须考虑如何自动产生故障(应为希望被重现),以及如何简化输入,得到最小测试用例。
×寻找可能的感染源:如果有自动化测试可以使用排除法,将测试数据中会导致错误的数据找到。
×分离感染源:假设找到是某个测试数据导致错误,现在可以回溯相关系统这个数据出来的模块。
×修正缺陷:
1.5自动调试技术
×简化输入:
×程序片段:
×观察状态:
×监视状态:
×断言:
×反常:
×因果链:
1.6 BUG、失误、还是缺陷
缺陷(defect):错误的程序代码(代码中的bug)
错误的状态感染(infection): 错误的程序状态(状态中的bug)
故障(failure): 可感知程序的错误行为(行为中的bug)
summary:
1.调试程序的七个步骤:跟踪->重现->自动化->发现感染源->重点关注->分离->修正
咱们平常就是自动化和分离的时候会偷懒,老实说,在调试复杂程序的时候,花点时间做自动化和分离是“磨刀不误砍柴功”
////////////////////////////////////////////////////////////////////////////////////////////////
程序员写了一段有缺陷的代码,这是否意味着他犯了过错呢?考虑这些情况:
原始需求没有预测到未来的变化,如:千年虫
只有当程序的某种行为呈现在用户面前是时,才有可能被列入“故障”
在模块化的程序中,故障可能是由两个模块之间的不兼容接口造成的。
分布式系统中,故障可能是由几个组件之间无法预测的交互造成的
。。。。。。
这时候讨论责任已然是一种政治态度
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
///// f16的bug
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////