デバッグは最高に面白いパズルゲーム
デバッグで大切なことは、様々な方向から問題を見るクセをつける、原因を推測するためのカンを養っておく、の二つだと思います。
バグを発見する方法
スラドにてバグを発見する典型的なやり方ってありますか?という記事を見かけた。
これは面白そうなので、反応してみる。:)
人によってプログラムの書き方が異なるように、バグの調査方法も人それぞれです。こういう方法もあるぐらいに考えた方がよろしいかと。
初期解析
問題が発生した。テストでは問題なかったのに。よくある話だ。(笑)
初期の段階で行うことは、まず状況の分析。現象から問題を引き起こしたであろうコンポーネントやモジュールを推測する。
この時点で原因らしきものが発見できればラッキーだ。可能であればプログラムを修正してテストしてみよう。
解析フェーズ
多くのバグは初期段階で発見できる。しかし、多数のコンポーネントが絡んでいたり、すぐに再現できないような場合、問題は長期化する。
この段階では、原因部分を特定するための絞込がメインとなる。デバッガを使ったり、Log情報を出力するデバッグモジュールを組み込んだりして、原因を特定するための細かい情報を収集する。基本的には消去法を使うとよい。まず関係のないモジュールを排除していこう。
初期段階と同じく、ある程度「当たり」をつけて情報収集しよう。ただやみくもに情報集めばかりしても、かえって効率が悪いことが多い。原因部分が全く特定できない場合でも、まずはこの部分、次はこの部分というように、なるべく調査範囲を広げすぎないように心掛けるとよい。
あらゆる角度からバグの原因を疑ってみることも重要だ。煮詰まってくると、どうしても視野が狭くなりがち。時々視点を変えてデバッグしてみると、意外な事実に気づかされるもの。
再現待ちフェース
再現性が低い、客先でしか再現しない、でも原因がつかめない。そういった場合は、要所に「トラップ」をしかけたモジュールに入れ替えて、バグが「罠」に引っ掛かるのを待つ。
再現性が低い場合は、トラップを仕込むことでタイミングが変化し、問題が発生しにくくなることも多い。こうなるとバグ探しは大変だ。とにかく少ない情報から原因を推測する。問題と思われる修正を施してみる。
机上デバッグも有効である。なるべく複数人集めてチェックするとよい。自分一人だと気づかなかったことが、他の人に簡単に発見されたりするから。
問題回避フェーズ
どうしても原因が分からない。しかし問題は発生する。お客さんは困っている。
原因を突き止めてバグを修正するのが正攻法だが、それが出来ない状況も存在する。そういう場合は不本意ではあるが、回避コードを作成する場合がある。とりあえず問題の部分が通らないようにするのだ。
もちろんこれは「その場しのぎ」でしかない。将来は原因を突き止めて、バグを修正しよう。
バグを早く見つけるには
バグを早く見つけるための心がまえとしては、二つの大きなポイントがあると思います。
- バグの原因を予測する「勘」
- 一つのことにとらわれず、いろいろな角度から現象を見る習慣
ちょっと不謹慎な言い方かもしれませんが、私はデバッグはパズルを解くようなものだと思っています。問題をいろいろな方向から探り、多くの可能性を疑い、勘を働かせて、問題を解決する。その過程は、まさにパズルを解く感覚に近いです。原因が分かった時の喜び、分かってみたら実は簡単な問題、そんなところも似てるかな。
デバッグの勘を養なうには、やはり経験しかないと思います。多くのシステムやコンポーネント、自分が作ったプログラム以外に他人のプログラムも見てみる。多くの経験をすることで、バグを発見する能力は高まっていくでしょう。
次回予告
次回は、バグを混入させないコーディングについて書いてみようかな。