DATE : 2008/02/11 (Mon)
「デバッガの理論と実装」(Jonathan B.Rosenberg著、吉川邦夫訳、アスキー、1998)を読みました。デバッガのアルゴリズムや、各種OSのデバッグ API について述べられた本です。
デバッガには常々お世話になっており、その動作が気になっていたのですが、実際にはかなり細々としたことを行っていました。
例えば、ブレークポイントを設定して、デバッギ(デバッガによってデバッグされるプログラムのこと)の動作を途中で止めるには、ブレークポイントの対象となっているメモリ内の命令を、CPU のブレークポイント命令に置き換えることで行っています。処理の再開は、置き換えた命令を元の命令に戻すことで行います。シングルステップ実行も似たようなもので、命令を実行する前に、次の命令をブレークポイント命令に置き換えます。そしてブレークポイントで処理が停止したら、置き換えた部分を元の命令に戻し、次の命令をブレークポイント命令に置き換え……という処理を繰り返します。
つまり、デバッガはデバッギのあるメモリを様々に操作することで、デバッグを実現していると言えます。
ところが、これではデバッギの実行は、通常の実行時とメモリの状態が異なることになります。本書でも「デバッガの諸原則」(p.26~)で述べられていますが、計測によって実際の状態が乱れてしまう「ハイゼンベルク効果」が現れてきます。つまり、通常の実行時には現れていたバグがデバッグ時には消えたり、その逆もありうるのです。この影響の度合は、デバッグ API を提供する OS によって異なりますが、デバッガが存在する限り、ゼロにはできません。同時に実行されるプロセスが1つ増えることで、命令の実行順序やイベントの送信順序も変化するためです。そのため、バグによってはデバッガでも捕らえきれないものが存在します。
これはとても勉強になった部分でした。デバッガというと、動作が神秘的でできないことはないような気がしていました。しかし、デバッガのアルゴリズムを知ることで、その限界も知ることができたような気がします。
(;^ω^)これからも、デバッガとは良いお付き合いをしていきたいと思います。