誰もが陥るデバッグの悪夢

プログラミングをしている人なら、常日頃デバッグ作業で悩まされているはずです。 プログラマにとって、はじめの関門はデバッグ作業ができることだと思います。 バグの原因を突き止めて自分で対処できるのか、 または誰かに聞いてみないと解決できないバグなのかも自分で判断してデバッグ作業をしていかないといけません。

デバッグ作業にも効率的なやり方やノウハウは存在し、それを知らないと ずっとバグと闘い続けるはめになり開発効率が上がりません。 今回は新米プログラマ(入社して1年が過ぎたのでいつまで新米なのか怪しいですが)の私がデバッグをしていて周りから注意or教えてもらったことを大まかに3つにわけてみました。 デバッガ等のツールを正しく使えるようになる技術も必要ですが、それよりも どうバグと向き合うか の部分にフォーカスしていきます。

1. ログを見ろ

(エラー)ログをちゃんと眺めろという話です。

プログラムは思った通りに動かない。書いた通りに動く。

というプログラマの名言がありますが、同じように

起こった通りに出力されるのがログ

なので、実際に何がプログラムで起こったのかを突き止める場合には確認しなければならないところです。

最初はエラーが英語だったりして避けたくなりますが、どこでエラーが起こっているのかや、どんなSQLが発行されているのか、 どのページを表示しようとしているのか等もわかるので、ちゃんとログが読めるようになりたいですね。

あと、途中計算の結果をログに出してみると、どこまで想定している動きなのかも追いやすいです。

2. 事実と予想を一緒にするな

よくやってしまうのが、自分でエラーの原因を勝手に想像して、対処しようとしてしまうことです。 本当は違うところが原因なのに、最初に見当違いな予想をしてしまったため、他の人に質問するときにも、自分の想像と事実が混ざってしまっていて 、相手が混乱してしまう 場合もありえます。

悪い質問の例として

モデルのリファクタの影響(想像)で、計算が正しく表示されていない(事実)です。hogeメッソドが怪しいと思う(想像)のですが(以下略)。

このような質問をされると、優れたプログラマなら “なんでhogeメソッドだと思ったの?” と聞いてくれるかもしれませんが 、何も背景知識が無かったりしたら、質問された側は “じゃあ、そのhogeメソッドをみてみるか” となり、 もし違うメソッドやモデル以外のところに原因があった場合に、2人で余計なところに時間を使ってしまう事態が起こります。

デバッグ作業で大事なのは どこまでが事実(実際に起ったこと、検証したこと)で、どこまでが予想(自分が考えた部分なのか) を切り分けることです。 実際にホワイトボード等に、何が事実で、何が想像なのかを箇条書きでもいいので書き出してみると、より理解が深まりますし、 どういったアプローチ(次にどこを調べるか)の参考になります。

実際のプログラムの挙動 は事実ですし、 出力されたログ既に検証したこと も事実です。しかし、そこから導き出した”モデルが影響している”は想定なので、 そこはちゃんと切り分けて、もし質問するなら

計算が正しく表示されていなくて(事実)、ログに計算の経過を出力してみたらhogeメソッドの返す値が空になっている(事実)ので、 hogeメソッドが怪しいと思うのですが(想像)(以下略)。

と質問すれば、質問された側も事実がどこまでか理解しやすいので、たとえ見当違いな想像をしていたとしても、事実をもとに原因を考えてくれます。

3. エラーはローカルで再現し、面倒ならテストを先に書け

バグの中には 本番環境でしかエラーが発生しない という事態もよく起こります。こういう状態の時に、 いちいち本番環境やステージングの環境でやろうとすると、大事なデータを書き換えてしまったりしてリスクが高すぎますし、 修正する毎にデプロイをするため、デバッグ作業に時間がかかってしまいます。

本番環境でのみ発生するエラーをローカルで再現する ことをしてみましょう。 例えばAWSのS3(クラウドのファイルサーバー)にアップロード後に失敗するバグだったら、 自分でローカル用のS3を作ってみたり、アップロードが面倒ならコンソールで試してみるということもできます。 Railsでコンソールからファイルをアップロードする方法

自分の環境なので、どんどんいじっても他に影響も出ませんし、いろいろ検証しやすくなります。

あと、再現が面倒なときはテストを先に書いてしまう というのも効率的にデバッグができます。

以前、とあるアプリで5つ以上のデータを削除しようとするとエラーが発生するバグと闘っていた時に、 毎回ブラウザ上で5つデータを作って再現させていました。何回も検証しようとするとそのたびに5つデータを作らないといけないので非効率ですね。

そんな時には、先にテストを書いてしまえば、いちいちデータを作成しなくても大丈夫ですし、今後もテストとして残るので、そこが担保されるようになります。 TDD(テスト駆動開発)をしろとまで言いませんが、こういった バグに出会ったら先にテストを書いていくと自然とテストで保証されるところも増えていく ので一石二鳥ですね。

以上のことを守るだけでも

3つのノウハウを上げてみましたが、以上のことを守ってデバッグ作業をするだけでもデバッグにかかる時間は半分以上(当社比)削減できるかもしれません。 どのノウハウも結局は 急がば回れ が大事なのかなと思います。なるべくデバッグ作業時間を減らして、効率的に開発をしていきたいですね。