Emacs proporciona una buena cantidad de recursos de depuración que incluyen M-x toggle-debug-on-error, M-x toggle-debug-on-quitdepurar la señal (que se puede usar enviando USR2a Emacs desde el exterior), debug-on-entry(de una función), debug-on-message(cuando se ve una coincidencia específica de expresión regular de un mensaje) y, finalmente, debugcomo alternativa para instrumentar una función con C-u C-M-x.
Ambos debugy edebugofrecen suficiente funcionalidad para inspeccionar el estado de Emacs al evaluar el código que le interesa, presione ee ingrese una expresión.
Sin embargo, mientras edebugsalta al lugar en la función instrumentada y, por lo tanto, le da una pista sobre dónde mirar (lo cual es un poco tonto ya que ya sabe exactamente qué ha instrumentado), debugno hace esto en absoluto. Realicé un truco más pequeño después de descubrir que cada vez que debugevalúa un búfer, emite el valor del punto asociado con el error; en otras palabras, ¡usar esta información en el búfer puede darle un número de línea en la traza inversa!
(with-eval-after-load 'debug
(defun debugger-setup-buffer (debugger-args)
"Initialize the `*Backtrace*' buffer for entry to the debugger.
That buffer should be current already."
(setq buffer-read-only nil)
(erase-buffer)
(set-buffer-multibyte t) ;Why was it nil ? -stef
(setq buffer-undo-list t)
(let ((standard-output (current-buffer))
(print-escape-newlines t)
(print-level 8)
(print-length 50))
(backtrace))
(goto-char (point-min))
(delete-region (point)
(progn
(search-forward "\n debug(")
(forward-line (if (eq (car debugger-args) 'debug)
2 ; Remove implement-debug-on-entry frame.
1))
(point)))
(insert "Debugger entered")
;; lambda is for debug-on-call when a function call is next.
;; debug is for debug-on-entry function called.
(pcase (car debugger-args)
((or `lambda `debug)
(insert "--entering a function:\n"))
;; Exiting a function.
(`exit
(insert "--returning value: ")
(setq debugger-value (nth 1 debugger-args))
(prin1 debugger-value (current-buffer))
(insert ?\n)
(delete-char 1)
(insert ? )
(beginning-of-line))
;; Debugger entered for an error.
(`error
(insert "--Lisp error: ")
(prin1 (nth 1 debugger-args) (current-buffer))
(insert ?\n))
;; debug-on-call, when the next thing is an eval.
(`t
(insert "--beginning evaluation of function call form:\n"))
;; User calls debug directly.
(_
(insert ": ")
(prin1 (if (eq (car debugger-args) 'nil)
(cdr debugger-args) debugger-args)
(current-buffer))
(insert ?\n)))
;; After any frame that uses eval-buffer,
;; insert a line that states the buffer position it's reading at.
(save-excursion
(let ((tem eval-buffer-list))
(while (and tem
(re-search-forward "^ eval-\\(buffer\\|region\\)(" nil t))
(beginning-of-line)
(insert (format "Error at line %d in %s: "
(with-current-buffer (car tem)
(line-number-at-pos (point)))
(with-current-buffer (car tem)
(buffer-name))))
(pop tem))))
(debugger-make-xrefs)))
Con esto, la pregunta original en el título debe ser respondida. En cuanto a su problema para obtener un seguimiento en primer lugar, no tengo ideas útiles.
nildebug-on-error? ¿Eso no ayuda?