Hiển thị số dòng bị lỗi


15

Nói rằng emacs ném một số lỗi mà tôi không hiểu. Hoặc có thể lỗi nói "Giá trị của biểu tượng là biến là void: mode", nhưng có nhiều lần xuất hiện của biểu tượng modestrong mã của tôi, vì vậy tôi cần một số ngữ cảnh. Emacs có thể được cấu hình để đề cập đến số dòng của mã lisp để tôi có thể biết mã nào gây ra lỗi không?

Tôi đã thử làm (setq stack-trace-on-error '(buffer-read-only))và chạy mã liên tục trong một nỗ lực để có được một dấu vết ngăn xếp. Không có dấu vết ngăn xếp.

Tôi cũng đã thử gọi edebug-defunchức năng của mình và bước qua nó. Mãi đến khi tôi bước ra khỏi chức năng thì lỗi mới bị ném.

(Tôi thực sự không quan tâm đến nguyên nhân của lỗi cụ thể mà tôi hiện đang gặp phải khi tôi đang phát triển các kỹ năng sửa lỗi chung cho elisp. Vui lòng tư vấn về cách tôi có thể phát sáng số dòng, hoặc sexp hoặc dấu vết ngăn xếp từ một lỗi.)


Bạn đã thử không- nil debug-on-error? Điều đó có giúp ích gì không?
vẽ

Không. Điều đó dường như không làm gì cả. (Sau khi tôi cài đặt thành trồi chuyển sang chức năng ném lỗi.)
Jackson

Có lẽ những gì xảy ra là một số mã khác bắt lỗi và chỉ in thông báo lỗi. Cũng kiểm tra xem debug-ignored-errorskhông liệt kê bất kỳ lỗi nào. Nếu bạn đặt debug-on-signalthành không nil, và đó là trường hợp mã khác xử lý lỗi, bạn sẽ có thể nhận được lỗi trước khi mã khác đã xảy ra.
wvxvw

Tôi hiện đang ở trong một tình huống tương tự và đang đọc câu hỏi này. Tôi đang tự hỏi về stack-track-on-error. Biến này không được ghi trong Emacs 25.1.
Matthias

Câu trả lời:


15

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 USR2cho 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, debugchí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 debugedebugcung 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 evà nhập một biểu thức.

Tuy nhiên, trong khi edebugnhả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), debughoà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.


Cảm ơn sự giúp đỡ của bạn, nhưng tôi vẫn không hiểu làm thế nào để có được số dòng. M-x debug...? Sau đó, tôi nhấn gì?
Jackson

Với mã này, bạn sẽ thấy một số dòng trong backtraces được tạo bởi debug, bạn có thể kiểm tra bằng cách truy cập tệp elisp bị lỗi, thực hiện M-x toggle-debug-on-errorM-x eval-buffersau đó một backtrace với số dòng ở vị trí có vấn đề sẽ xuất hiện.
wasamasa

Nó sẽ hoạt động nếu bạn không sử dụng eval-buffer? Ví dụ: nếu bạn chỉ nhấn một phím tắt chạy lệnh riêng bị lỗi và mở trình gỡ lỗi trong *Backtrace*bộ đệm ..
Håkon Hægland

Không, nó sẽ không. Bạn nhận được giá trị hàm của ký hiệu (có thể là danh sách hoặc thứ gì đó được biên dịch byte) và đó là khá nhiều.
wasamasa

4

Có thể vì bây giờ là 2018, nhưng trong trường hợp của tôi, tôi chỉ phải bật gỡ lỗi như wasamasa đã đề xuất: Mx toggle-debug-on-error

Sau này, Mx eval-buffer trên tệp Elisp bị lỗi của tôi đã đưa ra ngữ cảnh bằng cách cung cấp vị trí của lỗi, như thế này: Debugger entered--Lisp error: (invalid-read-syntax ")") eval-buffer() ; Reading at buffer position 523 [....]

Mx goto-char nhảy đến vị trí lỗi: M-x goto-char 523


Đẹp tìm thấy! Có vẻ như điều này đã được thêm vào năm 2017, trở lại khi họ làm lại chức năng đó để làm việc trên một danh sách các mục backtrace.
wasamasa

1

Tôi đã mở rộng câu trả lời của wasamasa để bao gồm thông tin bổ sung:

(save-excursion
  (let ((tem eval-buffer-list))
    (while (and tem
                (re-search-forward "^  eval-\\(buffer\\|region\\)(" nil t))
      (beginning-of-line)
      (insert (apply 'format "Error at line %d, column %d (point %d) in %s\n"
                     (with-current-buffer (car tem)
                       (list (line-number-at-pos (point))
                             (current-column)
                             (point)
                             (buffer-name)))))
      (pop tem))))
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.