debug-on-entry ¶関数にエラーが発生すると、Emacsは自動的にデバッガを起動します。
ちなみに、すべてのバージョンのEmacsでデバッガを手動で起動できます。利点は、コードにバグがなくてもデバッガが動作することです。時にはコードにバグがないこともあるでしょう!
debug-on-entryを呼び出して関数を実行すると、デバッガに入ることができます。
タイプ:
M-x debug-on-entry RET triangle-bugged RET
それでは、以下を評価してください:
(triangle-bugged 5)
Emacsのすべてのバージョンでは、*Backtrace*バッファが作成され、triangle-bugged関数の評価を開始する旨が通知されます:
---------- Buffer: *Backtrace* ---------- Debugger entered--entering a function: * triangle-bugged(5) eval((triangle-bugged 5) nil)
elisp--eval-last-sexp(nil) #f(compiled-function () #<bytecode ...>)() handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ---------- Buffer: *Backtrace* ----------
*Backtrace* バッファに、d
と入力します。Emacs は triangle-bugged
の最初の式を評価し、バッファは次のようになります。
---------- Buffer: *Backtrace* ----------
Debugger entered--beginning evaluation of function call form:
* (let ((total 0)) (while (> number 0) (setq total ...)
(setq number ...)) total)
* triangle-bugged(5)
eval((triangle-bugged 5))
eval((triangle-bugged 5) nil) eval-expression((triangle-bugged 5) nil nil 127) funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127) call-interactively(eval-expression nil nil) command-execute(eval-expression) ---------- Buffer: *Backtrace* ----------
それでは、もう一度 d を8回、ゆっくりと入力してください。d を入力するたびに、Emacs は関数定義内の別の式を評価します。
最終的に、バッファは次のようになります。
---------- Buffer: *Backtrace* ----------
Debugger entered--beginning evaluation of function call form:
* (setq number (1= number))
* (while (> number 0) (setq total (+ total number))
(setq number (1= number)))
* (let ((total 0)) (while (> number 0) (setq total ...)
(setq number ...)) total)
* triangle-bugged(5)
eval((triangle-bugged 5) nil)
elisp--eval-last-sexp(nil) #f(compiled-function () #<bytecode ...>)() handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ---------- Buffer: *Backtrace* ----------
最後に、d をさらに2回入力すると、Emacs はエラーに到達し、*Backtrace* バッファの先頭2行は次のようになります。
---------- Buffer: *Backtrace* ---------- Debugger entered--Lisp error: (void-function 1=) * (1= number) ... ---------- Buffer: *Backtrace* ----------
dと入力することで、関数をステップ実行できました。
*Backtrace* バッファ内で q
と入力するとそのバッファを終了できます。これによりトレースは終了しますが、debug-on-entry はキャンセルされません。
debug-on-entryの効果を解除するには、次のようにcancel-debug-on-entryと関数名を呼び出します。
M-x cancel-debug-on-entry RET triangle-bugged RET
(Infoでこれを読んでいる場合は、今すぐ debug-on-entry
をキャンセルしてください。)