Emacs Lispのソースコードデバッガ edebug を使う

edebugとはソースコードデバッガ

edebugとは、Emacs Lispのソースコードデバッガです。 これを使うと、Emacs Lispがどのように実行されているのかをステップバイステップで見ることができます。

前の記事で紹介した trace-function では不十分な場合は、edebugで本格的にデバッグします。 edebugは状態がころころ変化するので、実際に手を動かしてみましょう。

edebugを有効・無効にする

C-u C-M-xで関数をedebug対象にする

edebugは基本的には関数単位でedebug対象にします。 特定の関数をedebug対象にするのは簡単です。 通常、関数フォームを評価する、すなわち関数を定義するには、defun中あるいは、defunの直後でC-M-xを使います。 それに対し、関数フォームをedebug対象にするには数引数をつけ、C-u C-M-xを使います。 以下の関数にC-u C-M-xを使うと、エコーエリアに「edebug: fact」とでます。


(defun fact (x)
"階乗"
(if (zerop x)
1
(* x (fact (1- x)))))
C-M-xあるいはC-c C-cで関数を再定義・edebugを無効にする

edebugを使わない場合は、その関数を再定義します。 C-M-xはLispとして関数定義し、C-c C-cは関数定義をバイトコンパイルします。 もうデバッグが終わったならばC-c C-cでバイトコンパイルしてしまいましょう。

もちろん当該ファイルをロードしてもかまいません。

edebugを使う

SPCでステップ実行する

当該関数をedebug対象にしたら、今度はその関数を呼び出します。 関数定義の下に


;; (fact 2)

と書いてC-x C-eするか、 M-: (fact 2) を実行するかで呼び出せます。

すると、実行結果がでてくるのではなく、fact関数の最初の位置でカーソルが止まります。 これはedebugが有効になっている状態です。 モードラインに「*Debugging*」と出てきているので明らかです。

この状態では、いろいろなキーを受け付けます。

スペースを押すと、次の括弧までステップ実行します。 カーソル位置の値をエコーエリアに表示します。 何度も押すことで実行に様子がはっきりとわかります。

hでカーソル位置まで実行する

スペースだけだと、長い関数のデバッグが大変です。 そこでhを使います。 hはカーソル位置まで一気に実行するコマンドです。 edebugを有効にしたら、実行してほしいところまでカーソル位置を持って行って、そこでhを押すという使い方です。

ソースコード中に(edebug)を入れておくとブレークポイントを設定する

しかし、いちいちカーソルを移動するのは面倒です。 そこでソースコード中に (edebug) を書き加えることで、ブレークポイントを設定してしまいます。

edebugセッションでもブレークポイントが設定できます。 しかし、関数を書き換えた後でedebugを再び有効にするとブレークポイント情報が消えてしまうという欠点があります。 そのため、多くの場合はソースコードに直接ブレークポイントを設定する方が嬉しいのです。 ifやwhenと組み合わせると、条件つきブレークポイントも設定できます。

(edebug)自体がひとつの式なので、入れる場所によったら、prognと組み合わせる必要があります。


(defun fact (x)
"階乗"
(if (zerop x)
1
(* x (progn (edebug) (fact (1- x))))))
gで次のブレークポイントまで実行

ブレークポイントを設定したら、gを押すと、一気にブレークポイントまで実行します。 ブレークポイントまで一気に進んで、その後はスペースで綿密に調査をするのが普通です。

qでedebugから抜ける

edebugでの実行をやめるには、qを押します。 実行中の関数は実行をとりやめます。

iでカーソル位置の関数をedebug対象にする

edebug対象関数を追い掛けていて、その下の関数も追いかけたいことがあります。 それには、わざわざ当該関数定義に飛ばなくても、iを使えばいいです。


(defun hoge (x)
(1+ (fact x)))
;; (hoge 2)

hoge関数をedebug対象にし、(factの(の部分にカーソルが来たときにiを押すと、factもedebug対象になります。

eで式を評価する

しばしば、デバッグ中には変数や式の値を知りたいことがあります。 このときはeで式を評価してください。

Eで評価リストを使い、実行が進むにつれて自動更新される

eでは、式を評価するのは一度きりです。 実行するたびに評価してほしい場合は評価リストを使います。 評価リストは、edebug実行のたびに評価する式を複数書くところです。

評価リストを使うにはまずEを押します。 すると*edebug*バッファが出てきます。 そこで式を書いてC-c C-uで登録します。 *edebug*バッファは以下のようになります。


x
2
;-----------------------------------------------------------------------------------

複数の式を登録する場合は、末尾に追記してC-c C-uです。

評価リストに登録したら、C-x oあるいはC-c C-wでedebug対象関数にもどります。 あとは通常のedebugの操作をしてください。 実行が進むたびに評価リストが更新するのは、とても便利なものです。 しかも、関数定義を変更しても評価リストは保持されます。 評価リストは、とても便利ですよ〜