最適なデバッグは可能性を潰していく事

minekoaさんのエントリを読んでいて、

「そうそう、コンパイラがこんなこと言うときは実際にはあんな事が起きてるんですよ」みたいな知識データベース。そしてコンパイラが検出出来ないタイプのバグについても、現象に「あれ?、どこかでみたぞ、これ」となる。そういう「良くあるパターン」の蓄積はデバッグのスピードアップに大きく貢献します。
正しい。けれど、それはそれとして。
根本的な問題として、「問題の切り分け」というのが出来ていないからデバッグ出来ないというのが、「デバッグができないこと」なのではないかと思います。

デバッグという基礎素養 - みねこあ

「最適なデバッグはまず適切で高い可能性から潰していく事、最後に残った事が真実」
だなあと思いました。
デバッグをするときに経験があると
「そうそう、こういうときはこれだよね」
というのが解ります。
ハングアップが一番簡単で、
スタックを見ても良いし、
とんでもないアドレスに飛んでいるなら、
呼び出し元アドレス(大抵レジスタにあります)を表示するだけでも
手がかりになります。


ただ、こういうことは小手先のワザであって、
本質ややはりminekoaさんのいうように「問題の切り分けができるか?」
なんだと思います。
たまにバグがでたとき「それはありえない」という人もいますが、
バグに「ありえない」はない。「ありえない」と考えても、つぶせる可能性は潰すべき、なんてことを思います。
SDKとかライブラリのバグだったよ、なんてことがよくあるわけだしね。


例えば、ゲームなどでも
「テクスチャがでない」という問題があった場合、

「テクスチャが確保できてない」
「テクスチャが指定されていない」
「テクスチャのファイルが壊れている」
「その他のメモリ破壊の影響」
「モデル側のテクスチャを指し示すアドレスが壊れている/おかしい」
「そもそもテクスチャのVRAMアロケータのバグでテクスチャが見えてない」
「テクスチャがでてないのではなく、モデルがでてない」
えとせとらえとせとら、と様々な原因があります。
以上は、現実的にありえた事象です。

基本的にバグたりうる原因は無限大にあるので、
これらを一つずつ潰したところで収束するとは限りません。
例えば「デバッガが物理的に壊れている」なんてのもあります。(ありました)
ただ、殆どのケースはこれらを効率よく潰していくことで正答にたどり着きます。

結局は、デバッグは様々な要因を突き詰めて潰していき、
最後に残った物が真実です。

そういう意味では、「マインスイーパ」というのは凄く適切なたとえで、
勘や経験が働く人ほど、素早く的確に白い領域を広げていくことができるので、
非常に簡単に素早くデバッグが終わります。
ただ、時には「思いこみ」が支配していることがあるので
他人の助言が救いの手になったりもします。

ただし、どんなにうまい人でも、
マインスイーパが三次元で展開されていたり、
ヒントの数字が嘘だったりすると途端に手こずります。
ということは、やはり設計をシンプルに見通しよく、正しく保つことはデバッグの期間や時間、機会を減少させ、
効率よい開発を行える事に直結します。

パターンを覚えるタイプのデバッグ方は即効性はあるのだけれど、本来の意味での「デバッグ力」ではないんじゃないかな
だってデバッグ力は「学習する力」だもん(from マインドストーム

デバッグという基礎素養 - みねこあ

自分もパターンを憶えるより実際に被害に遭い、
理解を深め、
勘をやしなう方がいいかなーと思います。
C++の罠なんかも顕著で、浅いところを触っていると出会わないのですが、
経験によって「あああああああああああああああああ」と叫ぶことでより堅牢になるものですし。orz...
「理解」こそが最大の武器だと思います。なぜこうなるのか、ならばこういったこともあるのではないか、という手探りがデバッグ力?を養うのではないかと。

そういえば、
ハードウェアブレークポイントを知らない人もいます。
CPUによってはちゃんとICEを内蔵しているので、
ハードウェアブレークポイントをはることもできます。
固有のアドレスに読み書きされた場合に検出できるので、
非常に便利です。
ダンプを見ても、解ることがあります。
デバッガによってはダンプが変更されたら、赤く表示してくれたりするんですのにねえ、と思うこともあります。
これら知識も必要なのかな、とも。


ただ、
テストのコストやプログラムの設計の技術も結局はデバッグの期間を短縮させ、
品質の高いものに仕上がることに直結するのですよねえ、と思った次第です。


そして、マインドストームはポチっとしましたよ。:-)