오류시 줄 번호 표시


15

이맥스가 이해하지 못하는 오류가 발생한다고 가정 해보십시오. 또는 오류에 "변수의 변수 값이 void : modes"라는 메시지가 표시되지만 modes코드에 기호가 많이 표시 되므로 컨텍스트가 필요합니다. 어떤 코드가 오류를 일으키는 지 알 수 있도록 리스프 코드의 줄 번호를 언급하도록 Emacs를 구성 할 수 있습니까?

(setq stack-trace-on-error '(buffer-read-only))스택 추적을 얻으려고 가해한 코드를 시도하고 실행했습니다. 스택 추적도 없습니다.

또한 edebug-defun함수를 호출 하고 단계별로 시도 했습니다. 오류가 발생하는 함수에서 벗어날 때까지는 아닙니다.

(나는 elisp에 대한 일반적인 디버깅 기술을 개발할 때 현재 직면하고있는 특정 오류의 원인에 관심이 없습니다. 줄 번호, sexp 또는 스택 추적을 빛나게하는 방법에 대해 조언하십시오. 오류.)


이미 시도하지 않았습니까 nil debug-on-error? 도움이되지 않습니까?
Drew

아니. 그것은 아무것도하지 않는 것 같습니다. (로 설정 한 후 t오류 발생 기능 평가를 진행 한 후)
Jackson

아마도 다른 코드가 오류를 잡아서 오류 메시지를 인쇄하는 것입니다. 또한 debug-ignored-errors오류가 없는지 확인하십시오 . debug-on-signalnon-으로 설정 nil한 경우 다른 코드에서 오류를 처리 한 경우 다른 코드보다 먼저 오류를 얻을 수 있습니다.
wvxvw

나는 현재 비슷한 상황에 있으며이 질문을 읽고있었습니다. 스택 추적 오류가 궁금합니다. 이 변수는 Emacs 25.1에 문서화되어 있지 않습니다.
Matthias

답변:


15

이맥스 시설을 포함 디버깅의 좋은 금액 제공 M-x toggle-debug-on-error, M-x toggle-debug-on-quit(전송하여 사용할 수있는 신호에 디버그 USR2외부에서 이맥스에) debug-on-entry, (함수의)을 debug-on-message, (메시지의 특정의 정규 표현식 일치를 보는 경우) 그리고 마지막을 debug대안으로 자신을 로 기능을 계측합니다 C-u C-M-x.

모두 debugedebug검사 할 수있는 충분한 기능을 제공합니다 상태 는있는 거 관심에서 히트하는 코드를 평가할 때 이맥스의를 e식을 입력합니다.

그러나 edebug인스 트루먼 테이션 된 기능의 위치로 이동하여 볼 위치를 찾을 수있는 실마리를 제공하지만 (이미 정확히 무엇을 계측했는지 알고 있기 때문에 어리석은 일이지만) debug전혀하지 않습니다. debug버퍼를 평가할 때마다 오류와 관련된 포인트의 값을 방출 한다는 것을 발견 한 후 작은 해킹을 해냈습니다. 다시 말해 버퍼에이 정보를 사용하면 역 추적에 줄 번호를 줄 수 있습니다!

(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...? 그런 다음 무엇을 누르나요?
Jackson

이 코드를 사용하면에 의해 만들어진 역 추적에 줄 번호가 표시되며 debug, 잘못된 elisp 파일을 방문하여 M-x toggle-debug-on-errorand를 수행하여 확인할 M-x eval-buffer수 있으며 문제가있는 위치에 줄 번호가있는 역 추적이 팝업됩니다.
wasamasa

사용하지 않으면 작동 eval-buffer합니까? 예를 들어, 실패한 개인 명령을 실행하고 *Backtrace*버퍼 에서 디버거를 여는 키보드 바로 가기
키만 누르면됩니다

아뇨. 심볼의 함수 값 (목록 또는 바이트 컴파일 된 것일 수 있음)을 얻습니다.
wasamasa

4

어쩌면 2018 년이되었으므로 제 경우에는와 사마가 제안한 것처럼 디버깅 만 켜야했습니다 .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))))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.