夜寝ていたら突然本番障害だと起こされて異世界に召還されたときに役に立つこと

# 概要
本番障害が発生して突然よびだされたこととか、皆さんないでしょうか？
私は最近はないですが、昔は結構ありました。

そんなわけで、本記事では、不具合が発生した際に、どのようにデバッグしていくのが良いか？などについて、ざっくしと私の経験をもとに書いていこうかと思います。

なお、本記事は特定のプログラミング言語や、システムに依存しない、デバッグの考え方的なものとなっています。
そのうち、気が向いたら特定の言語、状況などに応じた記事も書いていこうかなと思っていたり、いなかったりｗ

# プレゼン資料
ちなみに、本記事は、会社で勉強会やるからなんか話してくれといわれた時に、さらっと行ったプレゼンの内容を再構築したものとなっていたりします。

SlideShareにその時の資料をアップしてあるので、もしよろしければ、そちらのほうがわかりやすいかも？

[勉強会のときのプレゼン資料](https://www.slideshare.net/kouziroutenkubashi/ss-73040008)

# デバッグとは
**プログラムを作ると、必ずバグが生まれます！**

世の中でプログラムが作られるということは、必ず対となるデバッグの作業が発生することに他なりません。

良くバグが発生すると謝罪する姿などを見受けますが、

**プログラムにバグがあることは、至極当然こことだということを忘れてはいけません！！**

例えば、テストをすることによって、バグを減らすことはできても、完全にバグを除去するテストを計画･実施することは、様々な要因により、現実的ではありません。
（※テストについては話が脱線しすぎるのでここでは割愛）

なので。。。

**プログラマなら、自分が作った部分のバグであっても、ドン！！と胸を張ってデバッグを行おう！！**

・・・もちろん、バグを減らす努力はしようね・・・

# デバッグへのアプローチ 概念図

それでは、実際にどのようにデバッグしていくのかを見ていきましょう。

![q_01_01.png](https://qiita-image-store.s3.amazonaws.com/0/81768/1d2aee14-85f6-4609-e8dc-04bb8c418ff1.png)

## 状況のヒアリング

バグを制すにはまず、バグの報告を受けた（または発見した）、時点で得られる限りの情報を、可能な限り収集することが、その後の解決に大きな影響を及ぼします。
特に第三者からのバグ報告の場合は、できる限り具体的な内容をヒアリングするように心がけてください。

- × ： アプリが突然落ちた
- ○ ： ある画面を表示し、50秒ほど経過した際に、突然エラーダイアログが表示（スクショ有）され、その後OKボタンを押下するとアプリが終了した。

また、人は、思い込みや、記憶の曖昧さ、間違った知識、経験などによって、**稀に良く**正確ではない情報を報告することがあります。
そのため、ログがある場合はログを、画面で問題が発生した場合はスクショなど、誤りようの無い、正確な情報を得ることが非常に重要です！！

デバッグをする際は、

**正確な情報以外はあくまで参考とし、正確な情報以外は常に疑え！！！**

## ボトムアップとトップダウン
バグの状況を把握したら、実際にデバッグの開始です！
バグを調査する際は、大きく分けて以下の2つの観点からバグを追い詰めていくことが基本となります。

- **発生状況からの特定（トップダウン）**
仕様や、環境、状況などから、問題を特定していく

- **発生原因からの特定（ボトムアップ）**
エラーコードや、発生したソースの行数などから問題を特定していく

## 発生状況からの特定（トップダウン）

- **既知問題の確認**
発生した内容と同様、または類似の事象が無いかを、周りの有識者から聞いたり、ググったりして調べる


- **モジュール差分確認**
既存では発生しないが、新規モジュールにしたら発生した場合などは、既存と新規のモジュール差分を確認する。

- **仕様確認**
発生した内容がシステム的なものではない場合、仕様の矛盾や仕様と実装の齟齬などを確認する
ミドルウェア、言語などの仕様面から、不具合の事象が発生しうるかなどを調査していく

## 発生原因からの特定（ボトムアップ）

- **エラー情報確認**
エラーログ、エラーの種類、エラーIDなどから、発生している根本原因を確認する。
ただし、問題の根本原因はスナップショットとなることが多いため、そこに至る過程が真の原因であることなどについては疑う必要がある

- **問題の切り分け**
発生したエラー情報、モジュールの内容、モジュールの最小化などを併せて、問題事象に関連する内容と、それ以外を切り分け、確信に近づいていく。
（例えばDBは関係ないとかそういったこと）
また、外部要因の切り分けは特に重要！
（裏を返すと、ありとあらゆる外部要因を考慮することを忘れないこと！！）

- **仮説の構築と立証**
発生したエラー情報や、ヒアリングした内容、調査事項などを加味して、バグが発生する条件について仮説を立て、本当にそうなるかを立証することによって、問題の特定を行う

## 補助的な作業
デバッグをしていく上で、下記2つについては、非常に重要な役割を持ちます。特に、難解な不具合（例えばOSの不具合など）であればあるほど、効力を発揮していきます。

**やらない人をよく見かけるので、重要だということを強く提唱したい！！**

急がば回れです！！！なのです！！

- **最小化モデルの作成**
問題事象が発生する、最小のモデル（モジュール）を作成する。
問題を切り分けたり、確認する範囲が少なくなっていくので非常に有効！
またメーカーのサポートを受けるには必須なことも多い。

- **再現性の確保**
バグの再現手順と、再現率を上げていく。
バグは再現率が１００％にできたら、もう勝利目前です！！
色々とチャレンジして、再現手順と、再現率を確保しましょう！

## 定期的に
デバッグをしていると、どうしても視野が狭くなり、問題解決から遠ざかってしまうことなどが多々あります。定期的に以下の３つを行いましょう！

- **状況の整理**
深呼吸をして、コカコーラゼロを飲みながら、状況の整理をしよう。
特に複数の人でデバッグをしている際は情報の共有を行いましょう！
また、一人の場合は、だれかに調査内容などを報告、説明するのは非常に有用です。人に説明すると、論理だてた説明が必要なため、矛盾点などに気づくことが多いです。
説明する人がいない場合は、iPhoneのSiriや、人形に向かって説明しましょう！！

- **事実の確認**
調査していると、事実を見失うことが良くあります。（特にググって関係ない情報に惑わされたり、嘘の情報を掴まされた時）。
そうならないためにも、本当に発生している事実と、仮説を正しく整理して認識しましょう

- **第三者との協力**
知見のある人、そうでない人も含め、第三者に協力を仰ぐのも非常に有効です。
一人の知識にはどうしても限界があります。皆で協力して問題を解決しましょう！

## 戦士には休息も必要です
適度に休憩を取りましょう。
デバッグは非常に頭を使う作業です。疲れた頭では問題解決することはできません！！！

また、人間の脳は休憩するとき、考えていたものが整理されるという機能を持っています。
そのため、実は休憩する方が問題解決に近づくこともあるのです。

どうしても、緊急の障害対応の場合は、がむしゃらに対応を行うこともあるかと思いますが、実は疲弊するほど、解決から遠のいていることも多々あるのです！！
そんな時こそ、

**勇気を持って寝てみよう！！！**

## 神はあなたを見捨てない (神という名の直感)
**努力している人を神は見捨てません！！！**

全ての行動は必ず解決へ向かっています！！！

**あきらめてはなりません！**
**神はあなたを決して見捨てないのです！！！**