错误显示行号


15

假设emacs引发了一些我不理解的错误。也许错误提示“符号的变量值无效:模式”,但是modes代码中出现了很多符号,因此我需要一些上下文。可以将Emacs配置为提及lisp代码的行号,以便我知道是什么代码导致了错误吗?

我尝试这样做(setq stack-trace-on-error '(buffer-read-only))并运行了永久代码,以获取堆栈跟踪。也没有堆栈跟踪。

我也尝试过调用edebug-defun我的函数并逐步执行它。直到我退出该函数后,才会引发错误。

(对于开发elisp的一般调试技能,我对当前遇到的特定错误的原因确实不那么感兴趣。请提供有关如何从行号,sexp或堆栈跟踪中获取信息的建议)错误。)


您是否已经尝试过非nil debug-on-error?那没有帮助吗?
画了

不。那似乎什么也没做。(在将其设置为t,然后评估一个引发错误的函数之后。)
杰克逊(Jackson

可能发生的情况是其他一些代码捕获了该错误并仅显示错误消息。还要检查debug-ignored-errors并没有列出任何错误。如果设置debug-on-signal为non- nil,并且其他代码处理了该错误,那么您将能够先于其他代码得到错误。
wvxvw 2015年

我目前处于类似情况,正在阅读此问题。我想知道关于错误的堆栈跟踪。Emacs 25.1中未记录此变量。
Matthias

Answers:


15

Emacs提供了大量调试工具,包括M-x toggle-debug-on-error,,M-x toggle-debug-on-quit信号调试(可以USR2从外部发送到Emacs 来使用),debug-on-entry(功能的)调试,debug-on-message(当看到消息的特定正则表达式匹配时),以及最终将debug其自身替代用C-u C-M-x

双方debugedebug提供足够的功能来检查状态评估代码,您有兴趣,命中时的Emacs e和输入表达式。

但是,虽然edebug跳转到已检测功能中的位置并因此为您提供了寻找位置的线索(这很愚蠢,因为您已经确切地了解了所检测的内容),debug却根本不这样做。在发现每当debug评估一个缓冲区时,它都会发出与错误关联的point的值,因此,我进行了一个较小的讨论。换句话说,在缓冲区上使用此信息可以为您提供回溯中的行号!

(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)))

这样就可以回答标题中的原始问题。至于您首先遇到回溯的问题,我没有有用的想法。


感谢您的帮助,但我仍然不知道如何获取行号。M-x debug...?那我要按什么
杰克逊

使用此代码,您将在的回溯中看到一个行号debug,可以通过访问一个错误的elisp文件M-x toggle-debug-on-error并执行和来进行检查M-x eval-buffer,然后应弹出一个在问题位置处具有行号的回溯。
wasamasa

如果您不使用,可以使用eval-buffer吗?例如,如果你只是按运行失败,并在打开调试的私人命令的快捷键*Backtrace*缓冲区..
哈康Hægland

不,不会。您可以获得符号的功能值(可以是列表的形式,也可以是字节编译的形式),仅此而已。
wasamasa

4

也许是因为现在是2018年,但就我而言,我只需要像wasamasa建议的那样打开调试:Mx toggle-debug-on-error

之后,错误的Elisp文件上的Mx eval-buffer通过提供错误的位置来提供上下文,如下所示: Debugger entered--Lisp error: (invalid-read-syntax ")") eval-buffer() ; Reading at buffer position 523 [....]

Mx goto-char跳至错误位置: M-x goto-char 523


好发现!看来这是在2017年添加的,当时他们重新使用该功能以处理回溯项列表。
wasamasa

1

我扩展了wasamasa的答案,以包括其他信息:

(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))))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.