软件调试与成功的测试形影相随。软件测试成功的标志是发现了错误,而软件调试则是在软件测试成功后,根据错误迹象确定错误的原因和准确位置,并加以改正。 软件调试是程序员自己进行的技巧性很强的工作,要确定发生错误的内在原因和位置不是一件容易的事,它占整个调试工作量的90%左右。调试工作的困难与人的心理因素和技术因素都有关系,需要繁重的脑力劳动和丰富的经验。 调试是一个相当艰苦的过程,究其原因除了开发人员心理方面的障碍外,还因为隐藏在程序中的错误具有下列特殊的性质: (1) 错误的外部征兆远离引起错误的内部原因,对于高度耦合的程序结构此现象更为严重; (2) 纠正一个错误造成了另一错误现象(暂时)的消失; (3) 某些错误征兆只是假象; (4) 因操作人员一时疏忽造成的某些错误征兆不易追踪; (5) 错误是由于风时而不是程序引起的; (6) 输入条件难以精确地再构造(例如,某些实时应用的输入次序不确定); (7) 错误征兆时有时无,此现象对嵌入式系统尤其普遍; (8) 错误是由于把任务分布在若干台不同处理机上运行而造成的。 在软件调试过程中,可能遇到大大小小、形形色色的问题,随着问题的增多,调试人员的压力也随之增大,过分地紧张致使开发人员在排除一个问题的同时又引入更多的新问题。 尽管调试不是一门好学的技术,有时人们更愿意称之为艺术,但还是有若干行之有效的方法和策略,下面介绍几种常见的调试方法。
简单的调试方法 (1) 在程序中插入打印语句 此方法的优点是显示程序的动态过程,比较容易检查源程序的有关信息。缺点是效率低,可能输出大量无关的数据,发现错误带有偶然性。同时还要修改程序,这种修改可能会掩盖错误,改变关键的时间关系或把新的错误引入程序。 (2) 运行部分程序 有时为了测试某些被怀疑有错的程序段,整个程序反复执行多次,使很多时间浪费在执行已经是正确的程序段上。在这种情况下,应设法使被测程序只执行需要检查的程序段,以提高效率。 (3) 借助于调试工具 目前大多数程序设计语言都有专门的调试工具,可以利用这些工具分析程序的动态行为。例如,借助"追踪"功能可以追踪子程序调用、循环与分支执行路径、特定变量的变化情况等,利用"设断点"可以执行特定语句或改变特定变量值引起的程序中断,以便检查程序的当前状态。另外,还可以借助调试工具观察或输出内存变量的值,大大提高调试程序的效率,缺点是会产生大量的无关信息,也会走弯路。 归纳法调试 归纳法是一种从特殊到一般的思维过程,从对个别事例的认识当中,概括出共同特点,得出一般性规律的思考方法。归纳法调试从测试结果发现的线索入手,分析它们之间的联系,导出错误原因的假设,然后再证明或否定这个假设。 归纳法调试的具体步骤如下:
演绎法调试 演绎法是一种从一般的推测和前提出发,运用排错和推断过程作出结论的思考方法。演绎法调试是列出所有可能的错误原因的假设,然后利用测试数据排除不适当的假设,最后在用测试数据验证余下的假设确实是出错的原因。演绎法调试的具体步骤如下:
回溯法调试 该方法从程序产生错误的地方出发,人工沿程序的逻辑路径反向搜索,直到找到错误的原因为止。该方法是对小型程序寻找错误位置的有效方法。