错误所带来的麻烦 软件开发人员通常都低估了软件测试的重要性。这一现象的根本原因很简单:处理错误很困难!因为错误往往暴露了代码的根本缺陷,所以有时候开发人员甚至会为了几个错误而从头开始重新编写项目的主要部分。
我认为,调试如此重要,以至于至少要为其分配整个项目 30% 的时间。额外的调试时间将导致更好的产品。另一方面,如果为了更快地推出软件而缩短调试时间,那么在软件生成后,您将花上双份的时间来修复那些稍后暴露出的问题。
有三种基本类型的错误:编码错误、文档错误和需求错误。需求错误通常由于需求不严密或缺少需求而导致。文档错误存在于手册或联机帮助中。编码错误是由程序员在实现需求时的错误而引起的。不幸的是,需求错误和文档错误不在本文范围之内,因此,我们只好只讨论如何“检测”、“解决”和 “修复”编码错误了。
调试的基本概念 我们已经将编码错误定义成程序员在实现需求时产生的错误。编码错误会导致不正确的程序行为(偏离需求的行为)。因此,程序员在编写或调试程序之前首先应该知道的是程序需求。
调试与狩猎没什么不同。第一步是检测错误(通过观察错误的行为并确认其模式)。在这个阶段,错误只是一些症状。
第二步是解决错误。因为必须要在源代码中消除错误,所以,应该有一个精通程序的人来检查错误,并知道这些错误的根本原因。如果代码理解起来更容易,并且现在的代码没有比当初错误版本中的代码更多,则您可能做对了。
第三步,也是最后一步,是修复错误(请注意“修复”与“解决”是有区别的)。调试程序将源代码更改放入“现场”的生产过程,然后检查它是否正确。如果代码不正确,则表明您没有解决错误,甚至更糟糕的是,可能还引入了新的错误。既然解决错误的目的不应该是引入新错误,请确保在解决错误之后修复每个错误。
要确保迅速找到错误并很好地理解它们,您应该对调试过程中程序使用模块和类在每个主要分支处的操作非常清楚。当然,这要求您对编写代码所用的语言(在我们的示例中是 Perl)有深入的了解。因为存在所有这些需求,所以很难找到好的软件测试人员。
Perl 调试器 Perl 程序员的第一个资源是 Perl 所带的调试器。如您所见,着手使用该调试器是非常容易的。
用调试器运行一个脚本
perl -d program.pl
Perl 调试器自带帮助('h' 或 'h h' 分别用于详细和简短的帮助屏幕)。perldoc perldebug 页面(在命令提示窗口输入 "perldoc perldebug")有更完整的 Perl 调试器描述。
现在,让我们从一个有错误的程序着手,看一下 Perl 调试器是如何工作的。首先,它将尝试打印一个文件的前 20 行。
buggy.pl
#!/usr/bin/perl -w
use strict;
foreach (0..20)
{
my $line = <>;
print "$_ : $line";
}
当它独自运行时,buggy.pl 将失败,并给出消息:"Use of uninitialized value in concatenation (.) at ./buggy.pl line 8, <> line 9."。更神秘的是,它还自己在一行上打印 "9:" 并等待用户输入。
那意味着什么?如果调用了 Perl 调试器,您可能已经找到问题所在了。
首先,让我们证实这个错误是可以重复的。我们将在第 8 行设置一个操作来打印发生错误的 $line,然后再运行程序。
buggy.pl 调试器命令
> perl -d ./buggy.pl buggy.pl
Default die handler restored.
Loading DB routines from perl5db.pl version 1.07
Editor support available.
Enter h or `h h' for help, or `man perldebug' for more help.
main::(./buggy.pl:5): foreach (0..20)