はじめに
バグ調査のやり方が人それぞれ違うなと感じている
私がやってることの共有と、他の知見を集めたいという目的
設計/実装に求められる能力と、バグの原因特定に求められる能力は、別物である
バグ調査は推理ゲーム
例えば、印刷してもプリンターが動かない場合
- 同じ端末から別のプリンターで印刷してみる
- 別の端末から同じプリンターで印刷してみる
- プリンタのプロパティからテスト印刷してみる
まずはこのように原因特定を始める
- いきなりプリンタドライバーを再インストールしてみる
みたいな闇雲な始め方は望ましくない
強制終了する場合
以下は基本
- Stack trace
- BreakpointとDebug実行
- printf的ログ出力を細かく仕込む
以下も使えると良い
- Crashlytics
- Build Scan
- 例外にBreakpointを貼る
参考
Xcodeでデバッグ実行中にクラッシュした時に捗るブレークポイント設定
Gradle Build Scanを使ってみる
エラーメッセージが出る場合
以下は基本
- そのメッセージで全文検索
- ユーザーに聞く
- ユーザーは何をしていたか
- ユーザーは何を期待していたか
- 実際に何が起きたか
以下も使えると良い
- Layout Inspector
動作が遅い、重い、固まる
以下は基本
- ANRから推測する
- メモリリークを調査する
以下も使えると良い
参考: Android PからのSystem TracingとPerfettoを使ってパフォーマンスを確認しよう
参考: iOS — Identifying Memory Leaks using the Xcode Memory Graph Debugger
共通していること
- 現象を再現させる
- 実装を理解する
- 人のコードを読む癖をつけておく
- デバッガーの呼び出し履歴を使う
- 原因を推理する
- ケアレスミス(Null、範囲外Index、定数の間違い、演算子の間違い(=/==))
- 考慮してない入力値
- 意図しない型キャスト(小数→整数)
- 複数スレッド非同期実行
- サーバーレスポンス異常
参考: How to fix bugs, step by step - Software Engineering Tips
共通していること
- わからなければ二分探索しよう!
- 一部をばっさりコメントアウトして実行
- めんどくさければモックを書こう!
- 同じレスポンスをサーバーで用意するのはとっても非効率
- 実体←→モックの差し替えが容易かどうかはアーキテクチャー次第
- 上手くいってる修正方法を探そう!
- GitHubはオープンソースの集まりで、トラブルシューティングの宝庫
- 英文に慣れよう!
- トラブルシューティングは大体英文
- 言語の壁が、探せる範囲の壁を作る
- 知らない言語でもそこに唯一の解決策があるかもしれないので、Translatorを使おう(Chromeアドオンおすすめ)
- とはいえ、怪しいサイトには注意
- Forumの回答で"same problem"はNGワード扱い
まとめ
バグとの戦いは開発言語の知識よりも、頭の中に引き出しがどれくらいあるかの方が大事だと思っています。
ちなみに僕はF1とかのモタスポが好きですが、F1でも車が予想外の挙動を示した時に、引き出しが多くて対応できるドライバー(どんな車でもそこそこ速いタイプ)と、そうじゃないドライバー(車を完璧に仕上げることが必須のタイプ)がいると思って見てます。どちらを目指すかは人それぞれ自由ですが、個人的には前者がいいな〜と思います。
さいごに
若手エンジニア向けの発表でしたが、私も今のお仕事は2年目でまだまだ無知な若手エンジニアなので、足りない観点があればぜひ教えてください!