Previous: Invoking the Debugger, Up: Debugger


17.1.8 デバッガの内部

本節では、デバッガが内部的に使用する関数や変数について述べます。

— Variable: debugger

この変数の値は、デバッガを起動するために呼び出す関数である。 その値は、可変個数の引数を取る関数(あるいは典型的には関数名)であること。 その関数でなんらかのデバッガに入ると仮定する。 この変数のデフォルト値はdebug

Lispが関数に渡す最初の引数で、呼び出した理由を表す。 引数の規約はdebugに記述してある。

— コマンド: backtrace

この関数は、現在活性なLisp関数呼び出しのトレースを表示する。 これは、debugがバッファ‘*Backtrace*’を 満たすために用いる関数である。 どの関数呼び出しが活性であるかを 判断するためにスタックを参照する必要があるためCで書いてある。 戻り値はつねにnil

以下の例では、Lisp式で明示的にbacktraceを呼び出す。 これにより、バックトレースをストリームstandard-outputに出力する。 ここではバッファ‘backtrace-output’に出力する。 バックトレースの各行は、1つの関数呼び出しを表す。 関数の引数値すべてが判ればそれらを行に表示する。 それらが計算途中であれば、その旨を行に表示する。 スペシャルフォームの引数は省略する。

          (with-output-to-temp-buffer "backtrace-output"
            (let ((var 1))
              (save-excursion
                (setq var (eval '(progn
                                   (1+ var)
                                   (list 'testing (backtrace))))))))
          
                nil
          
          ----------- Buffer: backtrace-output ------------
            backtrace()
            (list ...computing arguments...)
            (progn ...)
            eval((progn (1+ var) (list (quote testing) (backtrace))))
            (setq ...)
            (save-excursion ...)
            (let ...)
            (with-output-to-temp-buffer ...)
            eval-region(1973 2142 #<buffer *scratch*>)
            byte-code("...  for eval-print-last-sexp ...")
            eval-print-last-sexp(nil)
          * call-interactively(eval-print-last-sexp)
          ----------- Buffer: backtrace-output ------------

文字‘*’は、 抜け出るときにデバッガを起動する印が付いているフレームを表す。

— Variable: debug-on-next-call

この変数がnil以外であると、 つぎにevalapplyfuncallを呼び出すまえに デバッガを呼び出すことを指定する。 デバッガに入るとdebug-on-next-callnilに設定する。

デバッガのコマンドdは、この変数を設定することで動作する。

— Function: backtrace-debug level flag

この関数は、levelの深さのスタックフレームに 値flagに応じてフレームから抜け出るときのデバッガ呼び出しの印を付ける。 flagnil以外であると、 のちに当該フレームから抜けるとデバッガに入る。 非ローカルな脱出で当該フレームから抜けるときにもデバッガに入る。

この関数はデバッガのみが使用する。

— Variable: command-debug-status

この変数は、現在の対話的コマンドのデバッグ状況を記録する。 コマンドが対話的に呼び出されるたびに、 この変数はnilに束縛される。 デバッガはこの変数に設定することで、 同じコマンドの起動中にデバッガが将来起動された場合に備えて 情報を残すことができる。

デバッガにとっては、通常のグローバル変数ではなくこの変数を使う利点は、 以降のコマンド起動にデータが繰り越さないことである。

— Function: backtrace-frame frame-number

関数backtrace-frameは、Lispデバッガで使うことを意図している。 深さframe-numberのスタックフレームで進行中の計算に関する情報を返す。

当該フレームで引数の評価を完了していなければ(あるいはスペシャルフォーム)、 値は(nil function arg-forms...)

当該フレームで引数の評価を完了し関数を呼び出していれば、 値は(t function arg-values...)

戻り値において、functionは評価したリストのcarであるか、 マクロ呼び出しではlambda式である。 関数に引数&restがあれば、リストarg-valuesの残りで表現される。

frame-numberが範囲外であると、backtrace-framenilを返す。