printfデバッグの問題を指摘する人は多いですが、printfデバッグよりも優れた手法を編み出す人はなかなかいません。
高機能なデバッガが使えない場合、printfデバッグしか選択肢がないわけではないと思います。
たとえば、システム内部の変数やオブジェクトを見たいなら、アドレス指定で決まった型としてアクセスする簡単なプログラムを書けば、動いたままでも内部状態を調べることができます。うまくすれば、フラグや内部データを書き換えて、実装を修正する前にロジックの検証もできるのです。
デバッグ用のそういう機能をある段階で組み込めばよいだけのことです。
その出力を内部のストレージやイーサで外に出すなら、「なんだ結局printfデバッグと変わらないじゃないか」という人も多いかもしれません。
ぜんぜん違います。
printfデバッグの場合、printfが書いてある箇所を通過しない場合、空振りになって、中がぜんぜん見えません。
簡易デバッグ機能は、ハードウェアで言うところの、ジャンパです。IOや内部回路にジャンパで論理を流し込むのです。あるいは状態を上書きします。
ジャンパはワニ口ならどこにでも設置できます。いつでもはずせます。
そうか、この状態のときにこの入力がONになれば、期待した動作を簡単に実現できるじゃないか
そういう『気付き』にも役立ちます。
ある大昔の本*1に、デバッグ用の機能が、全実装の8割を占めることもあるという記述がありました。
スタンドアロンで動くものほど、そういう傾向があると私は思います。PCのソフトなら、あとからデバッガでアタッチすることも、膨大なログを記録することも簡単にできます。しかしマッチ箱の中でできることと言えば、せいぜいシリアル端末を引き出して、ポチポチコマンドを打つことくらいなのです。
ポチポチコマンドを打てばデバッグができる仕組みを作りこんでおくことは、当たり前すぎて誰も本に書かない類の話なのだろうなと思ったりします。ですがそのために、デバッグ用コードが極端に少ない困った製品を作ってしまう人が後を絶ちません。
問題が発生してから、printfを仕込み、特定する。いくら手が早くても、コマンド叩けば答えが出るシステムに比べれば、数倍~数十倍の効率の差が出るのです。あまった手数で、いくらでも製品を改善することができ、コマンドはいずれ使われなくなります。それで良いのです。
なんでもかんでもICEでデバッグできるなら幸せになるでしょうが、ICEでステップ実行を繰り返すのが効率的なデバッグとはとても思えませんな。動作タイミングの問題もありますし。
コメント