Endless Parentheses

Ramblings on productivity and technical subjects.

profile for Malabarba on Stack Exchange

Debugging Elisp Part 2: Advanced topics

Debugging Emacs-Lisp post series

Now that the previous post has leveled the playing field, we go into slightly more advanced debugging features. First we go deeper into Edebug navigation commands, and then we discuss when Edebug just won't do and explain the power of Emacs' built-in debugger.


Stepping through a function with n and finishing with c is just a subset of what Edebug can do. You can find the full list of commands on Edebug's manual page (under “Modes”, “Jumping”, and “Misc”), but here are the most useful ones:

Quit current execution, occasionally more useful than c, C and G.
Move point somewhere else, then hit h. Everything in between will be “skipped” (executed, but not displayed), and Edebug continues from there. Highly useful in very long functions.
Move out of the containing sexp. Tremendously useful in loops.
Go “inside” the function called at point. In other words, if point is immediately before a function call, i will instrument the function as if you had called C-u C-M-x on it and leave you inside this new Edebug session.

You also have the possibility of setting breakpoints, which I may go into later. But the keys above are enough to do what Edebug is best at, interactive investigation when you just don't know where the problem is.

debug and debug-on-entry

As shiny as it is, Edebug isn't exactly clean. Its instrumentation, though invisible, is not free of side-effects. It is not surprising then, that some bugs simply vanish when you Edebug them. Fortunately, that's not our only option. Emacs also offers the debug function, which is powerful and straightforward.

Just add (debug) anywhere inside a function. Next time the function is executed, Emacs will present you with a backtrace of the code state at that point. Alternatively, you invoke the command debug-on-entry and give it the name of a function.

Now, you might be forgiven to think there's nothing special about that. Any programming language worth its salt can spew out backtraces on demand. But that's not the end of it. Though this backtrace display might not be as pretty as Edebug, it's every bit as interactive.

There's a gif here (linked separately to avoid annoyance) which shows what you can do by just hitting d to step deeper into the structure, and then c to quickly get out. You can also jump around a bit with j, and evaluate expressions under an environment as if you were inside the function with e.

These are all much easier to use than to explain, so give it a shot yourself. Write (debug) inside a function of yours and start jumping around in there. You should get the hang of things quickly enough.

comments powered by Disqus