Blog ブログ

デバッグ Debug No.1

今日は、 プログラマの安藤です。

さて、前回 はエラー処理についてお話したわけですが、そのなかで少しだけデバッグについて言及しています。そうなると今度はデバッグについて語らなければなりますまい。

え?タイトルのネタが古い?いいんです。解る人だけニヤリとしてくれれば。

例によってまずは用語の定義。

不具合(ISSUE):
製品の望ましくない振る舞い
バグ(BUG):
不具合の原因となるプログラム上の欠陥
デバッグ(DEBUG):
欠陥のあるプログラムを修正すること

さて、この定義によれば、不具合の原因はバグだけではないって理屈が成り立つわけですが、今回はバグ以外の不具合の原因については言及しません。これはこれで面白おかしいトピックではありますが。

そして、デバッグというのは不具合を発見することではなく。不具合の原因を究明することってことになります。

普段はバグと不具合を区別して考えることは少ないですし、実際のところ私たちプログラマも混同してバグって言葉を使っていることも多い。っていうか今 web 翻訳で「不具合」を翻訳したらいきなり「Bug」って出力されて困っちゃった。

と、とにかく、この文書のなかでは「バグ」と「不具合」を明確に区別します。

有名なところでは、マーキュリー計画で、コンマとピリオドの typo でロケットが爆発したって伝説のバグがあります。
このバグの場合

  • バグ : コンマとピリオドの typo
  • 不具合 : ロケットが爆発
ってことになります。(ナニ、そんなバグの話なんか知らない?近くのおじいちゃんプログラマに聴きなさい)
それはさておき、開発現場では、テストチームが不具合を報告したチケットが関係者の間で行ったりきたりするわけですが、悩ましいことに不具合報告はバグの在処までは教えてはくれません。
観察された不具合は、なんらかのバグが引き起こした結果に過ぎないわけです。

ここでデバッグ担当のプログラマは、不具合を起こしたプログラムの状態をデバッガで調べて、まず、こうつぶやいて途方にくれます

「どうしてこうなった?」

そこには、辻褄の合わないカウンター変数であったり、全く期待はずれのデータを参照するポインタであったり。バグの結果生じた壊れたデータが見えるばかりです。バグのあるコードですぐに停止してくれるような簡単な不具合なんて製品テストの段階まで残ってやしません。

さて、途方にくれてばかりいては仕事になりませんから、この事故現場から、事故を引き起こした犯人、もといバグのありかを推理する手がかりを探すことになります。だれかコナン君呼んできて!!

ガーベージ・イン・ガーベージ・アウトの法則ってものがありまして、全くバグのないコードにゴミのように壊れたデータが食わされることがある。そうなるとさらにゴミのような結果を吐き出して、それが他の正常なコードに連鎖反応のように作用し、最終的に不具合として現れる。

このような場合、なんとかして最初のきっかけとなったバグをあぶり出さなきゃならない。だれかホームズ呼んできて!!

ここで担当プログラマに悪魔の囁き。

「ゴミの入力データを検出して辻褄の合ったデータに成形しなおせばとりあえず不具合はなくなるんじゃない?」

こういうのはデバッグとは言いません。むしろバグの存在を覆い隠す試みです。バグのあるコードが作ったゴミデータからは重要な情報が失われているじゃありませんか。結局のところ、すぐにバレる間違いからもっともらしい嘘に変換しているだけ。

ゴミをどんなに飾り立てたところで食べられるようにはなりません
こういうことをすると、因果関係のよくわからない不具合がさらに報告されることになります。そして、元々のバグのありかを探すのを難しくしてしまい、出荷をさらに遅らせることになります。ゴミ隠蔽、ダメ、ゼッタイ

それではどうするか。

まず、デバッガでデータの壊れ具合を観察し、どのような手順でで観察された壊れたデータが作られるかシナリオを想定する。この段階でどれだけのパターンを思い描くことができるかがポイント。

次に、そのシナリオが実際に起こるケースがあるか、実行されたコードを分析する。そして起こる可能性の無いシナリオを排除する。

可能性のないケースを全て排除して、最後に残ったものが真実だ。ワトソン君。

ともあれ、めでたくバグのあるコードを見つけて修正したとしましょう、そのバグが不具合の原因だったことをどうやって確認しますか?

と、いうわけで、不具合報告には、不具合を発生させるための再現手順が必須となります。修正済みのプログラムで再現手順を実行して不具合が確認できない場合、めでたく不具合の原因は取り除かれ、問題は解決されたことになります。

再現手順がはっきりしていれば、これでめでたくバグが一件修正されたってことになりますが、やはり現実は厳しい。発生する条件がはっきりしない不具合がつねに一定の割合で報告されてくる。

突然ランダムになんの前触れもなくプログラムがクラッシュしたり、一定の操作を何度も繰り返したらたまに不具合が発生したり。

このように再現性の低い不具合の場合に犯人、もといバグのありかを突き止めるには、徹底的に論理的な思考しかありません。だれか金田一君を呼んできて!!

マルチスレッディングによる並列処理のバグなんかは大抵の場合こんな再現性の低い不具合となります。このようなバグのありかを推論するにあたって、不変条件という概念が強力なツールになるのですが、その話はまた別の機会に。


クラウドクリエイティブスタジオではプログラマを募集しております。
一緒に面白いゲームを作っていきましょう!