Emacs cung cấp một số lượng tốt của gỡ lỗi tiện ích bao gồm M-x toggle-debug-on-error
, M-x toggle-debug-on-quit
, debug trên tín hiệu (có thể được sử dụng bằng cách gửi USR2
cho Emacs từ bên ngoài), debug-on-entry
(một chức năng), debug-on-message
(khi nhìn thấy một trận đấu cụ thể regexp của thông điệp) và cuối cùng, debug
chính nó như là sự thay thế để thiết bị một chức năng với C-u C-M-x
.
Cả hai debug
và edebug
cung cấp đủ chức năng để kiểm tra trạng thái của Emacs khi đánh giá mã mà bạn quan tâm, nhấn e
và nhập một biểu thức.
Tuy nhiên, trong khi edebug
nhảy đến vị trí trong chức năng của thiết bị và do đó cung cấp cho bạn một đầu mối để tìm (điều này thật ngớ ngẩn vì bạn đã biết chính xác những gì bạn đã sử dụng), debug
hoàn toàn không làm điều này. Tôi đã thực hiện một bản hack nhỏ hơn sau khi phát hiện ra rằng bất cứ khi nào debug
đánh giá bộ đệm, nó sẽ phát ra giá trị của điểm liên quan đến lỗi; nói cách khác, sử dụng thông tin này trên bộ đệm có thể cung cấp cho bạn một số dòng trong backtrace!
(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)))
Với câu hỏi ban đầu trong tiêu đề nên được trả lời. Đối với vấn đề của bạn với việc nhận được một backtrace ở nơi đầu tiên, tôi không có ý tưởng hữu ích.
nil
debug-on-error
? Điều đó có giúp ích gì không?