はじめに
次から次へとバグが発生するソフトウェアシステムにおいて、Coverityはいかにしてバグ発見ツールを構築し、ビジネスを確立したのだろうか。本稿では、米国Communications of the ACMの"A Few Billion Lines of Code Later: Using Static Analysis to Find Bugs in the Real World"の記事を一部転載して、バグ発見の法則について紹介する(翻訳:コベリティ日本支社)。
バグ発見の法則
バグ発見の基本法則は「チェックなければバグはなし」である。ツールがシステム、ファイル、コードパス、一定のプロパティをチェックできなければ、バグも発見できない。適切なツールがあると仮定すると、バグの勘定をまず拘束するのは、そのツールを使って一体どれだけのコードをこなせるか、ということだ。コードが10倍になれば発見されるバグも10倍になる。
この法則は、充分に簡潔に事実を述べているものと推測した。残念なことに、一見すると無効な2つの結論が、バグの勘定に厳しい一次限界を設けることとなった。
法則:見えないコードはチェックできない。「コードをチェックするには、まずコードを見つけなくてはならない」という指摘は、あまりに陳腐に聞こえるかもしれないが、膨大なコードベースでそれを首尾一貫して実施してみれば、言っていることの意味が分かるだろう。システムをチェックする上でもっとも信頼できる方法はおそらく、プログラムのビルドの過程でコードを獲得することだ。ビルドシステムは、どのファイルがシステムに含まれており、どのようにコンパイルするかを熟知している。これは簡単なことのように思われる。ところが残念なことに、その場しのぎで作られた自家製ビルドシステムがこうした情報の抽出を滞りなく行うべく充分な働きをしているかは理解しがたいということが頻繁に起こる。「そこに触れては駄目だ」という、ありがちな絶対的命令により、困難の度合いはさらに増す。
企業は通常、外部の人間が何かを修正するのを拒むものだ。彼らのコンパイラパスや破損したメイクファイル(それがある場合)を修正することはできず、自分自身のテンポラリファイル以外は、何も書いたり再設定したりすることができない。修正するにしても理解できないのが関の山なので、それはそれでよしとしよう。
そのうえ、企業はセキュリティのためにテストマシンの設定を厳格化することも多い。その結果、チェックのために与えられたビルドが最初は正常に作動しないことも珍しくなく、何か手を加えていた場合には非難されることになる。
2002年の商品化で最初の数か月に我々がとったアプローチはローテクな、ビルドコマンドの読み取り専用の再生だった。メイクを実行し、ファイルへのアウトプットを記録し、コンパイラ(gccなど)への呼び出しを書き直し、当社のチェックツールをかわりに呼び出した後にすべてを元に戻す。簡単で単純なやり方だ。このアプローチは、研究室と初期の少数の顧客では完璧に機能した。その後、我々と見込み客への間では次のような会話が交わされた。
御社のツールは、どうやって実行すればいいんでしょうか?
ただ「make」とタイプしてください。そうすれば当社がアウトプットを書き直します。
「make」ってなんですか?うちはClearCaseを使っているのですが。
えっ、ClearCaseってなんでしょう?
これは乗り越えることのできない隔たりとなった(厳密にいえば顧客は「ClearMake」を使っていたのだが、表面的には名称が似ていても、技術レベルではまったく役に立たない)。この会社はあきらめて、我々は別の企業にアプローチした。彼らは我々の手法のまた別の問題を露わにした。しかし、こうした問題について、我々は敏速に随時対処してきた。そのどれもが、アプローチの再検討を迫るほど厄介なものにはみえなかった―――少なくとも、ある大手顧客から次のようなサポート依頼の電話を受けるまでは。
「御社のツールを実行するとき、なぜLinuxをCDから再インストールしなきゃならないのですか? 」
これは実に不可解な質問だった。さぐり回ったところ、次のような一連の出来事が明らかになった。この会社のメイクは、コンパイラが実行されるディレクトリの絶対パスをプリントアウトするのに新しいフォーマットを使用していた。当社のスクリプトはそのパスを誤って解析し、空白文字を生成したが、それがUnixの「cd」(change directory)コマンドの宛先として与えられ、システムのトップレベルに変更された。これはコンパイル中に「rm -rf *"」(再帰的な削除)を実行し、テンポラリファイルをクリーンアップした。そしてビルドのプロセスはルートとして実行された。このようなイベントが組み合わされて、システム上のすべてのファイルが削除される結果となったのだ。