2010/02/06

信頼性について-2: MTTFによるテスト

クリーンルーム手法では品質保証を目的としたテストの指標としてMTTF(Mean Time To Failure)を利用する。そして、バグ密度のような指標は品質にとっては意味がないと言っている。クリーンルーム手法はホーア理論に基づいた形式手法の一種である。

また一方、ソースコード検証ツールであるPolySpaceのWebセミナー

  1. プログラム検証によって発見されたソースコードのバグを100%取る必要は無い。95%ぐらいでよい。
  2. 機能テストプログラム検証は違う。
  3. プログラム検証をやっても機能テストは必要だ。5%の取り残しバグがあっても機能テストをパスすれば良い。

と言っている。

クリーンルームの方は、機能テストをすればプログラム検証は必要ないという言い方になっていて一見すると別のようだが、障害の有無が重要でありfaultの数は重要でないと言う点では一致している気がする。バグは欠陥(fault)に対応し障害(failure)と同じでないことはすでに述べた。テストの世界では、ホワイトボックステストとブラックボックステストという分類があるが、ホワイトボックスはfaultの検出、ブラックボックスはfailureの検出と対応づけることができるかも知れない。

クリーンルームでは、ユーザの使用特性を分析して、それに基づいて実際にシステムを動かしてMTTFを測定する。ある欠陥が発見されてから次の欠陥が発見されるまでの時間がMTTFになる。このMTTFがある値以上になれば出荷基準に達したと判断する。

クリーンルーム手法によってプログラムを作ればfaultは無いはずだからfailureの検出が重要だとも説明している。またfaultの無いプログラムを高品質と定義している。faultの無いプログラムであればMTTFの測定が出来る。それでどのようなテストをするかというと、品質を測定するためのテストであり、まず利用モデルと言うものを作る。利用モデルには以下のものが含まれる。

利用者: システム外部の実態、アクターやデバイスなど
利用の仕方: 動作モデル
環境: プラットフォーム、利用の状況(昼/夜、緊急時、オートモード)

動作モデルは、状態遷移図や決定表で表現される。利用モデルからテストケースを生成するには利用の仕方の統計的情報が必要になる。具体的には各遷移の遷移確率を入れた状態マシンを利用する。同値分割とかは利用しない。ソースコードの作り方はシステムの品質とは無関係と考える。具体的にどのようにテストケースを生成するのか、MTTFをどのように測定するのかについては色々な論文を読まなくてはならない様だ。

参考文献



2010/02/04

信頼性について

品質と同じようにわかり辛いのが信頼性だ。ソフトにバグが有ると品質も信頼性も低くなることは依存はないと思うが、バグが無ければ高品質で高信頼性かというとそうでもない。仮にそうだとしてもバグの無いソフトはない、あるいはバグの無いことを証明することはできないとも言われるので、ソフトについて高品質とか高信頼性とか言うと嘘つきになって、話が終わってしまう。そんな訳だからあまり人と議論してもまともな議論にならないことが多い。もっと定量的な定義が必要である。
品質属性の一つとして信頼性があるというのが一般的なので、信頼性から考えてみたい。障害が起きるかどうかは確率的事象と考えることが妥当である。f(t)を障害が起きる確率密度関数とすると。ある時刻tまでに障害が起きる確率分布関数F(t)は以下のようになる。
障害を広辞苑で引くと「2. 身体器官に何らかのさわりがあって機能を果さないこと」と出ている。この何かのさわりがソフトではバグと言うことになる。ソフトウェアにバグ(fault, 故障)があると処理結果に誤り(error)が生じる。処理結果が間違っているとそれはシステムの障害(failure)になる。誤りがあっても必ず障害が発生するとは限らない。たとえば、リレー接点が焼き付いてしまって常時ONになった場合でも、OFFにしようとしない限り障害として顕在化することはない。ソフトウェアにバグがあれば必ずエラーは起こるが、障害というレベルで考えると確率事象であると言う主張は、言われてみればそんな気もする。
それで、障害が発生しない確率を信頼度(reliability)と定義する、と言ってもどんな状況でシステムを動かしてなのかがはっきりしないと意味が分からない。電源を入れた瞬間火を噴かない確率なのか、ある機能を利用しようとしてちゃんと使える確率なのかが分からない。そこで、火を噴くとか、機能しない等は故障としてまとめてしまう、そうすると電源を入れた瞬間か、機能を使おうとした時かと言うことが残る。これは、障害がいつ起こるかと言うことだから、信頼度は電源を入れた時からt時間までに障害が発生しない確率と言う意味と考えれば良い。すると信頼度は時間の関数なのでR(t)と表せば、F(t) = 1 - R(t)である。
障害が起きる確率と信頼度の関係が見えてきた。f(t)が何かがもう少し分かるとスッキリする。ある時刻tまで順調で、時刻tとt+dtの間に障害が起きる確率をλ(t)とすると、f(t)はR(t)とλ(t)の掛け算になる。λを障害率(failure rate)と呼ぶ。このλを時間に対して定数とするとR(t)は以下のようになる。
ソフトには時間による劣化のようなことは無いのでλが定数と言うのは妥当な気がする。だからλが分かればソフトウェアシステムの信頼性が定義できるかも知れない。ソフトのバグは踏めば必ず爆発する地雷のようなものだから、システム障害が発生する確率はどんな歩き方をするかに依存する。全ての歩き方を考慮すればランダムな歩き方と言うことになり指数分布になるのは納得がいく。ハードの場合には、初期故障がありしばらくすると落ち着いてまた摩耗が起こると障害率が上がるバスタブ型になるが、ソフトの場合はそのようなことはないので上記の信頼度の関数はハードよりもソフトに当てはまる。
障害までの平均時間(Mean Time To Failure: 平均寿命)と言う尺度がある。これは以下のように表せる。
そしてこれを実際に計算すると何と
となるのである。完成したシステムのフィールドでの平均障害発生時間を調べればソフトウェアの障害率がわかる。後は、バグの数あるいはバグ密度と障害率の関係が分かれば面白くなる。





Prism

テクマトリクスでのPrismの説明会に参加した。Prismは、プログラムの動的解析をするツールである。
入力としては、デバッグ情報付きのオブジェクトコード、実際に実行して得たトレース情報、ソースコードである。
 マルチタスクやマルチコア環境でのチューニングやシングルコアからマルチコアに移行する際の設計支援に利用することが出来る。ソースコードを入力として利用するのでソースコードを解析するのかと思っていたら、解析対象は実行トレースであった。別々のスレッドが同じアドレスにアクセスしていたらソースコードを参照してアラートを上げてくれる仕組みである。従って、実行した部分のみが解析対象になる。排他制御が必要なのに排他制御されてないと、タイミング上実際に不具合が無くても不具合の可能性として検出する。また、アドレスを見ているので、ポインターのポインターのそのまたポインターによる参照でも検出することが出来る。ソースコード解析ではなかなか難しいが直接アドレスを見ているので簡単に検出できるわけである。また、ヒープの中でも解析できる、メモリーリークの検出ばかりでなく、freeするタイミングを早くすると次のmalloc待ちのスレッドが早く動けると言うようなメモリーの使い回しのチューニングをシミュレートしながら出来る。なかなか良い機能だ。
 静的解析でデータ依存が報告されるがパフォーマンスのボトルネックになるものがどれかを予測することは難しいが、what-if解析でどの依存を解消すべきかについてもシミュレーションで優先度を決めることが出来る。
 製品の目的はシングルコアからマルチコアに移行する際の設計支援だが、シングルコア/マルチタスク環境におけるタスク設計のチューニングにも応用できる。30日の評価版があるので実際に使ってみようと思う。


2010.08.29: 書き足し
確率モデル検査をおこなうPRISMとは違う

2010/01/31

マルチタスク環境におけるWatchdogの設計

Watchdogタイマーは基本的にはカウンターでzeroになった時かオーバーフローした時にシステムにリセットを掛けてシステムを再スタートさせるハードウェア部品だ。組込屋さんは、PCプログラマのことをバグがあってもリセットすれば良いと思ってる見たいに偉そうに言うが、実はWatchdogはそれを自動化したものだ。やばい時にはリセットするのは変わりない。
ここでは、どんな使い方をするのかまとめてみる。組込では、RTOSを使う場合と使わない場合があるが面白いのはRTOSを使った場合である。以降はWatchdogタイマーをWDTで表す。

要件(やりたいこと)
  1. OSやタスクの無限ループ、デッドロックの検出をする
  2. 低優先度のタスクが動けることのチェックをする
  3. 単に動くだけではなく、アプリケーションに応じて健全性チェックをする
設計(つくりかた)
WDTをkickするタスクをモニタータスク(MTask)とする。その他のタスクをアプリケーションタスクとする。アプリケーションタスクを定周期タスク(Cyclic Task, CTask)とイベント駆動タスク(Eventdriven Task, ETask)に分類する。

イベントドリブンタスク
定周期タスクには有効そうだが、イベントドリブンタスクに対してWDTはどんな効果があるのか? と言うか要件は実現可能か? 外部イベントはいつ来るか分からない、来ないかも知れない。だから、イベント待ちの状態はWDTのモニタ対象外にする。その状態をasleep状態とする。

Sanity Flag
各アプリケーションタスクにフラグを持たせる。alive, asleep, unknownを値として持つ。このフラグはatomicに読み書きできるようにintかcharにする。と言うかCPUのレジスタサイズにする。CTaskとETaskは書き込みのみ、MTaskは読み書きする。MTaskが書き込むのはunknownのみ。CTaskが書き込むのはaliveのみ。

動作
健全性チェックは各アプリケーションタスクがおこなう。CTaskは問題がなければフラグにaliveを書き込む。ETaskはイベント待ち状態に入る際に問題がなければasleepを書き込む。待ちが解除されたらaliveを書き込む。
MTaskは起床されたら、各フラグをcheckしてaliveかasleepだったらWDTをkickしする。aliveフラグをunknownに書き換える。WDTをkickしなければシステムはリセットされる。参考文献-1のFig.3は定周期タスクとモニタタスクの動きを示している。ただし、アプリケーションタスクをシステムタスクと呼んでいる。



参考文献
1) Watchdog Timers