68

Normally the easiest way to debug is using printf. What can I do to debug emacs-lisp? How can I print something to emacs editor from elisp? Or is there any way to debug elisp code?

For example, how can I check if the following code is run in .emacs file?

(load "auctex.el" nil t t)
AdrieanKhisbe
  • 3,899
  • 8
  • 37
  • 45
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • This [manual](http://www.gnu.org/software/emacs/manual/html_node/elisp/Debugging.html) may be help to you. – Yantao Xie Jan 14 '14 at 02:30
  • 2
    Allow me to recommend [this blog post](http://endlessparentheses.com/debugging-emacs-lisp-part-1-earn-your-independence.html) on Edebug. – Malabarba Jan 02 '16 at 20:50

5 Answers5

93

The debugger (edebug) is pretty straight forward to use. Go to the definition of the function, and type M-x edebug-defun. The next time it is called, you'll be able to step through the code as with every other debugger. Type ? for the list of keybindings, or check out the documentation for edebug.

Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • 3
    It's worth noting the most important keybindings while debugging: `SPC` to proceed to the next step, `i` for stepping in, `o` for stepping out, `q` for quitting. – kotchwane Nov 06 '21 at 13:59
36

There are two debuggers in GNU Emacs:

  • edebug -- explained in another post here
  • debug

I use debug. These are common entry points (ways to use it):

  • M-x debug-on-entry followed by a function you want to enter using the debugger.

  • M-x toggle-debug-on-error -- Enter the debugger when when an error is raised.

  • M-x toggle-debug-on-quit -- Enter the debugger when the user hits C-g.
  • Place explicit calls to function debug at particular places (breakpoints) in your code, to enter the debugger at those places:
    (debug)

You step through the debugger using d, or c to skip over the details of a particular evaluation.

Drew
  • 29,895
  • 7
  • 74
  • 104
  • 4
    how to check the values of different variables? I am able to debug through a function but don't know how to check value for different variables. – Alok Mar 30 '12 at 02:14
  • 5
    @Alok: You can place the cursor over a variable and press `RET`, or press `e` and evaluate the variable you're interested in. – danlei Apr 03 '13 at 15:49
  • 3
    You can evaluate any sexp in the original (calling) context. You can also provide a sexp to evaluate to function `debug`, so it shows you the value when the debugger is opened. E.g., `(debug nil (current-buffer))`. – Drew Nov 18 '13 at 02:42
  • thanks, I came here looking to undo what happens when you `pkill -SIGUSR2 -i emacs` from a shell (it toggles debug-on-quit). That's another way to start `debug` if emacs has hung in some function somewhere and you just want to break the loop, but `C-g` doesn't work – mike Jul 16 '18 at 22:41
  • @Drew is there a way to 'step-over'? I mean to evaluate the current expression without the debugger increasing depth into any of the subexpressions? `d` is more of a 'step-into', and most debuggers have both. Similarly, a 'step-out' would be nice. – nate May 23 '21 at 11:56
  • 1
    @nate, [Elisp docs](https://www.gnu.org/software/emacs/manual/html_mono/elisp.html#Debugger-Commands) list available commands. In particular, see `j`, `u` and `e` keybindings. `Edebug` seems to provide more fine-grained possibility to control the flow if `debug` is not enough. – Y. E. Jun 07 '21 at 14:54
  • 1
    @nate: That's what `c` does. I called that "skip over the details". `c` stands for "continue", presumably. It evaluates the given step completely, without making you step through every intermediate step to accomplish that. – Drew Jun 07 '21 at 16:31
  • @Y.E. Ah, ok. Thanks for the suggestions. I realized what i wanted here. If i put a (debug) at the top of a function, i can 'd' to eval the next expr (the first expr of the function). It is autoflagged to break on exit with a star. Then i hit c and it runs and i see its return value. Then i hit 'd' one more time to debug the next function in the list. It is kind of a 'd-c-d-c-d-...' combo to do the "step-over" that i intended. – nate Jun 10 '21 at 13:16
23

This is useful for printing values

(message "Hello (%s)" foo)

but doesn't work so well for data structures. For that, use

(prin1 list-foo)

or (prin1-to-string) to embed it in a (message).

jplindstrom
  • 974
  • 1
  • 10
  • 12
8

The easiest way to debug may be to run your code interactively. You can do that in a lisp buffer by placing your point after the expression and running C-x C-e (eval-last-sexp).

Alternatively:

(message "hello world")

C-h f message to find out more about the built in message function. If you generate lots of messages, you may want to customize the variable message-log-max to a larger value.

Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
Dave Bacher
  • 15,652
  • 3
  • 63
  • 86
  • This is the equivalent of the `printf` approach, and it is sometimes a very good one. – Drew Aug 21 '11 at 02:09
3

To answer your questions one by one:

  • print something: there's a million ways. (message "Hello") puts the string in the echo area; (insert "hello") puts the string into the current buffer at point ...
  • how can I check if the following code is run: I'd just replace "auctex.el" with (say) "frotzumotzulous" (i.e., any string at all, as long as it doesn't name a real file) and then see if you get an error message. If you get no error, then clearly that code isn't being run.
offby1
  • 6,767
  • 30
  • 45