Elisp Debugging Notes

<2023-02-20 Mon>

1. "edebug" vs "debug"

There is a difference between edebug and plain-old debug. See:

TL;DR: Edebug is probably what you want.

2. Basics

To instrument a function for debugging, evaluate it via C-u C-M-x. When you're done, remove instrumentation by re-evaluateing it with the usual C-M-x

3. Edebug commands

C-u C-M-x launch debugger
b set breakpoint
u unset breakpoint
g continue until next breakpoint
w Show current position
e eval someting
M-: Evaluate something (in local scope)

What edebug seems to lack is an easy way to inspect variables. Here's some code I found which attempts to address this, although it doesn't work well for complex local variables.

(use-package edebug
  ;; A quicker alternative to E for inspecting local variables in Edebug
  ;; Not extensively tested
  (define-key edebug-mode-map "A" 'nate/elisp-add-to-watch)
  (defun nate/elisp-add-to-watch (&optional region-start region-end)
    "Add the current variable to the *EDebug* window"
    (interactive "r")
    (let ((statement
           (if (and region-start region-end (use-region-p))
               (buffer-substring region-start region-end)
             (symbol-name (elisp--current-symbol)))))
      ;; open eval buffer
      ;; jump to the end of it and add a newline
      (goto-char (point-max))
      ;; insert the variable
      (insert statement)
      ;; update the list
      ;; jump back to where we were

I generally don't use this as M-: is good enough.

4. Backtraces

Here's a tip for dealing with backtraces that look like this:


Figure 1: unreadable backtrace

You can tap + to pretty-print:


Figure 2: Formatted backtrace

Keywords: emacs

Modified: 2023-09-30 20:15:05 EDT

Emacs 29.1.50 (Org mode 9.6.1)