プログラマyasuhoの隠れ家

某ソフトウェア企業に勤務するおじさんプログラマyasuhoです

デバッグは最高に面白いパズルゲーム


デバッグで大切なことは、様々な方向から問題を見るクセをつける、原因を推測するためのカンを養っておく、の二つだと思います。

バグを発見する方法


スラドにてバグを発見する典型的なやり方ってありますか?という記事を見かけた。


これは面白そうなので、反応してみる。:)


人によってプログラムの書き方が異なるように、バグの調査方法も人それぞれです。こういう方法もあるぐらいに考えた方がよろしいかと。

初期解析


問題が発生した。テストでは問題なかったのに。よくある話だ。(笑)


初期の段階で行うことは、まず状況の分析。現象から問題を引き起こしたであろうコンポーネントやモジュールを推測する。


この時点で原因らしきものが発見できればラッキーだ。可能であればプログラムを修正してテストしてみよう。

解析フェーズ


多くのバグは初期段階で発見できる。しかし、多数のコンポーネントが絡んでいたり、すぐに再現できないような場合、問題は長期化する。


この段階では、原因部分を特定するための絞込がメインとなる。デバッガを使ったり、Log情報を出力するデバッグモジュールを組み込んだりして、原因を特定するための細かい情報を収集する。基本的には消去法を使うとよい。まず関係のないモジュールを排除していこう。


初期段階と同じく、ある程度「当たり」をつけて情報収集しよう。ただやみくもに情報集めばかりしても、かえって効率が悪いことが多い。原因部分が全く特定できない場合でも、まずはこの部分、次はこの部分というように、なるべく調査範囲を広げすぎないように心掛けるとよい。


あらゆる角度からバグの原因を疑ってみることも重要だ。煮詰まってくると、どうしても視野が狭くなりがち。時々視点を変えてデバッグしてみると、意外な事実に気づかされるもの。

再現待ちフェース


再現性が低い、客先でしか再現しない、でも原因がつかめない。そういった場合は、要所に「トラップ」をしかけたモジュールに入れ替えて、バグが「罠」に引っ掛かるのを待つ。


再現性が低い場合は、トラップを仕込むことでタイミングが変化し、問題が発生しにくくなることも多い。こうなるとバグ探しは大変だ。とにかく少ない情報から原因を推測する。問題と思われる修正を施してみる。


机上デバッグも有効である。なるべく複数人集めてチェックするとよい。自分一人だと気づかなかったことが、他の人に簡単に発見されたりするから。

問題回避フェーズ


どうしても原因が分からない。しかし問題は発生する。お客さんは困っている。


原因を突き止めてバグを修正するのが正攻法だが、それが出来ない状況も存在する。そういう場合は不本意ではあるが、回避コードを作成する場合がある。とりあえず問題の部分が通らないようにするのだ。


もちろんこれは「その場しのぎ」でしかない。将来は原因を突き止めて、バグを修正しよう。

バグを早く見つけるには


バグを早く見つけるための心がまえとしては、二つの大きなポイントがあると思います。

  • バグの原因を予測する「勘」
  • 一つのことにとらわれず、いろいろな角度から現象を見る習慣


ちょっと不謹慎な言い方かもしれませんが、私はデバッグはパズルを解くようなものだと思っています。問題をいろいろな方向から探り、多くの可能性を疑い、勘を働かせて、問題を解決する。その過程は、まさにパズルを解く感覚に近いです。原因が分かった時の喜び、分かってみたら実は簡単な問題、そんなところも似てるかな。


デバッグの勘を養なうには、やはり経験しかないと思います。多くのシステムやコンポーネント、自分が作ったプログラム以外に他人のプログラムも見てみる。多くの経験をすることで、バグを発見する能力は高まっていくでしょう。

次回予告


次回は、バグを混入させないコーディングについて書いてみようかな。