プログラムのバグとプロセスの関係について

プログラマやソフトウェア・エンジニアにとって、“バグ”との付き合いはなくなりそうもありません。この“バグ”のために、どれだけ多くのエンジニアが悩み、挫折していったことか。そして、今も多くのソフトウェア・エンジニアが、このバグに悩まされていることでしょう。

誰もバグの訪問を望んでいません。でも知らないうちに自分のプログラムの中に入っています。そして多くの人は、バグを厄介者扱いしています。まるで自分の職(生存)を脅かす存在のように対応します(実際に存在を脅かされている人もいることでしょう)。

でも、バグを厄介者扱いしている間は、あなたは、このバグの訪問から逃れることは出来ないでしょう。現にこの10数年間で、あなた方の遭遇するバグは減りましたか? 多少の増減はあっても、それは減るべくして減ったのではなく、システムに慣れていたり、システムの規模が小さかったり変更カ所が少ない、といった“向こうの都合”ではありませんか? その証拠に、その後もバグの数は減り続けていますか?

バグを目の敵にするのを止めて、バグがどのようにして作りだされるのかを正しく認識しないかぎり、バグはなくなりません。

1.バグはプログラムだけに存在するのか?

一体、バグはどうして作りだされるのでしょうか。どうやってあなたのプログラムの中に入り込んでくるのでしょうか。厳密に言えば、バグはプログラムの中だけ入にり込むのではありません。その前のモジュール仕様書や、さらにさかのぼって設計書や要求仕様書、果ては製品企画の中にも入り込んでいます。ただし、それらはプログラムと違って、多くの開発現場では「動作」させることがないためバレなかっただけです。

CR手法のように、要求仕様の段階から、それらのドキュメントに対して厳密な検証手続きを実施することで、要求仕様書や設計書などに入り込んだバグが各々の段階で表に出てくるのです。そのような厳密な検証手続きは、ちょうど“ドキュメントを動作”させるのと同じことなのです。分かりやすく言えばバグは「動かしてみれば分かる」のです。

残念ながら、多くの現場で生成されているドキュメントは“動かされることのない”ドキュメントなのです。その結果、「動作するもの」はプログラムだけとなり、それまでの段階で入り込んだバグも含めて、プログラムを動作されたときに一機に吹き出すのです。

その証拠に、バグの処理票などには、どの段階に入り込んだバグであるかを分析して記入するようになっているではありませんか。「要求仕様のミス」とか、「設計モレ」とかいうのは、本来はその段階で「動作」させれば発見できた事を意味しているのです。それをやらなかったから、テストの段階になって、全てのミスや矛盾が絡みあって吹き出したのです。

2.プログラムのバグがどのようにして作り出されるのか?

「要求仕様のミス」とか「設計モレ」と言ってもミスしようとしてミスしたわけではありませんし、故意に設計モレをしたわけでもありません。コードのインプリメントの“イージーミス”も誰もイージーミスするつもりはありません。

「設計レビューモレ」というのも、それではレビューすれば良かったのかというと、そんな単純なものではありません。その時点では、間違いなく“レビューできなかった”状況があったのであり、その意味では“レビューされてもらえなかった”と言った方が適切かもしれません。同じように、「設計モレ」も、モレるような設計しかさせてもらえなかったと言える可能性もあるのです。

 ・欠陥プロセスがバグを産み出す

それでは何がそうさせるのかというと、分かりやすく言えば「作業手順」と言ってもいいでしょう。そこでは、設計モレが見つからないような作業手順や、レビューが出来ないような作業手順が行われていたはずです。もっと言えば、その職場に広く認識された作業手順すら存在していないかもしれません。いや、現実にはその方が多いかも知れません。

しかしながら「手順」に全てを含めることは無理で、どうしても各人の「発想パターン」や「行動パターン」も含める必要があります。そこまで細かく「手順」で決めることは出来ないし、必ずしも適切ではないからです。

そこで「プロセス」という概念を持ち出したわけですが、此処で言う「プロセス」とは、入力データに対して何らかの作用を及ぼして、結果を出す行為の総称として用いています。「設計作業」とか、「モジュール仕様書の作成」というのは、何らかの成果物を生成しますので問題なくプロセスと認識できるでしょう。「ウォークスルー」や「インスペクション」も、成果物そのものは生成しませんが、成果物の品質を変化させますので、これもプロセスに含めます。したがって、「設計書」を作成している担当者の「思考」や「行為」もプロセスということになります。

これらのプロセス自身が適切でなかったり、プロセス間の連携が適切でなかったり、プロセスの品質をチェックするための適切なプロセスが設定されていないとき、『バグ』が入り込むのです。

分かりやすくいえば、生成物にバグが含まれる(入り込んだ)のは、それを生み出したプロセス自身が欠陥をもっているか、バグを含んだ「もの」をそのプロセスにインプットしたかの何れか、または両方なのです。つまり、バグの原因は“プロセスの品質”にあるのです。

 ・繰り返されるバグ


したがって、バグを無くそうとすれば、それらの“プロセスの品質”を改善するしかありません。コードになった「バグ」を発見してその原因(正しくは“原因”ではない!)を修正しても、その行為は、そのような「バグ」を生み出したプロセスとは何の関係もありませんし、そのプロセスには何ら作用を及ぼしません。これが同じ様なバグが何度も繰り返される「原因!」なのです。

担当者が変われば、結果が変化するというのは、その組織で行われている作業手順?は変わっていなくても、個人のなかにあるプロセスが変化したからです。「こんなもんでいいだろう!」というプロセスと、「もうちょっと考えて見よう!」というプロセスの違いが結果の差になってくるのです。

それでも、そのような「内なるプロセス」だけで問題が片付くわけではないことは言うまでもないでしょう。どうしても「外のプロセス」の方が強いのです。レビューの運営の仕方を越えて、「内なるプロセス」の改善だけでレビューの精度がそれ以上に上がることはありません。
したがって、この組織も、この状態で今後も同じ様なバグが繰り返される筈です。

 ・“イージーミス”の意味するところ


仕様の追加が、評価の2日前に届くようなプロセスの状態ではイージーミスが起きても不思議ではないのです。あと4時間で仕上げなければならないという状況では、“多分、これでいいのだろう”ということで、確認が甘くなってしまうことは避けられないでしょう。

「え〜と、構造体の名前はなんだったけ」というとき、「この関数を他に呼んでいるのはどこだ」と言うときに直ぐに分かるような仕掛けになっていない(様なプロセスの)状況であったり、その要求を入れるためにどの関数を修正すべきかを判断する材料が用意されていない状況であったりすれば、イージーミスは簡単に起きてしまいます。

そして、バグの処理票の「原因欄」には「構造体名を間違えたため」と記入されるのです。イージーミスの殆どは、こういう仕組みで発生しているのです。二度と起こさないように「注意」して直る問題ではないのです。

3.バグを無くすにはどうすればいいのか?


此処までのところでバグの正体は大体分かっていただけたものと思います。バグは、工場のラインと同じように、開発工程上のプロセスの欠陥なのです。
ラインの場合は、工程間で欠陥の有無がチェックされ、欠陥品を次工程に流さないようにします。そして、その欠陥の様子から、プロセスの問題の箇所を割り出し、その箇所を修理したり、流れ方を改善したりします。

その原因が必ずしも工場のライン上にあるとは限りません。設計の仕方によっては、組み立て工程で不良が発生しやすくなります。これは、設計工程の欠陥を製造工程にまで持ち込んだということです。このような欠陥を無くすために、設計工程でのレビューに、生産プロセスの専門家に参加してもらうのです。後工程の人を早い段階で参加してもらうことで、各々の工程の段階で品質を上げるのです。これが「コンカレント開発」です。

 ・プロセスの問題個所を知る


結局、バグを無くすためには、欠陥(品)を作り出すプロセスを見つけ、欠陥が入り込む仕掛けを見つける必要があります。バグの「本当の原因」はそのようなプロセスであって、プログラムのコード上の処理の誤りは「原因」ではありません。それは、むしろ「発症の仕組み」とでも言うべきものなのです。デバッグで分かることは「こういう仕組みでバグを発症した」ということであり、その後のコードの修正は、発症を抑えるための施された治療行為に相当するものです。

「原因」とは、それが治癒されれば2度と同じ原因で発症しないもののはずです。もし、プログラム・コードの処理の間違いが「原因」だとすると、それが治された後も、その種のバグがその後も頻繁に起きることに対して説明がつかなくなります。

多くの開発現場において、「原因」という言葉が間違えて使われているために、本当の原因が他に存在することに気付くきっかけを失っているのです。言葉は、正しく実態を表すところに用いられなければ、効力を発揮しないのです。

ではどうやってプロセスの欠陥箇所を見つけるかというと、それは発症したバグを分析することによって知ることが出来ます。と言うよりそれ以外の効果的な方法はないと思います。
もっと標準的な表現をすると、「基準を満たさない現象」があれば、それとの「差」が欠陥であり、それを分析すれば原因をしることが出来るのです。

その意味では、スケジュールを外すことも、予定外のリワークも、すべて「欠陥」ということが出来ます。その場合、スケジュールやその時の作業予定が「基準」なのです。そして、このような「基準」があって初めて「差」として認識されるのです。もし、その組織に“守るべき”スケジュールがなければ、スケジュールを外しても「差」として認識出来ません。したがって「原因」を求めて分析することも出来ないでしょう。

プログラムのバグを分析することによって、例えばそのバグは設計モレに起因していて、しかもそれを事前に見つけることが出来なかったということが分かります。したがって、各々の設計書に盛り込まれようとしている内容が明確にされるよう(な成果物が生成されるよう)にプロセスを変えなければなりません。さらに、それを早い段階に検証(頭のなかで“動作”させること)するプロセスを組み入れなければなりません。

 ・プロセスを直す(変更する)


一方、そのようなプロセスを新しく(?)組み入れることによって、開発期間の前半のウェートが大きくなるかも知れません。そうなると今までの作業手順(プロセス)のままでは納期や予算を外してしまう危険があり、それも見直さなければなりません。つまり前工程に時間を掛けた分だけ、後工程の作業が軽くなるように考えられなければなりません。

どのような組織であっても、そこに“存在する”プロセスは、全体としてお互いに“バランス”しているものです。欠陥を含んだ成果物を出すプロセスも、組織全体のなかで吊り合っているのです。ですから、そのような中に新しい(望ましい)プロセスを故意に入れようとすれば、そのバランスを崩してしまうのです。

そこに“存在する”好ましくないプロセス(群)の繋がりは、ある時間の中で、お互いに折り合いをつけながら「安定」するところに収まったものということができますが、そのようなものであっても、意識してプロセスを変えようとすれば、一種の免疫反応によって拒絶されるのです。取り組み方が不用意であればあるほど、激しい拒絶反応が起きてしまいます。

大事なことは「全体」を見ながら、新しいプロセスが収まりやすくすることです。この種の取り組みが殆ど成功しない理由は、バグの分析からそれを早期に発見するような取り組みを考えても、実際には全体の手順が何ら見直されていないために、その場になって、改善のためのプロセスを実行すれば納期に対して不安が生じてしまい、結局、今まで通りの作業に戻ってしまうのです。
そのような新しいプロセスを組み入れることが“出来るかどうか”ではなく、うまく組み入れる為にはどうすればよいのかというスタンスでなければ実現しないのです。

Cleanroom 手法」に取り組むにしても、このことが意識されていなければ、個々の工程の品質を上げることは出来なくなるでしょう。
先ずは、バグを分析して、直すべきプロセスを見い出し、周到な計画に基づいてそれを改善して行くことです。それが一番の「近道」なのです。


「Index of SE の為の講座」へもどる