どんなやっかいなバグでも見つける9つの原則
-
バグを発見するのに時間がかかる人は、デバッグの基本的な原則を無視しているためだ。 ひとたび体系的に原則を適用できるようになれば、バグを見つけるのは早くなる。
-
効率的なデバッグのためには、これらの原則はすべて必要だ。 デバッグが得意な人はみな無意識のうちにこれらの原則を理解し、適用している。
これらのルールはおもにソフトウェアのバグを見つけるためのものだが、 基本的にどんなものに対しても応用できる。
この原則は一番重要なので最初にきている。
- 文書はきちんと読め。
- 時には隅から隅まで目を通す必要もある。
- 基礎はきちんと学んでおくべし。 チェインソーがうるさくても「異常」ではない。
- 処理の流れを理解せよ。 エンジンの回転はギアを通してタイヤへと伝わる。
- ツールをきちんと理解せよ。 ログの見方、ツールの使い方、そしてその注意点。
- 細部にも注意を払うべし。 うろ覚えの記憶に頼るべからず。
「意図的に失敗させる」のはデバッグの成功・失敗を決める極めて重要なステップである。 これができれば解決は近いし、できなければ永久にバグは見つからないかもしれない。
- 何度でも好きなだけバグを発生させられるようにせよ。 そうすれば原因を追求できるし、本当に直ったかの確認もできる。
- 安定した状態から再現できるようにせよ。 バグは複雑なシステムの状態の結果起こるものである。バグを確実に起こすステップをつくりだせ。
- 失敗しやすい状況になるよう工夫せよ。
- しかし「失敗した状態」を人工的に作ってはならない。 できるだけ不具合が起きたシステムそのもので再現させよ。「類似の」システム上での再現は劣っている。
- 条件が簡単に再現できない場合は、条件をばらつかせろ。 こういうときは自動化テストツールが役に立つ。
- すべてを詳細に記録しておき、再現のヒントをつかめ。
- 統計を信頼しすぎるな。 統計はパターンを見つける手助けになりうる。しかし逆に目くらましになることもあるので注意。
- 「そんなこと起こるわけがない!」 「そんなこと」とは一体、何なのか? 実際に起きている現象は「そんなこと」ではなく別のことかもしれない。
- デバッグ用のツールは捨てるな。 たとえ一過性のツールでも次回にまた使える可能性があるし、それが売りものになる場合すらある。
ソースコードを眺めながら「こうにちがいない」と推測するのは危険である。 必ず実際に起こっている現象を確認してから修正すること。 さもないと、思いもよらない勘違いにつながる。
- 自分の目でバグが起こっている箇所を確かめよ。 原因だと「思われる」だけでは不十分である。
- しかも、その箇所をできるだけ細かく特定せよ。
- 測定器・検出ポイントを仕込んでおけ。 本番環境でこれをやるのは手間がかかるが、それだけの価値はある。
- 追加できるツール・検出ポイントを準備しておくべし。
- 手を汚すことを恐れるな。 いざとなれば本番システムの中まで踏みこんでいく必要がある。
- ハイゼンバグに注意! 測定器がシステムに与える影響を無視すべからず。
- 推測は、探索範囲を狭めるためだけに使うべし。 実際の現象はこの目で確認する必要がある。
バグを特定するための唯一ともいえる戦略。
- 探索範囲をじょじょに狭めていけ。
- ただし、最初の「範囲」には注意。 そもそもバグがその外側にあったら、探索は失敗する。
- 「バグはどっちの側にあるか」を特定せよ。
- 一目でわかる目印を使え。 必要とあらば「目立つもの」を仕込んでおくこと。
- 探索は「動かない部分」から始めよ。 正常な部分から始めたら探索候補は山のようにある。
- バグを見つけたら、すぐに取り除け。 そうすることでさらに深い原因まで探索できるようになる。
- まず、ノイズを除去せよ。 細部に気をとられると本当の原因に近づきにくい。
いわゆる「ショットガンデバッグ」、数打ちゃ当たる式にあちこちを 同時に直すのは危険である。たとえ直ったとしてもどこが本当の原因だったのか わからずじまいだし、最悪の場合は「直ったように見えるだけ」で直ってない可能性がある。
- 鍵となる要因のみに絞りこめ。
- まず自分の手を縛れ。 よくわかっていないうちに手を出すと、なおさら被害が拡大する恐れがある。
- 一度にひとつのことだけを試せ。 効果がなかったら、すぐもとに戻すこと!
- 良い場合の結果と比較せよ。
- 前回から何をやったか記録をつけよ。
「短いエンピツのほうが、どんな長い記憶よりも長持ちする」
- 何をどういう順序でやったか、そして何が起こったかを詳細に記録せよ。
- ささいなことでも重要な手掛りになりうる。
- 同時に起きた出来事 (とその時刻) も記録せよ。
- これまでの変更点もすべて記録しておくこと。
- 頭で覚えようとするな、書いておけ。
「思い込みはウソよりもたちが悪い」 - ニーチェ
- 自分が当たり前と思っていることを疑ってみよ。 電源は本当に入っているか?
- 最初から順を追って考えてみよう。
- ツールも故障する。 まずツールが正しく動いているかテストせよ。
- まず他人に説明してみよう。 アヒルちゃん人形に説明するだけでもバグが解決する場合がある。
- 専門家に聞くのを恐れないこと。
- 経験者のアドバイスに頼ろう。
- 助けはいたるところにあることを忘れるな。
- 自分ひとりで解決しようと思うべからず。 他人に相談して解決しても、それは立派な成果だ。
- 「自分の考え」ではなく、起こったことを話すこと。 他人の目まで曇らせる必要はない。
- ささいなことももしかするとヒントになる可能性がある。
ほとんどのバグは「自然に治る」ことなどありえない。 自分が直していないものは、直っていないのだ。
- それが本当に直ったかどうか確認せよ。
- それが本当に自分の方法で直ったのかどうか確認せよ。 確実なのはいちどもとに戻してみて、バグが再発するかどうか見ることだ。
- バグが「勝手に直る」ことなどない。
- ただの回避策でなく、そもそもの原因を直すべし。
- 最終的には、設計から見直すのが一番だ。
遠隔地にいるユーザのシステムをデバッグするのはさらに大変である。 アマチュアであるユーザは重要なことを見落し、記憶も確かではなく、 作り話を言うこともある。またユーザはすでにさんざん試行錯誤した 後かもしれず、その変更履歴は残っていない。にもかかわらず、 貴重な時間は刻一刻とすぎてゆく。
「1オンスの忍耐は1ポンドの脳味噌に足る」 - オランダの諺
- たとえ信頼できない状況でも、9つの原則に従うよう努力せよ。
- すべての結果を曖昧なく逐一確認せよ。 ユーザは誤解もするし、ミスもする。これらを早期に発見し是正せよ。
- なるべくログや監視ツールなどの自動化ツールを使うべし。
- 当たり前と思われる前提もチェックせよ。 相手はPCを使うのに電気が必要とは思っていないかもしれない。
- 既知の問題を参考にすべし。
- 問題が解決したら、トラブルシューティングガイドに追加せよ。 そうすれば次回の人はすこし楽になる。