第2章 软件缺陷、故障及失效
2.1 几个基本概念
对软件缺陷(Bug/Defect)、故障(Fault)、失效(Failure)的研究是软件可靠性研究的基础,因此本章对上述概念进行介绍。缺陷、故障、失效等词汇的含义很相近,在软件领域使用这些词汇时更容易混淆。因此,在进行讨论之前,先对这些词汇的含义分别进行介绍。
1.软件缺陷
软件缺陷一词最早出现在1945年的Annals年报中,并被称为“Bug”。随着软件工程及软件缺陷学的发展,产生了对软件缺陷发展过程各个阶段的定义,软件缺陷也变为由“Defect”来描述。然而,计算机应用领域仍然沿用“Bug”来描述软件缺陷。目前,软件工程领域已普遍认为软件缺陷是软件的一种固有属性,并且可以通过修改软件而消除。
ISO 9126将软件缺陷定义为“Bug”,可分为两类。
(1)Defect,其定义为未满足期望的使用需求(the Nonfulfillment of Intended Usage Requirements)。
(2)Nonconformity,其定义为未满足需求的准确性(the Nonfulfillment of Specified Requirement)。
目前软件缺陷学界将缺陷定义为“Defect”,其含义包括ISO 9126定义的“Bug”的所有内容。此外,还有其他一些软件缺陷定义,如能力成熟度模型(Capability Maturity Model,CMM)中对软件缺陷的定义是系统或系统部件中能造成它们无法实现被要求功能的缺点,若在系统执行过程中遇到缺陷,则可能导致系统故障。
本书中对软件缺陷的定义如下:软件缺陷是指存在于软件中的那些不希望出现或不可接受的偏差,其结果是软件在运行于某一特定条件时出现故障。当软件意指程序时,软件缺陷与软件“隐错”(Bug)同义。
上述定义表明,软件缺陷是软件产品的静态属性,其表现为与预期不一致。软件产品包括文档和程序;与预期不一致包括软件产品与用户需求不一致、与软件自身需求不一致、与隐含需求不一致。
2.软件故障
当运行软件时激活了软件缺陷,可能导致软件故障。在ISO/CD 10303-226中,软件故障被定义为存在于组件、设备或子系统中异常的条件或缺陷,常常会导致系统失效。
本书中对软件故障的定义如下:软件故障是指软件的运行与规定不符,使软件或其组成部分丧失了在规定的限度内完成所要求的功能的能力。软件只有在执行一次任务时用到有缺陷的部分程序,才会发生故障,如果在执行一次任务时未用到有缺陷的部分程序,则软件仍能正确运行。
3.软件失效
软件失效是指软件故障使软件不能完成规定功能,是一种外部行为结果。软件故障不一定使软件在执行任务时失效。
本书中对软件失效的定义如下:软件失效泛指当软件故障无法被容错技术处理时,软件在运行过程中丧失全部或部分功能、偏离预期的正常状态。
由上述分析知,软件失效是软件缺陷发展的最终阶段,也是影响软件质量的关键性因素。因此,三者间遵循缺陷→故障→失效的关系。软件缺陷与软件故障、软件、失效的区别在于:软件缺陷是软件固有的静态属性,而软件故障、软件失效是软件的动态属性;软件缺陷是软件故障、软件失效的根本原因。软件失效标志着软件一次使用寿命的结束。失效过的软件通常仍然是可用的。只有当软件频繁失效或公认已经“陈旧”时,软件才被废弃,这一点需要加以说明。进一步给出软件缺陷生命周期,如图2.1所示。由图2.1可见,软件缺陷生命周期分为软件缺陷引入、软件缺陷传播、软件缺陷激发和软件缺陷定位及修改四部分。
图2.1 软件缺陷生命周期
(1)软件缺陷引入:由人的错误(以下“错误”均指由人为失误所导致的错误)导致软件产品中存在缺陷的过程称为软件缺陷引入,导致软件缺陷引入的原因很多。由Ram Chillarege等学者提出的正交缺陷分类(Orthogonal Defect Classification,ODC)中就包含软件缺陷引入,即“缺陷起源”(Source)属性。由于软件缺陷引入是软件缺陷生命周期的起始阶段,对该阶段的预防性研究也成为软件缺陷学领域的热点问题,并取得了一定的成果。Eitan Farchi等学者针对多线程软件结构的特点指出,使用统一建模语言(Unified Modeling Language,UML)可以在很大程度上避免多种并行软件缺陷的引入。W.Eric Wong等学者将程序切片技术引入规范说明与描述语言(Specification and Description Language,SDL),用于预防软件架构设计阶段的缺陷引入。
(2)软件缺陷传播:软件开发前期引入的缺陷导致软件开发后期引入相关缺陷的过程称为软件缺陷传播。例如,软件需求分析阶段引入的缺陷可能导致软件概要设计、软件详细设计、软件编码阶段引入相关缺陷。因此,在软件开发后期定位、修改软件缺陷的成本比在软件开发前期定位、修改软件缺陷的成本要高得多。
(3)软件缺陷激发:将静态的软件缺陷触发为动态的软件故障或失效的过程称为软件缺陷激发。软件缺陷激发的方式主要有两种:第一种是在软件版本固化并投入使用之后,软件发生故障或失效的激发方式;第二种是在软件测试过程中,通过运行软件(包括人脑运行软件的审查过程和系统运行软件的测试过程)激发软件缺陷,导致预期结果与实际结果不符的方式。
(4)软件缺陷定位及修改:针对软件故障进行分析,最终找到导致该故障的软件缺陷的过程称为软件缺陷定位,对该缺陷的修正称为软件缺陷修改。由软件缺陷生命周期中的传播阶段所导致的软件缺陷定位一直是软件缺陷学领域的难题。SD Times的主编Alan Zeichick经调查表明:软件缺陷定位、修改费用的一般规律为,在软件开发阶段花费10美元,在软件质量保证阶段花费100美元,在软件BETA版本测试阶段花费1000美元,而在软件投入使用之后则会花费10000美元以上。对单个软件缺陷而言,其生命周期的最后阶段就是被修改直至消除。但对软件缺陷整体而言,测试方法的非完备性将导致在理论上软件缺陷是不可能被完全定位、修改乃至消除的,只能逐渐减少。同时,由于在软件修改过程中可能会引入新的缺陷,并且随着软件使用范围的不断扩大,有可能激发需要更长时间才会导致失效的软件缺陷,这导致对软件缺陷整体而言,软件缺陷残留数最终会保持在一个常数水平上,并且缺陷激发阶段和缺陷定位及修改阶段是一个循环过程。