软件的可靠性

大多数机械电子机器都使用计算机,所以都以不同的形式提出软件要求,这种倾向随着机械电子化的发展而日益增大,特别是象前面阐述的那种由于机械的CCV化,没有软件就不能运转的机械会不断增加了.

捕获.JPG

此时,对于软件的设计也要象机械的设计那样,需要在充分考虑后进行,特别是对软件错误的对策,需要比以前作更慎重的考虑才行,对于机械电子学来讲,软件的设计与机械设计、电路设计具有同等的重要性甚至比它们更重要。

为了提高软件的可靠性,大致可采用两种办法,第一是在开始进行程序设计的阶段就必须防止产生错误,也就是说在最初编写程序时,就要考虑不致产生错误的方法。这一建议最早是E,W.

捕获.JPG

Dijkstra1969年在NATO软件工程会议中提出的。它的出发点基于下列信念,即“通过检查程序虽然可以证明程序中存在错误,但是不能证明程序中不存在错误”。把这种想法具体化,就得到了结构化语言,它需要进行程序流程控制的整理和附加变量的构造等等,此外,还要设法把希望程序化的内容简明地表示出来。关于结构化程序设计,已经出版了大量的参考书,可供参考。

但是事实表明,即使说是用结构化语言编写,也不能保证没有一点程序错误。况且如果制造期间不能完全消除错误,就仍然有必要实施某些检查。这就是第二个观点。

程序的检查与调试是两个根本不同的概念,尽管两者都是以排除程序内部的故障为目的,但调试是由程序的设计者即程序员来进行的,而检查则是指由其它人员系统而客观地进行工作,所发现的错误不当场更正,而是退回到程序设计者处。

现在让我们考虑一下,什么是比较好的检查方法。对检查提出的第一条要求是“检出性”。这是很自然的,能够正确地检查出程序内的错误是必不可少的条件;第二是“覆盖性”。这是指在程

序可能的输入条件(据此,程序的控制发生变化)中,通过何种程度的检查即可完成整个程序的检验。这是因为不管多优秀的检查功能,也不可能仅通过对部分输人条件的测试就把所有的错误都检验出来;第三是“再现性”,程序的输人条件有多少可以自由设定就是所谓“再现性”。正像前面叙述过的那样,因为在检验工作中发现的错误,要退回给程序设计者修正,所以对于被修正过的程序,还必须再度进行检查。这时必须在与发现错误时相同的输入条件下进行检查;第四是“模块性”,从上述覆盖性、再现性的角度出发,对整个程序同时进行检查,效率是不高的。因此,将程序分割为若于模块,然后分别各自独立地进行检查更为有效,在对模块单位进行检查时,必须将模块工作的输人环境完备化。为使模块单位能象在整个系统中一样工作,需要有一种模拟器。对下位模块进行检查时,需要有代替上位管理程序的设备(驱动器),对上位模块进行检查时,则需要因此而被起动的各个子程序的伪程序(短接线),良好的模块检查,能忠实地模拟出整个系统运行时的环境条件,此后再把通过了单个检查的模块组合成整体系统,就必定能完全消除错误了。

程序检查大体区分为两种,即静态试验和动态试验。前者只以程序的源码为对象进行检查,并不实际地去执行程序,后者是在系统地制定好输入条件的情况下,实际地执行程序,并且经过检查确认是否实现了预期的功能。

静态试验分作几个阶段进行。第一阶段是检查源码格式,叫做码检查,通过这种检查,对格式作了整理,程序就变得非常容易阅读了,至少从表面上看把程序整理得比较完善了。第二阶段是分析数据结构上的矛盾。这一阶段和第三阶段结合起来叫静态分析,这时将根据存放在编译程序中,且经过大幅度提高语法检查功能后的程序,进行工作,例如,检查正在参考的尚未定义的变量或检查一次也未被参考过的变量是否被定义.此外,是否在对型式不同的变量之间进行演算等情况,也在检查范围之内。第三阶段是关于控制流程的检查。它包括无限环路的检测,即所谓死码(在

任何输人条件下都不能执行的程序部分)的检测。以上是针对程序的语法方面进行的检查,采用自动化工具是可能的。第四阶段是涉及程序内容的检查,它难于进行自动检查,就现状来讲,只好利用人海战术了.

静态试验虽然给人一种无效率的印象,但它与动态试验相比,在再现性和覆盖性方面都比较优越。在动态试验之前,进行彻底的静态试验是非常有效的。特别是在在线控制多个程序运行的操作系统等的系统程序检查中,许多专家认为静态试验是最有效的.机械电子学机器的软件具有较强的在线性,而且又有增大传感器数量的趋势,所以,从本质上讲,进行完全的动态试验是趋于不可能的。从这种意义上讲,今后将把从逻辑上保证机械电子学机器软件的可靠性作为一种手段,静态试验的重要性就增大了。诚然,在静态试验中,特别是在到了第三阶段的检查中,有时也会将一些技巧性的软件作为错误检测出来。也有的报告说,事实上在静态试验检查出的东西,真正属于错误的不足10%。但是,人们认为,静态试验是从逻辑上证明程序正确性的唯一方法,今后其重要性只会增加而不会减小。

静态试验结束后,便开始进行动态试验。在动态试验中由于要实际地起动程序进行实验,所以必须解决输入的选择问题。如果选择任意数据作为输入,则可以忽略试验情况,但必须考虑许多其它内容。动态试验的关键,实际上是从包括无数输入的组合中,选择一个能最有效地检查程序的输入。在图6.37(a)表示的程序的运行中,输人空间的点P仅与输出空间内的点Q相对应。设某程序做了四次动态试验,如果选择了图6.37(b)所示的输入方法,那么它可能只进行了程序中的很小一部分试验,图6.37(c)才是理想的选择方案。基于动态试验,用来表示将程序试验进行到何种程度的覆盖性指标,通常用“网罗率”表示。这就是说,在整个程序中,它只表示通过怎样一种程度的动态试验,使它“进行了工作”。在现在的电子学机器中,经常通过上述分阶段的实际试验来进行检查,但是将来,随着软件比重的增加,这里阐述过的系统检

捕获.JPG

查方法将成为必要的了。

例如,设有个程序如图6.38所示。圆圈表示语句,箭头表示控制流程。最简单的覆盖指标是测定在全部语句中,被执行语句所占百分比,这叫做“C0网罗率”。比如,只执行abcef总线时,C0网罗率为100%,此时d,g,h等总线被忽略。因此,这里考虑的是用通过总线的比例表示的网罗率,这叫“C1网罗率”,现在如果单说网罗率,做为覆盖性指标,它是最为合适的。但是由于围绕环路次数的不同,也经常导致不同的程序控制情况,所以只根据这一

点还不充分,又如图6.39所示,只经过(ac),(bd)测定时,CI网罗率达到100%,但是实际上必须对(ac),(ad),(bd)的总线

捕获.JPG

进行试验。因此,把C1网罗率作为指标也是不完善的。

这样一来;在动态试验的选择输人数据的方法是很重要的,完全从程序的外部考虑,选择输入数据的试验叫做功能试验,从涉及到程序流程图考虑时,则叫做结构试验

功能试验的试验数据,是由程序的外部方法构成的,在功能试验中,具有代表性的方法是同值分割法.它是将程序的输入变量域(输人空间)分割成若于级,然后在每级中有代表性的点上进行试验。级不同则程序完成的动作也不同。这时,对代表点的选择方法设定了一些限制条件,因此叫限界分析法,代表点要选择在同值域的界上或稍稍偏离的地方,这样就更有效地进行界值错误的检測(图6.40).在这两者方法中,同值级的构成必须采用试探的方法,但程序整体的网罗率未必很高。

功能试验完成后的C1网罗率,通常被认为在40—50%范围内,即使采用了因果关系曲线图那种有力工具,其值也只能达到70%、因此,当发现未执行的通路,寻找通过此通路的输入量组合时,有必要提高网罗率。这就是结构试验。在结构试验中,根据通

1)古川善吾、野木薬六:機能テストのためのテスト頃目作成法について,情処理学会ソフトウェプ工学研究会資料Vol.16,No.2,1980.

捕获.JPG

捕获.JPG

路自动地产生与其相应的试验数据并非是一件易事。

作为一种尝试,提出了一种叫做符号执行的方法。它实际上不是用数字执行程序,而是根据已定下来的通路,将保证通过上述通路的条件逐个用符号代入的方法。通常符号执行法是由前往后执行的(如图6.41).

软件的可靠性与成本之间存在着矛盾关系。要排除所有的错误恐怕需要无限长的时间,这样成本也就无限增大了。例如,在图

捕获.JPG

执行语句和分支

分支④

分支⑧

分支②

分支①


④(3)③②(3)(2)③(1)

END

d=

d→1m

d—1

d一1=

d—2口d-2=

d—2=kb—2=

 

 

 

a≥

 

 

f(a)≥5f(a)≥cf(a)≥c

 

 

 

 

d+t

d-1キたd—1+d-1キ

b-!÷

 

 

 

 

 

 

 

 

<a<

(b)符号执行举

国6.41符号执行,由此表看出,为了通过点线的总线,输人变量a、b的条件为

f-(0)≤<b:bmK+2(b中K+1)

捕获.JPG

6.42中把在试验中发现故障累积数所需要的时间定为横轴,这时画出的典型曲线形状如图所示。从此图可以看出,随着发现错误量的增加,发现新的错误的困难急剧增加。因为要完全排除所有的错误,几乎需要无限长的时间。所以我们只好满足于有限的可靠性了。作为体现软件可靠性的指标,第一是常用的已介绍过的网罗率,特别是C1网罗率,从中大致可以估计出软件成品经过了何等程度的严格检验。第二可以偿试从以前的经验数据总结出来的错误累积曲线,估计出最终的错误个数。第三是变异分析(mutationanalysis)即一种实验的方法。例如,假定预先人为地在程序中制造了个错误,测试结果,设发现的错误数为i个。另外,假设发现的程序本来错误为i个,这样就可以以1=Ii/i来评价程序内本来存在的错误数。因此,通过上述试验,可以在一定程序上检验试验数据的完整性。


随便看看