diff options
Diffstat (limited to 'lisp/emacs-lisp/debug-early.el')
| -rw-r--r-- | lisp/emacs-lisp/debug-early.el | 83 |
1 files changed, 58 insertions, 25 deletions
diff --git a/lisp/emacs-lisp/debug-early.el b/lisp/emacs-lisp/debug-early.el index 2e56d5ab321..bb41d55f02d 100644 --- a/lisp/emacs-lisp/debug-early.el +++ b/lisp/emacs-lisp/debug-early.el | |||
| @@ -27,14 +27,17 @@ | |||
| 27 | ;; This file dumps a backtrace on stderr when an error is thrown. It | 27 | ;; This file dumps a backtrace on stderr when an error is thrown. It |
| 28 | ;; has no dependencies on any Lisp libraries and is thus used for | 28 | ;; has no dependencies on any Lisp libraries and is thus used for |
| 29 | ;; generating backtraces for bugs in the early parts of bootstrapping. | 29 | ;; generating backtraces for bugs in the early parts of bootstrapping. |
| 30 | ;; It is also always used in batch model. It was introduced in Emacs | 30 | ;; It is also always used in batch mode. It was introduced in Emacs |
| 31 | ;; 29, before which there was no backtrace available during early | 31 | ;; 29, before which there was no backtrace available during early |
| 32 | ;; bootstrap. | 32 | ;; bootstrap. |
| 33 | 33 | ||
| 34 | ;;; Code: | 34 | ;;; Code: |
| 35 | 35 | ||
| 36 | ;; For bootstrap reasons, we cannot use any macros here since they're | ||
| 37 | ;; not defined yet. | ||
| 38 | |||
| 36 | (defalias 'debug-early-backtrace | 39 | (defalias 'debug-early-backtrace |
| 37 | #'(lambda () | 40 | #'(lambda (&optional base) |
| 38 | "Print a trace of Lisp function calls currently active. | 41 | "Print a trace of Lisp function calls currently active. |
| 39 | The output stream used is the value of `standard-output'. | 42 | The output stream used is the value of `standard-output'. |
| 40 | 43 | ||
| @@ -51,26 +54,39 @@ of the build process." | |||
| 51 | (require 'cl-print) | 54 | (require 'cl-print) |
| 52 | (error nil))) | 55 | (error nil))) |
| 53 | #'cl-prin1 | 56 | #'cl-prin1 |
| 54 | #'prin1))) | 57 | #'prin1)) |
| 58 | (first t)) | ||
| 55 | (mapbacktrace | 59 | (mapbacktrace |
| 56 | #'(lambda (evald func args _flags) | 60 | #'(lambda (evald func args _flags) |
| 57 | (let ((args args)) | 61 | (if first |
| 58 | (if evald | 62 | ;; The first is the debug-early entry point itself. |
| 63 | (setq first nil) | ||
| 64 | (let ((args args)) | ||
| 65 | (if evald | ||
| 66 | (progn | ||
| 67 | (princ " ") | ||
| 68 | (funcall prin1 func) | ||
| 69 | (princ "(")) | ||
| 59 | (progn | 70 | (progn |
| 60 | (princ " ") | 71 | (princ " (") |
| 61 | (funcall prin1 func) | 72 | (setq args (cons func args)))) |
| 62 | (princ "(")) | 73 | (if args |
| 63 | (progn | 74 | (while (progn |
| 64 | (princ " (") | 75 | (funcall prin1 (car args)) |
| 65 | (setq args (cons func args)))) | 76 | (setq args (cdr args))) |
| 66 | (if args | 77 | (princ " "))) |
| 67 | (while (progn | 78 | (princ ")\n")))) |
| 68 | (funcall prin1 (car args)) | 79 | base)))) |
| 69 | (setq args (cdr args))) | 80 | |
| 70 | (princ " "))) | 81 | (defalias 'debug--early |
| 71 | (princ ")\n"))))))) | 82 | #'(lambda (error base) |
| 72 | 83 | (princ "\nError: ") | |
| 73 | (defalias 'debug-early | 84 | (prin1 (car error)) ; The error symbol. |
| 85 | (princ " ") | ||
| 86 | (prin1 (cdr error)) ; The error data. | ||
| 87 | (debug-early-backtrace base))) | ||
| 88 | |||
| 89 | (defalias 'debug-early ;Called from C. | ||
| 74 | #'(lambda (&rest args) | 90 | #'(lambda (&rest args) |
| 75 | "Print an error message with a backtrace of active Lisp function calls. | 91 | "Print an error message with a backtrace of active Lisp function calls. |
| 76 | The output stream used is the value of `standard-output'. | 92 | The output stream used is the value of `standard-output'. |
| @@ -88,14 +104,31 @@ support the latter, except in batch mode which always uses | |||
| 88 | 104 | ||
| 89 | \(In versions of Emacs prior to Emacs 29, no backtrace was | 105 | \(In versions of Emacs prior to Emacs 29, no backtrace was |
| 90 | available before `debug' was usable.)" | 106 | available before `debug' was usable.)" |
| 91 | (princ "\nError: ") | 107 | (debug--early (car (cdr args)) #'debug-early))) ; The error object. |
| 92 | (prin1 (car (car (cdr args)))) ; The error symbol. | ||
| 93 | (princ " ") | ||
| 94 | (prin1 (cdr (car (cdr args)))) ; The error data. | ||
| 95 | (debug-early-backtrace))) | ||
| 96 | 108 | ||
| 97 | (defalias 'debug-early--handler ;Called from C. | 109 | (defalias 'debug-early--handler ;Called from C. |
| 98 | #'(lambda (err) | 110 | #'(lambda (err) |
| 99 | (if backtrace-on-error-noninteractive (debug-early 'error err)))) | 111 | (if backtrace-on-error-noninteractive |
| 112 | (debug--early err #'debug-early--handler)))) | ||
| 113 | |||
| 114 | (defalias 'debug-early--muted ;Called from C. | ||
| 115 | #'(lambda (err) | ||
| 116 | (save-current-buffer | ||
| 117 | (set-buffer (get-buffer-create "*Redisplay-trace*")) | ||
| 118 | (goto-char (point-max)) | ||
| 119 | (if (bobp) nil | ||
| 120 | (let ((separator "\n\n\n\n")) | ||
| 121 | (save-excursion | ||
| 122 | ;; The C code tested `backtrace_yet', instead we | ||
| 123 | ;; keep a max of 10 backtraces. | ||
| 124 | (if (search-backward separator nil t 10) | ||
| 125 | (delete-region (point-min) (match-end 0)))) | ||
| 126 | (insert separator))) | ||
| 127 | (insert "-- Caught at " (current-time-string) "\n") | ||
| 128 | (let ((standard-output (current-buffer))) | ||
| 129 | (debug--early err #'debug-early--muted)) | ||
| 130 | (setq delayed-warnings-list | ||
| 131 | (cons '(error "Error in a redisplay Lisp hook. See buffer *Redisplay-trace*") | ||
| 132 | delayed-warnings-list))))) | ||
| 100 | 133 | ||
| 101 | ;;; debug-early.el ends here. | 134 | ;;; debug-early.el ends here. |