デバッグついて（不具合の特定について）

# はじめに
皆さんが見るもの、聞くのも嫌なワードの「不具合」が起きた時に、どうやってデバッグしていくか？
というところの、不具合を特定するところまでの、対応の仕方をダラダラと書いてみたいと思います。
不具合を特定してからの、いわゆる「不具合の解消」については記載しません。
Webベースで書いていきますので、その辺はあしからず。

確立された、手法ではなく、あくまで私独自の考え方や、手法です。
書いていくことは基本的なことではありますが
いざ調査していくことになった時に、私も含め
当たり前のことができていなかったりすることもあると思いますので
ご参考程度にと考えていただければと思います。

## まずデバッグする際に1番大事なことは何か？
### 「不具合を再現すること！！」
何じゃそれ？当たり前やん！
と思うかもしれませんが、これが1番大事なことで
これができれば不具合の９０％は解消できたと考えても良いでしょう。

逆にできなければ、地獄です。。
これについては後述します。

### では、どうやって再現するのか？
時と場合によりますが（そんなの当たりまだろ、、）
私が取るであろう行動パターンを書いていきます。

###1. お客さんに再現したパターンをヒアリングする。

なるべく詳細に聞くことが求められます。
どうった操作をした。
いつ（いつ頃から発生したか）
誰が（どのユーザ、他の人は起きていないか）
どういった環境　どのサーバ、ブラウザ（バージョン）、ネットワーク環境は
どういったデータか？（可能ならば入力、使用したデータをもらう）

再現するための情報を必死に聞き出します。

###2. ヒアリングした材料を元に、不具合を再現
ヒアリングした、情報を元に、開発環境などで
なるべく不具合が発生した状況に、近づけ、再現を試みます。
再現すれば、オケで、再現しなければ

できなければ、、
###3. はい、地獄が待ってます。。
ありとあらゆる、再現パターンを、想像（まさに創造）しながら
試すことになります。
ヒアリングした情報も材料になります。
再現シナリオを考えなければいけないので、かなりの想像力が必要になります。

もし許可が得れるなら、データベースをもらって（もちろんお客様の同意が必要）
開発環境でリストアして、という強硬手段に出ななければいけないかもしれません。

お客様の環境で、試させてもらうとか、お客様に再現してもらうということを
しなければいけないかもしれません。

ここには行きたくないですね。。


では一旦不具合を再現できたとして、、
## どうやって不具合の原因を特定していくのか？
多分、皆さんが興味があるのがここですね。

まず、私のベースの考え方ですが、不具合は１本の線のどこかにあると考えています。

Webであれば下記のような流れがあります。
(1)お客様のブラウザ → (2)お客様のPC → (3)お客様のネットワーク
→　(4)サーバのNW →　(5)サーバ　→　(6)サーバのプログラム　→　(7)DB　→　(8)サーバのプログラム
→　(9)サーバのNW →　(10)お客様のNW →　(11)お客様のPC　→　(12)お客様のブラウザ

ごちゃごちゃ書いているようで、簡略して書いてますが、この中のどこかに原因があり
それを探していく旅となります。

#### 1. どこに原因があるかは、最初の内は、あまり特定しすぎてはダメです。

実は言いたいことは、ほぼこれだけといっても過言ではないのですが、、

例えばお客様のNWに原因があるのに、プログラムに原因を探しても永遠に見つかりません。
昔のよくあるある話ですが、
「おたくのページが見えないんですが？」
と言われて、
「yahooは見えますか？」
「あ、見えません。あ、LANが抜けてました。」
てな、初心者あるあるのミスによって、不具合？とい疑いをかけられることもあるのです。
最初の段階では、初歩的なことも最初のうちは見逃してはいけません。
お客様にヒアリングしていく中で、ここに原因がないとわかった箇所は白にしてもいいですが
白でなければ、黒である可能性を潰してはいけません。

よくあるのが、こういう現象が起きているなら、ここに原因があるはずだ！という勘や読みをベースに
ピンポイントで、不具合の調査をしていくことです。
ここか？違う、ここか？違う。ということを続けていくとかなり時間を取られてしまいます。
このやり方は、最初の１、２回はこれでもいいですが、外れたら
理性を取り戻して、もう少し効率的に、不具合の原因を探してかなければなりません。

## 2. まずは大まかに不具合の特定の絞り込みしていきます。
例えば、下記に原因があるかどうか？
「(1)お客様のブラウザ → (2)お客様のPC → (3)お客様のネットワーク」
お客様にヒアリングするしかないです。
ヒアリングして、ここに原因がなければ、これ以降の部分になります。

次は、ここですね。
「→　(4)サーバのNW」
ネットワークチームに確認する必要があります。
何か、ネットワークのトラブルがなかったか？負荷がなかったか？

まぁ、ここまでは白であることが多いですね。
ただ、白であることが多いという理由だけで、原因がある箇所を見過ごしてしまうと
その後に別の場所を調査しても、永遠に不具合を見つけれることはないので、油断してはいけません。

例えば、「(1)お客様のブラウザ → (2)お客様のPC 」に原因がある時には
ブラウザ特有の原因であったり、ウイルス対策ソフトが原因だったりする
ことが起因する可能性があることを忘れてはなりません。

「 →　(5)サーバ」
ここは何が言いたいかというと、サーバにリクエストが来ているのか？
ということを見逃しがちで、リクエストが来てないのに、受け側のプログラムを見ても仕方がないということです。
Ajaxなどであれば、画面には見えないので、ブラウザの開発ツールを使ったり、
サーバのログを見たりして、リクエストが来ているかどうかをチェックしなければなりません。
もし来ていないのならば、受け側のプロブラムではなく、ブラウザのHTMLやjavascriptがどうなっているかを
見なければいけないので、１つ前のプログラムに原因がある可能性が高くなります。


「(6)サーバのプログラム　→　(7)DB　→　(8)サーバのプログラム」
ようやく来ました。ここに原因があることは多いですね。
とはいえ、何度も言ってますが、盲目にここに原因があると理由もなしに、特定してはなりません。
周りに原因がない、白であることを確定させてから、ここの調査を行わなければなりません。

ここまできたら、もうあとは犯人を追い詰めるかのように、じりじりと追い込んでいきます。
あまりやり方に差はないですが、私は下記の３つのどれかを使い分けて不具合を特定していきます。
1. 半分ずつに割って、原因を特定する
2. ローラー作戦で特定する
3. 原因と思う箇所を、ピンポイントで特定する
4. プログラムを変えたことが起因しないかという観点から、不具合を特定する

#####1. 半分ずつに割って、原因を特定する
例えば、プログラムの上半分で止まっているか、下半分で止まっているかなどを
特定し、上に原因があれば、さらに半分にしてということを繰り返していきます。
原因の場所を、狭めて、狭めて、という繰り返しを行い、不具合を特定します。
今まで説明してきたことの延長になりますね。

#####2. ローラー作戦で特定する
いわゆる全調べですね。
ちなみにローラー作戦とは、犯人を特定するときに、警官などを総動員して、
ありとあらゆる場所を探して、犯人をあぶり出すことです。
あまり効率的ではないですが、、
ログを一定の割合で埋め込む、とかトレースデバッグで追っていきながら、１連の動きを
すべて通して見て、どこに不具合があるかを特定します。

######3. 原因と思う箇所を、ピンポイントで特定する
これは読みや勘を必要としますが、ある程度場所が絞り込めていたら
経験のあるエンジニアであれば、最後はこれで特定することができます。
勘と言っても、過去の類似の経験から、ビビビとくるもので、完全な山勘ではありません。
新人のエンジニアにはできない芸ですね。

#####4. プログラムを変えたことが起因しないかという観点から、不具合を特定する
プログラムを変更したことにより、違う場所のデグレを引き起こしてしまう。
特にお客様が、バージョンアップを機に不具合が発生した、とか言われている時は
ここに原因があることが多いです。
前のバージョンで不具合が発生しないけど、新しいバージョンで不具合が発生することを
確認できたら、そこの差分に原因がある可能性が高いです。
バージョンアップによって、プログラムが変更されたところを重点的に調査し
そこに原因がないかを調べます。
ただ、ここに原因があることが１００％確定したわけではありません。
ある動作によって、特定のデータが作られたことによる原因かもしれませんので
そういったことも考慮しながらの調査になります。


##最後に
それでも不具合の原因が何かわからないことはよくあります。
何が何だかわからないのL状態ですね。
ただ現状の開発もあるので、いつまでも不具合の調査に時間を使うわけにもいきません。
これにはお客様の理解が必要ですが、、
次につなげるために、次に発生した時に原因を特定できる、もしくはできやすい状況を作りましょう。
#####疑わしい箇所に、ログを詳細に埋め込むなどが、常套手段ですね。
できれば次に不具合が発生した時に、特定できることが望ましいですが
何回かに段階的に分けてやる必要があるかもしれません。
原因の特定に向けて、前進していくことが大事です。

いかがでしたでしょうか。
特に理論などないのですが、不具合の特定に対して大事なことを纏めると下記のようになります。
####1. まずは不具合を再現すること
####2. 最初は場所を特定せず、大まかに不具合の場所を狭める
####3. 最後はケースバイケースで、細かく場所を特定する。

##1番ダメなことは、ここの範囲に不具合があるという、盲目な視点です。
そこ以外に原因がある可能性を忘れずに、視野を広げて見てください。
これができなければ、永遠に不具合を特定ができない可能性もあるので気をつけてください。
逆にこの盲目な視点から脱却することができれば、どんなやり方にせよ
不具合の特定には辿り着けるはずです。

長々と大したことないことを書きました。
ここまで読んでいただいた方、ありがとうございます。