🐈

デバッグに関する9つの原則

2024/02/11に公開

この記事は デバッグルール―9つの原則、54のヒント
という本を私が読んだ上で内容をまとめたものです。対象の本は新書ではもう発売されておらず、中古なら売ってるところがあるかな?という感じです。デバッグについて原則を知りたい人、対象の本を気になって調べてみた人に向けた記事です

本記事の対象者

書籍に関わる情報

著者

1954年のアメリカ人男性の電子工学エンジニア

書籍の対象読者

  • エンジニア
    • ハードウェア、ソフトウェアは問わない
  • デバッグを扱う人々を管理する立場の人
  • デバッグに関して教える機会のある教職の人

取り上げてないこと

  • 問題自体が起こらないようにする予防やプロセスの話
  • 特定の言語や環境に依存するTips

書籍の構成

著者本人の経験した問題例と原則がセットで書かれています。それらの問題例の多くがハードウェアに関する問題が多く、ソフトウェアの話は少なめです。ただし原則自体はソフトウェアのデバッグにも使えるものとなっています。

9つのルール

書籍に書かれている9つのルールについてまとめました。

その1: システムを理解する

システムに分からないところがある場合、問題は大体そこにある気がする。これは単なるマーフィーの法則ではない。「設計時に理解していない部分があると、そこで問題が起きやすいものだ。」という話。

理解するために

  • マニュアルを読む
    • ライブラリーであれば公式ドキュメント、モジュールであれば仕様書
    • どこかでバグが起きている時点でマニュアル全てを信じ切ることは危険だが、最初の理解としては重要
      • 料理が思った通りできない場合、レシピ通りにしてないことが理由である可能性が高いように、マニュアルを読んで理解していないことが原因のことはよくある
  • 徹底的に読む
    • 自分が重要であると思うところだけでなく、徹底的に読み込む
    • 問題の原因を突き止める鍵はまだ読んでないところにある。

何が正しいかを知る

  • 何が正しいかを知る
    • チェーンソーンの音を一度も聞いたことない人はブンブンうるさくなる音が問題であると勘違いする可能性がある
  • 何が問題かに気づくためには基礎知識が必要

現状を知る

  • 問題を切り分けるためには、どの機能がどこにあるかを知る必要がある
    • オーブントースターでトーストを焦がしたら、調整つまみで焼き時間を調整できることを知ってる必要がある
  • 問題が起きた時、通過する全てのAPIやモジュール、手順を理解しておく必要がある
    • トーストが焦げた例
      • 調整つまみで時間を短くしてもトーストが焦げた場合は、トースターの時間を調整する機能が壊れていると理解できるので、新しい物を買うか修理に挑戦すればよい

ツールを知る

  • デバッグツールは目となり耳となります
    • 正しく使用し、結果を正しく解釈する必要がある
      • 例えば、体温計の反対側を口に入れても意味がない
  • 多くのツールは使い込んだ人だけが知っている強力な機能がある
  • ツールを使い込めば使い込むほどシステムで何が起きているかを理解できるようになる
    • 時間を割くべき
    • ツールでできることは全て習得しよう

その2: わざと失敗してみる

もう一度やってみる

  • 自分が何をしたか調べて、もう一度再現してみる
  • 作業を進めながら手順を一つ一つ書き留める
    • 書き留めた手順に従ってやると、本当にエラーが起きるかを確認する
  • バグは環境や状況に依存する可能性があるので、手順の最初には環境や状況を書き留めておくこと
    • 寒い日に車の窓がくっつことを整備士に調べてもらいたいなら、あなたが毎朝洗車していることを伝える必要がある

失敗を促す

  • 失敗する手順に多くの手間がかかる場合は、テストなどを書き自動化することが有益
    • 飲酒運転の疑いかけた警察官はを相手にもう一度ハイウェイを走らせて確かめるようなことはしない。まっすぐに歩かせたりして簡易的に確かめるものだ
  • ただし、メカニズムを変更してはならない
  • 「新しい問題を生み出す」のではなく「促す」
    • 何かを変更するときが頻度にだけ影響与えるような高いレベルで行う必要がある
    • 窓の水漏れをテストするために消防用ホースを使い、窓ガラスを粉々にして、「原因は窓ガラスである」と言ってはならない
      • 窓自体に影響が出ないように普通のホースで水をかければよい

制御されていない条件を見つけ出す

  • どの条件がシステムに影響するかわかった時点でいろんな組み合わせを試してみればよい
    • 起こした結果を書き出す
  • 条件を調整すると問題が解決することもある
    • これは問題が起きる条件を特定したことになる
    • その条件を書き出して、その条件を色々変えてみて観察する

統計データに騙されるな

  • わざと失敗させる理由のもう一つとしては「原因の糸口をつかむこと」
  • 問題がいつ起こるかわからない場合、例えばボタンを右手でクリックする場合と左手でクリックする場合など意味のない比較を膨大にすることになる
  • 十分な情報が集まれば、問題に常に関係あることと、いっさい関係ないこととの区別がつく
    • 問題が解決したのか、たまたま運がよかっただけなのかが分かる
  • テストのサンプルは多いほど良いが、必ず発生する一連の流れを探す方が圧倒的に有効である

そんなことはないが起きることもある

  • 開発者が「そんなはずはない」と思うことが起こったりすることもある
    • テスト実施者のミスで実際には起きてないかもしれないし、本当に起こったかもしれない
  • まずやるべきことは、憶測を取払い開発者自身が再現してみること
  • 「そんなこと」を発見するには、再現してみてデータをとって状況を確認するしかない

その3: 考えるのをやめて観測する

まず「観察する」

  • エンジニアは 「思想家」
    • 考える方が楽しいし、肉体労働よりも楽
    • エンジニアにとって「観察する」より「思想する」方が楽
  • ただし、問題がおきたいきさつは想像力を超えることがある
  • 「観察する」のは難しい
    • ソフトウェアで「観察する」ということは、ブレークポイントを設定し、デバッグ文を追加し、値を監視する
      • 非常に複雑である
    • 根拠がない推測をして問題を特定できなくても、バグの追跡はし続けなければならない
      • 時間がただ消費しただけで何も前進していない
  • 従って、まず 「観察する」 という意識が大事なのである

問題を直接見る

  • バグを見つけた時、私たちが見ているのは問題ではなく問題の「結果」である
    • 「電気がつかない」という結果には見つけるべき問題がある
  • 実際に何が起きているかを 一部始終を観察しない限り問題は誤解されやすい
  • これが問題だと見当つけて修正しても、実際には別のところで問題が起きていることがある
    • 逆に問題が隠れたり、さらに別の問題を生む可能性もある
  • サーバが夜中に再起動する問題があった
    • 毎晩ほぼ同じ時刻に起こるので、ログなど証跡はなかったバッチ処理だと決めつけた
    • 自動的に動くプロセスを監視してみることにしたが何ヶ月も問題は発見できなかった
    • 夜中に残ってマシンの様子を眺めていたら掃除のおばちゃんが電源を抜いていた
  • 通常は近道するより 実際に見た方が数倍早い

詳しく見る

  • 前例のようにほんのちょっと見たら原因が発見できることは稀である
  • 一般的には問題を確かめるために、調査すればしただけ何が原因なのかがよく見えてくる
    より多くの情報を得るにはどこを探ればよいか判断できるようになる
  • では、どこまで観察を続けれよいのか?
    • 「システムを理解する」と同じようにここでも経験が役にたつ
    • 見当違いの推測をして、それを追いかけているうちに、どのような場合にどこまで観察すればよいかわかってくるだろう
  • デバッグの名手の基準が「どれだけ早く推測できるか」でも「どれだけ素晴らしい推測が」できるでもなく、「下手な推測に基づいて行動を起こす場合がどれだけ少ないか」 にあることを理解するだろう

ハイゼンベルグの不確定性原理に気をつける

  • ハイゼンベルグは本当に軽くて、本当に小さな量子物理学を研究しているときに、粒子の位置または運動量のどちらか一方を測定することは可能だが、一方の測定がもう一方の測定を阻害することにきづいた
  • テスト用のツールがテスト対象の システム自体に影響すること は可能なかぎり減らすべきである
    • ツールを追加したら失敗を再現してみて、ハイゼンベルグの呪いにかかっていないか確かめてみよう

あくまで検索を絞り込むために推測する

  • 「考えをやめて観察する」とは推測を全くしないということではない
  • 問題の検索を絞り込むため推察する
  • 推察が全くの的外れになることがある。
    • 調査によりその推察に根拠がない場合は最初からやりなおそう

その4: 分割して攻略する

調査範囲を絞り込む

  • ターゲットを効率よく調査するためには、逐次近似法 という手法が一般的に用いられる
    • 予想範囲内で何かを見つけるためには、範囲の両端の中間点でターゲットが通り過ぎたかどうかを確認して、通り過ぎたら、その先半分のまた中間地点を通り過ぎてないかを逐次的に調べていく方法
  • 友人に1から100の間の整数を1つ想像してもらい、あてていく作業をイメージすると良い
  • 逐次近似法には非常に重要な前提が二つある
    • 調査の範囲を知っていなければならない
    • あるポイントを調べるためには自分が問題のどちら側にいるかを知らなければならない
      • 友人が嘘をついたり、135を選んだりしたら永遠に調査は完了しない

妥当な範囲を知る

  • 近くの川が悪臭をしている場合、海まで遡るのか近くの川までに限定するのか経験と手間に従って妥当な範囲を特定する必要がある

どちら側にいるかを知る

  • 近くの川が悪臭をしている場合、汚水が流入しているのが今より上流なのか下流なのか知る必要がある
  • 各ポイントを調べ、問題が上流なのか下流になるのかを特定していく必要がある
    • 調べた結果ポイントを移動させる

目立つテストパターンを使用する

  • 綺麗だった水が赤みがかって悪臭を出していれば簡単にわかるが、バグの影響が捉えにくい場合や、データをそもそもバラついていて派手に壊れていてもわからない場合は簡単に見分けられる入力やテストパターンを用いる
    • 川の例の場合、濁った川の流れより透き通った川の流れの方が流入ポイントは見つけやすい

問題のある方から始める

  • 多くのシステムでは、本流に流れ込む支流のように、さまざなな流れが1つに合流する
    • 上流から検索を始めると見当はずれの支流を調べ時間を無駄にする可能性がある
  • 悪臭を放つ赤い排水がある悪い方から手をつけて、上流へ向かって作業を進めること
  • 例えば、加熱炉が作動しないとしよう。
    • 燃料切れはよくあるので、まずそれが原因ではないかとしれないと疑って、タンクがいっぱいかどうかを確認する。次に燃料の注入に問題がないかを確認する。注入が問題がない場合(以下略
      • 最終的にスプレーヘッドからオイルが噴出していることに気づくまでには時間がかかる
    • 問題のある加熱炉からまず調査を始めよう

分かっているバグをまず修正する

  • システムは複数のバグが紛れ込んでいるものだ
  • 発生している問題の1つを見つけたら、ほかのものを探す前にまず修正しよう
  • 修正が他の問題へ影響する可能性はある
    • 影響する場合、修正した後に再度テストしよう
  • ある問題が解決すると別の問題が解決される可能性がある
  • 修正によってどちらにせよ他へ影響出る場合は、発見が早いことに越したことはない

ノイズは先に修正する

  • 前のルールから次の結論が導き出される。「ある種のバグは、ほかのバグの原因になりやすいので、まずそれらを探して修正すべきである」
  • ノイズ信号はなかなか見つけられない断続的な問題全ての原因となりうる
    • まず他の問題を解決する前にノイズの問題を解決する必要がある
    • 他の問題は現時点で予測するのが難しくても、ノイズを除去することで解決することもある
  • ただし、そればかりに没頭してはならない
    • ノイズの問題を修正することの難しさと、それが実際に何か影響している可能性を比較しよう
    • 完璧主義になりがち
    • それらが実際に問題の原因になってないなら、通常はそのままにしておく方がよいだろう

その5: 一度に1つづつ変える

例)エンジンがかからない時の話

  • ある朝、妻の車で仕事に出かけようとした時、エンジンがかからなかった
  • ギアをパーキングからニュートラルにすればエンジンがかかるだろうと思い、ニュートラルにした
    • それでもエンジンがかからなかった
  • 妻に尋ねると車のキーの調子が悪いらしい
  • いろんなやり方でキーを回してみたが、エンジンはかからなかった
  • キーを色んな方法で回してみる前にギアをパーキングに戻していれば、エンジンはおそらくかかっていただろう
    • つまり、パーキングにギアを戻してからキーの差し方を色々試すべきだった

散弾銃ではなくライフル銃を使う

  • 変更は一つづつ行おう
    • 散弾銃のように一度にたくさんやっつける方法は、今すぐ忘れること
    • 良いライフル銃を手に入れて、一つずつやってけよう
  • 問題を実際に目撃した場合 は、それだけを修正すれば良い
    • ターゲットを撃つのに散弾銃が必要と考えた場合、ターゲットがはっきり見えてない可能性がある
      • 本当に必要なのは良い照明と良いメガネである
  • 小学校でよく行っている植物観察では、全く同じ土と全く同じ種で、全く同じタイミングで水をやり、植物にあたる日光の量だけ調整する
    • こうすると成長のばらつきは日光の照射時間によるものと分かるようになる
    • あるいは日光の照射時間を同じにし、水の量をかえると成長にばらつきがでる
  • 成長が悪いのが修正したいバグだとすると、鉢の色と水の量と照射時間全て同時に変えると鉢の色が関係ないことがわからなくなる

両手で真鍮の取っ手をつかむ

  • システムのさまざまな部分に変更を加えて、それが問題に影響するかどうか調べたくなることがよくある。
    • これは通常、ツールを使って何が起きているかを調べることではなく、推測していることなので注意が必要
    • これでは問題が起きている状況を探すのではなく、変更 してしまっている
      • この変更によって、最初の問題が見えなくなるどころか、問題をますます増えてしまうこともある
  • 原子力潜水艦のは発電装置の制御パネルには真鍮の取っ手が付いている。警報装置が鳴り出したら、エンジニアはその取っ手を両手で掴、システムで何が起きているか正確に理解するまで話さないように訓練を受けていた

正常なものと比較する

  • 問題が起きた時と正常なもので、デバッグログやトレースなど取得できるあらゆる出力を比較するだけで問題の多くが解決したりする
  • ただ、前後でコードを大きく変更すると比較が難しくなる
    • 2つのトレースの要因はバグだけに絞り、他の要因は全て排除しよう
  • 二つのテストのログは同じマシン上で続けて実行しよう
    • 異なるマシン、異なるパラメーター、異なるユーザ入力、異なる環境は避けよう

最後に動いていた時から何を変更したか考える

  • バージョン管理してるなら、問題が起きてないバージョンまで遡り問題が起き始めたところの直近の変更をみること で問題の焦点がはっきり絞られる
  • ただ、状況がそこまで単純じゃないケースもある
    • 例えば、問題はかなり前からあって、タイミングやデータベースのサイズなどの変更によって表面化することがある-バージョン5.0で問題が起きたように見えても、バージョン3.2の問題が表面化したに過ぎないこともある
  • 重要なのは落とし穴への道を塞ぐことではなく、落とし穴自体を防ぐことである

その6: 履歴をつける

例) テレビ会議システムのビデオ圧縮チップの話

  • ビデオデータを小さなサイズに圧縮して送信する必要がある
  • ある日、これといった理由もなしに圧縮の速度がかわることがあった
    • 再起動すると直る
  • チップを緩めたり冷やしたりしても改善しなかった
    • 理由がわからずイライラした
  • ある時、椅子から立ち上がると突然速度が落ちた(ように見えた)
    • 椅子から立ち上がると着ているシャツがカメラに広く映り込むことがわかった
    • その時は格子柄のシャツを着ていた
  • もう何回か立ったり座ったりして原因を調べて、わかった
    • 格子柄は対象のプロセッサが極めて圧縮を不得意とするパターンだった
  • この話のポイントは 「最も取るに足らないように見えることが、実際にはバグを引き起こす犯人になり得る」 ということ

何をどの順番で行い、何が起きたかを記録する

  • 記録をつけよう
    • 問題を調査する際には、自分が何をどの順番で行ったのか、そして結果として何が起きたかを記録しよう。これは毎回行うこと
    • ハードウェアでもソフトウェアでも同じ
  • 食物アレルギーの症状が現れると、アレルギー専門医はアレルギー反応とその時の食べたものを結びつけることで、アレルギーの原因となった食べ物を特定しようとする
    • 関連がはっきりせず、より詳しい情報が必要な場合は、食べたもの全てと時間、その時の反応を全て日記に書くように指示されるだろう
    • これが 「履歴」
  • この「履歴」からいちごを食べた時に蕁麻疹が出てることの因果関係がわかったとします。
    • そうすると医者は対処法を提示することができる。
      • つまり、この「履歴」は大切
    • 処方はもちろん「いちごを食べない」こと

例) フロッピーディスクの故障

  • カスタマーサポートに、ある顧客から立ち続けに電話があった
    • 購入したフロッピーディスクが一度だけ正常に動いたが、その後動かなくなってしまった
  • カスタマーサポートは何度も新しいフロッピーディスクを送ったが、同じように一度は正常に動き、その後動かなくなった
  • とうとうスタッフはその顧客に電話をかけ、手順を一つ一つ教えてもらった
    • フロッピーディスクは1回使った後にファイルキャビネットに  磁石 で留められていた

悪魔は細部に宿る

  • 多くの場合履歴が大事だと理解されるが、残念なことに本当に必要な詳細な記録が必ずしもあるわけではない
    • たんなる「問題がある」「動かない」しかない場合が多くある
    • グラフィックが完全に歪んでいるとも、赤い部分が全て緑で表示されているとも、3番目の数字が間違っているとも書かれない
  • ログがあるが、いつ問題が起きたが分からないレポートが出てくる時がある
    • アレルギーの場合、食べたものだけ書かれているが、いつ症状が出たか書かれていない履歴に何の意味もない
  • ログには記録されない状況や症状をデバッグトレースやログに 注釈 として書き込んでおくこと
  • 状況を説明する時には、具体的に、矛盾がないようにする
    • ビデオ通信では大体システムAとBがあり、それが相互に通信する。そして、「リモートビデオなし」とバグレポートを受け取ったとしよう
    • これでは問題はAなのかBなのかわからないし、リモートビデオとはリモート側で表示されるビデオのことなのか、リモート側から送られてきたビデオのことなのか
  • 基本的な症状を理解しないことには問題の解明に着手できない
  • もう一つ注意しないといけないのは「何が起きた」だけでなく、 「どれくらい続いたか」 である
    • 「ほとんど聞こえないほどのブンブンいう音が0.5秒続いた」なら問題ないが、「キーンという音が6秒続いた」とかなら詳しく調査する必要があるだろう

関連付ける

  • ある症状を他の症状やデバッグ情報と関連付けるのは非常に有益
    • 「とても大きな音がした」より「14時5分23秒から4秒間、非常に大きな音がした」が良い
  • 食物アレルギーと日記に話に戻ると、一枚の紙にいつ何を食べたかを下記、もう一枚野上に蕁麻疹が出たことをかいたとしても、じんましんがいつ出たか書かないと意味がない
  • 複数のシステムの連携をみる場合、同期の取れているタイムスタンプ を使おう

どんなに短い鉛筆でも、どんなに良い記憶力に勝る

  • 細かな点は記憶にたよってはならない。記録しよう
  • 自分にとって重要でないものが、別の問題を扱う他の人にとって重要なこともある
  • デバッグログやトレースを保存しておき、ログにでない事象や状況は注釈として残しておこう
  • 全てを記録しよう

その7: 電源を確認する

自分の憶測を疑う

  • 自分の憶測を絶対に信じてはいけない
    • 特に説明のつかない問題に遭遇したとき「プラグは差し込まれているか」と自問しよう
  • 凝ったデジタルチップがなぜ正常に動作しないかを疑問に思い、それでいながら実際に電源が流れているかどうかは確認しないことがよくある
  • 実行していると思っているコードは本当に実行しているだろう
    • 実際には古いコードを読み込みロードしている可能性はないだろうか
  • トラブルの原因が土台にあることはよくある
    • この世のものと思えないような問題にぶつかったら、そこで立ち止まり足元を見よう

3マス目からはじめない

  • エンジンがかからない場合、もう一つ検討すべきなのは エンジンをかける時の状況が正しいかどうかである
    • プラグが差し込まれているだろうか、スタートボタンを押しただろうか
  • 必ず最初からはじめよう
    • プログラムを実装する前にメモリーが初期化されることを前提としていても、それを明示的に行わなければ、状況は悪化するだけである

ツールをテストする

  • ツールも開発者が作ったものだ。ツール自体にバグがある可能性 がある
    • ツールにはバグがないというのは幻想だ
  • デバッグツールについても思い違いがあるかもしれない。バッテリーの切れた断線チェッカーを使って何らかの接続のテストしたら、正しい配線でもピープ音が鳴らず、接続不良だと勘違いするだろう
    • 間に配線がない状態でチェッカー自体のテストが必要である
  • デバッグログなどを入れた場合、まずコードを直す前に ログが正しく出力されることを確認しよう

例)ボイラー修理の話

  • 築90年の家で突然ボイラーが止まってしまった
  • 石油で動いていたので給油が間に合ってないと思い、給油の目盛をみたが問題なかった
    • そこでボイラーの修理屋を呼んだ
  • 修理屋も真っ先に目盛を見に行った。
    • それは確認したと話したあったのだが、彼が懐中電灯ので目盛をドンっと叩くと、メモリが0に急降下した
  • 修理屋は補充用の石油を給油して、私を都会ズレしたまぬけなやつだと冷たい目で見て帰っていった

新しい視点でものをみる

例)ブレーキライトのヒューズが飛ぶ話

  • 車の調子がおかしくなった。車をバックさせるとブレーキライトのヒューズが飛ぶ
  • すでにヒューズをいくつかダメにしていたので、車に詳しい同僚に聞いてみた
  • 同僚は「車内灯が車のフレームにぶつかって配線を締め付けているんだ。車内灯をあけて、それを取り出してしまい、まわりに丈夫なビニールテープで巻いておけば大丈夫さ」
    • 結果、直った
    • そんなことはよくあるらしい

助けを求める

  • 問題をそっくり誰かに押し付けてしまいたいという願望は別として、助けを求める理由は3つある
    • 新しいものの見方
    • 専門技術
    • 経験

新しい見解を吹き込む

  • 固定観念にとらわれていると全体像を眺めることは難しい
  • 全てに対して誰もが先入観 を持っている
    • 先入観があると、実際に何が起きているかが見えなくなる
  • 偏見のない視点で問題を見つめる人がすばらしい見識をもたらし、新しいアプローチのきっかけ を与えてくれるのはよくあることだ
  • また、問題を他人に説明 すると 自分の中に新しいものの見方 が生まれ、問題が解決することがある

専門家や経験者に聞く

  • 車内灯がショートした話のように同じような状況を目撃したことがあり、何が問題なのかをすぐに説明できる人がいる
  • 特定分野の経験を積んでいる人はなかなか見つけられないもので、したがって高くつく。ただし、投資する価値があるかもしれない

例)ベテランの技術士の話

  • 引退するまで長年にわたって大きな工場で機械を管理している男がいた
  • 彼が引退してからしばらくの間、工場は問題なく稼働していた。しかしある日機械が止まってしまい、新人の整備士のあらゆる努力もむなしく2度と動かなくなった
  • 工場主は引退した男に電話をかけ、状況を説明し助けてくれるように頼んだ
    • すると男は修理に1万ドルはかかるだろうと答えた。法外な要求だったが、工場側は切羽詰まっていたので、その要求を飲んだ
  • 男は道具箱を下げて工場にやってくると、機械が設置してあるところに向かった
    • そして、ハンマーを取り出すと、機械の側面を一回だけ強く叩いた。すると機械が動き出した
  • 工場主が「ハンマーを一回叩いただけで一万ドルとだと?」と激怒すると「それは違う。ハンマーで叩くのは10ドル、どこを叩けば良いかを知っていることに9,990ドルだ」と、誤りを正した

助けはどこからでも得られる

  • 新しい見識が必要なのか、専門知識が必要なのか、経験が必要なのか、それともこれらの組み合わせが必要なのか
    • 会社の同僚もその一人
  • サードパーティーの装置やソフトウェアなら、そのベンダーに聞ける
  • 問い合わせベンダーがいない場合やいても連絡が取れない場合に対するアドバイスは 「もう一度マニュアルを読む」
    • 1のルールにしたがっていれば、マニュアルを一度読んでいるはずだから、問題への新たな視点を持った上でマニュアルをもう一度読んでみよう
      • 理解できなかったものが理解できるようになっているかもしれない
  • ツール、プログラミング言語、設計作法、デバッグに関しても、多くの情報源がある
    • 近所の書店やオンライン書店、関連のある雑誌やニュースレターやリリース、全てが情報源。専門家は周りに溢れている

プライドを捨てる

  • 助けを求めることは、無能の証ではない
    • バグを何とか修正したいという願望の表れ である
  • 新しい見解や専門知識や経験を取り入れ、より素早くバグを改修できる
    • これが援助を選んだあなたの賢明さを表す
  • 逆もまたしかりで、自分はおろかで、専門家が神であるうなどとは考えないこと
    • 専門家もミスを犯す。それが自分のミスであると思い込むと泥沼にはまる

例)B-treeに起きた問題の話

  • B-treeと呼ばれる大きなデータベースのインデックス構造を利用するプログラムを書いていたときのことである
  • コンピュータサイエンスに非常に詳しい同僚とコードを書いていた
  • ある時、自宅でソースコードを見直していると、彼のプログラムに理解できない部分があると気づいた
    • ある条件が揃うと、ソフトウェアがツリー構造を作り直すときにデータブロックをそっくり破壊しているようなのだ
    • 自分の考えがどこか間違えているかを突き止めようとして何時間も奮闘したが、自分の間違いは何も見つけられなかった。
  • しかたなく出社して同僚に「なぜここが正しく動作するのかがわからない」と聞いた
    • 同僚はすぐに「これはバグだね」と言った

持論ではなく症状を説明する

  • 新しい見解を持つ誰かに聞くのは自分の理論では結論が出せないからだ
  • それなのに持論を展開すると、相手の正しい考えが自分の持論に引きずりこんでしまう
    • それだけなく先入観は重要な事実を隠してしまうかもしれない
  • 断固たる態度で望むこと
    • 助けを求める時は下記を説明すること
      • 何が起きたのか
      • 何を見たか
      • どういう状況だったか
  • 腹痛のために訪れた病院で医者が聞きたがっているのは、あなたがインターネットで調べて骨髄癌であると確信していることではなく、どのような痛みかである
  • ゼネラルモーター社が欲しいのは、月曜日に組み立て二日酔いの組み立て工がフィニアピンをきつく締めすぎた話ではない。寒い朝にエンジンがかからないことである

確信する必要はない

  • 物事にはあいまいなグレーゾーンがある
  • なぜそうなのかよくわからない、こういう情報も提示する価値がある
  • あなたが理解していない、もしくは期待していないものが発見されたのだ
    • 物おじせず情報として提示しよう

あなたがしなければ問題は解決しない

本当に解決したかを確認する

  • 「その2: わざと失敗する」で失敗する手順と状況は確認済みなので、その手順と状況に従い再テストする
  • 修正が上手くいったと決めつけてはならない。修正後、同じ手順で再度テストすること

本当に自分が解決したかを確認する

  • 修正した部分を元に戻して問題が再発するか確認しよう
  • 修正すべき部分だけを修正し、問題が解決したことを確認した後、その修正された部分を失敗する状態に戻し、再度失敗するかを試す
    • こうしてはじめて問題が自分がした修正により解決したことが証明される
  • 理由として、デバッグの最中にテストの手順やソフトウェアまたはハードウェアの一部など正式な「修正」の一部でないものまで変更してしまうことがよくあるから
    • 変更による影響がなければ良いが、それによって偶然問題が解決される場合や、見えなくなる場合がある

例)セサミストーリーの話

  • スーパーグローバーとベティールーがコンピューターの電源を入れようと奮闘していた
  • スーパーグローバーが「飛び跳ねて、Wubba!っていうと電源が入るんじゃないかな」と言って「Wubba!Wubba!Wubba!」と言って大声をあげている間にベティールーが電源ボタンを見つけた
  • ベティールーが電源ボタンを押すとコンピュータの電源が入った
    • グローバーはベティールーが何をしたかも聞かずに、電源が入ったのを見て、自分がコンピュータの電源を入れる重要な手段を見つけたと確信した

自然になくなることはあり得ない

  • あなたが修正しない限り、問題は解決しない
    • バグがなくなったと信じたいのは誰しもが同じだ
    • ただ、また失敗する
  • それまで失敗していたシステムが、状況が何か変わったため失敗しなくなった(あるいは頻度が減った)としよう
    • この場合「その2: わざと失敗してみる」に戻って、たましか起きない失敗をもっと頻繁に再現させる方法を読み返そう
    • 色々修正してしまっているなら元の状態に戻して、対象のシナリオでテストしよう
    • 新しいソフトウェアで再現できないとしたら、問題は解決されたのかもしれない、両者の違いを調べて原因を突き止めよう
  • 時間がない時もある。その場合は顧客の手元の対象の問題が起きた場合に備えて、情報が記録されるようにしよう
    • こうすれば、もう一つの利点としてその情報で問題を解決できないとしても、少なくとも顧客には、あなたが真剣に問題を解決しようとしてるのがわかる

プロセスを修正する

  • 本書では予防やプロセスについて言及しないと書いたが、システムを修正することとシステムを誤動作させたプロセスを修正することの境界線を見極めることは難しい
  • 工場の床にオイルがこぼれたいたとする-オイルを拭けば良いが根本の問題は解決されていない
    • 金具の隙間から漏れ出しているから、金具を締めたが止まらない
    • 振動が激しい機械は4本ボルトで締めた方が良いところを2本で締めている
      • これが主原因
      • だが、これも違う。このままでは新しい機械を設置した場合にも同じ問題が発生する
  • 要件、設計、テスト段階において機械の振動を計算に入れるように、「設計プロセス」を修正しなければならない

まとめ

デバッグルール―9つの原則、54のヒントというデバッグに関する原則が書かれた書籍に書かれた「原則」についてまとめました。皆さんの何かのお役に立てれば嬉しいです。また、この書籍は分野を閉じないフラットな原則ついて書かれてますので勉強会や輪読会などで書籍をベースにチームにディスカッションしてみるのも良いかもなと思いました。

Discussion