Island Life

< らむ太とteapot | 『ミスト』のラスト >

2008/08/25

デバッガ

未来のいつか/hyoshiokの日記

アプリケーションの開発時にはデバッガーを使うのはあたりまえだろう。 そのデバッガーを使えなくて何がプログラマだ、くらいの事は思うのだけど、 世のプログラミング言語の入門書にデバッグの仕方もましてやデバッガーの使い方も載っていない。

おごちゃんの雑文 - デバッガなんて使わねーよ

この手の言い草はよく聞くけれど、私はデバッガはほとんど使わない。使ってもせいぜい、どうしても他に資料のないコアダンプを解析しなきゃいけない時だけで、普段はまるっきり使わない。そこにソースがあるなら、怪しい箇所を推理しつつprintfをつっこむ。なぜなら、私はプログラムを書く時に一番大切なものは、そういったツールを使う能力ではなくて、

思考力

であると思うからだ。それと共に、本当にクリティカルなバグには、デバッガは無力だからでもある。

ハンドアセンブルが長かったので、CP/Mが動くようになってDDTという デバッガを最初に使った時は感動したものだ。ハンドアセンブルではprintfデバッグ は簡単ではない。コードを挿入するとアドレスがずれてジャンプオフセットの計算を やりなおさないとならない。インストラクションの頭をRST命令で潰すのが定石だが 戻し忘れると面倒なことになる。それを自動でやってくれて、対話的にレジスタの 内容が見られて、ステップ実行まで出来るというのは衝撃だった。 そのあとコアダンプを見るのにadbを覚えて、gdbを使うようになったのはだいぶ 後だなあ。一時期はgdb+Emacsで何でもやってた。

でも今ではデバッガは滅多に使わなくなった。使うときもソースレベルで ブレークポイント設定しまくってさらにステップ実行…というのはほとんどやらない。 インタラクティブな逆アセンブラ/メモリダンパとしての使い方が多いかなあ。 GC絡みの怪しい挙動の解析とか、最適化のかかったコードの振る舞いを追ったりとか、要するに ビットに直接触る必要がある場合限定。 通常のデバッグはprintfスタブを使い、もう少し込み入った問題であれば その問題限定の検証ツールを組み込んだりしている。

ソフトウェアって多くの層の積み重ねで、 gdbみたいなスタイルのデバッガがぴたっとサポートできるのは そのうちの特定の層だけなんだよね。 仕事の主要部分がその層に集中していればデバッガは強力な武器になるけれど、 そうでないとあまり役に立たない。で、昔はよく使ってたのに何で使わなくなったのか なあ、と考えてみたのだけれど、 ソースレベルデバッガは出発点としているモデル:「メモリ、レジスタ、 CPUの状態変化とソースとを関連付けて追っかける」っていうのが崩れてきているって 背景があるんじゃないかなあと。

  • ランタイムの多層化。例えばVM上で走るコードのロジックのバグの場合、 gdbで実行を追ってもVMの同じところをぐるぐる回ってるだけでほとんど何も分からない。 watchpointや条件付きbreakpointも、粒度がソースレベルのロジックと 大きく異なっていて使いにくい。
  • コンパイルタイムの多層化。 メモリ読み書きのリオーダリングで、ソースの字面どおりに状態が遷移することは もはや当てに出来なくなっている。高水準言語における「関数」や「データ構造」は 抽象的な存在で、そのまま一連のインストラクション列やメモリの連続した領域へと マップされることはどんどん減っている。
  • 単一の状態遷移モデルの限界。 並列に走ってるスレッドがあれば、ソースの字面で見えている状態遷移とは 関係ないところで状態が変わっちゃう。
  • あと、コードを実行する主体がもはやCPUとは限らない(GPU等)、とかね。

ソフトウェアの一番下が状態機械である以上、その層を覗くツールとしての 現在のスタイルのデバッガの有用性は今後も残るだろうけど、 より一般的なツールとしての「デバッガ」に求められる異なるモデルっていうのが 必要になってるんじゃなかろうか。状態遷移よりは静的・動的な検証というものが 主役になるような気がする。言語の方にもそれに結びついた仕様が入って行くだろうし。 というか大きな企業はこのくらい既に考えてるだろうから最近流行りの「えんたーぷらいず」 言語の開発環境にはそういう支援が入ってたりしないんだろうか。

Visual Studioで作業してる若い人なんかを見ていると、実行環境からすぐにデバッガに 入ってがしがし編集してすぐ再実行して…ってサイクルを回してて、それはそれで 悪くないんだけれど、何て言うのかな、 「手元のデバッガが面倒を見られる層に無意識的に作業リソースを集中させてしまう」 というおそれがあるようにも思う。無意識に「デバッガで見られる状態機械の レイヤを越えた抽象化を避ける」というか。杞憂ならいいんだけど。

(追記2008/08/27 01:56:39 PDT: ちなみに、もちろんロートルLisperは 「実行環境からすぐにデバッガに入ってがしがし編集してすぐ再実行」なんだけどさ。 20年前から。でももっと良いやり方があるんじゃないかなあ、と思うのだ。)

Tag: Programming