edebug ソースレベルデバッガ
¶Edebugはソースレベルデバッガです。通常、デバッグ対象のコードのソースを表示し、左側の矢印で現在どの行を実行しているかを示します。
関数の実行を1行ずつ辿ることも、実行が停止するブレークポイントに到達するまで素早く実行することもできます。
Edebugについては、The GNU Emacs Lisp Reference ManualのEdebugに記載されています。
以下は triangle-recursively のバグのある関数定義です。復習には カウンタの代わりに再帰を用いる
を参照してください。
(defun triangle-recursively-bugged (number)
"Return sum of numbers 1 through NUMBER inclusive.
Uses recursion."
(if (= number 1)
1
(+ number
(triangle-recursively-bugged
(1= number))))) ; Error here.
通常、この定義をインストールするには、関数の閉じ括弧の後にカーソルを置いて C-x C-e (eval-last-sexp) と入力するか、あるいは定義の中にカーソルを置いて C-M-x (eval-defun)
と入力します。(デフォルトでは、eval-defun コマンドは Emacs Lisp モードまたは
Lisp Interaction モードでのみ動作します。)
ただし、この関数定義を Edebug 用に準備するには、まず別のコマンドを使ってコードをインストルメントする必要があります。定義内またはその直後にカーソルを置き、次のように入力することで実行できます。
M-x edebug-defun RET
これにより、Emacsがまだロードされていない場合は自動的にEdebugをロードし、関数を適切にインストルメントします。
関数にインストゥルメントを追加した後、以下の式の後にカーソルを置き、C-x C-e (eval-last-sexp) と入力してください:
(triangle-recursively-bugged 3)
triangle-recursively-bugged
のソース位置までジャンプバックし、カーソルは関数の if
行目の先頭に配置されます。また、その行の左側に矢印が表示されます。この矢印は、関数が実行されている行を示しています。(以下の例では、矢印を
‘=>’
と表示していますが、ウィンドウシステムでは、ウィンドウの枠線に塗りつぶされた三角形として表示される場合があります。)
=>∗(if (= number 1)
例では、点の位置は‘∗’と表示されています(印刷本では五芒星で表示されます)。
ここで SPC を押すと、ポイントは次に実行される式へ移動し、行は次のようになります。
=>(if ∗(= number 1)
SPC
を押し続けると、ポイントが式から式へと移動します。同時に、式が値を返すたびに、その値がエコーエリアに表示されます。例えば、ポイントを number の先に移動させると、次のように表示されます。
Result: 3 (#o3, #x3, ?\C-c)
つまり、number の値は 3 であり、これは 8 進数の 3、16 進数の 3、そして
ASCII の Control-C にあたります(念のため付け加えておくと、アルファベットの 3
番目の文字です)。
エラーが発生している行に到達するまで、コードを読み進めてください。評価前のその行は、次のようになっています。
=> ∗(1= number))))) ; Error here.
再度 SPC を押すと、次のようなエラーメッセージが表示されます:
Symbol's function definition is void: 1=
これがバグです。
q を押して Edebug を終了します。
関数定義からインストルメンテーションを削除するには、インストルメンテーションを行わないコマンドで再評価すればよいだけです。例えば、定義の閉じ括弧の後にカーソルを置き、C-x C-e と入力します。
Edebugは、単に関数の実行に伴走するだけではありません。エラー発生時や指定した停止ポイントでのみ停止するように設定して自動で実行させたり、さまざまな式の値の変化を表示させたり、関数が何回呼び出されたかを確認したりすることも可能です。
Edebugについては、The GNU Emacs Lisp Reference ManualのEdebugに記載されています。