diff options
Diffstat (limited to 'lisp/emacs-lisp/debug.el')
-rw-r--r-- | lisp/emacs-lisp/debug.el | 53 |
1 files changed, 40 insertions, 13 deletions
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index 593fab97275..e8a3015b8fb 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -27,6 +27,7 @@ ;;; Code: +(require 'cl-lib) (require 'button) (defgroup debugger nil @@ -144,9 +145,29 @@ You may call with no args, or you may pass nil as the first arg and any other args you like. In that case, the list of args after the first will be printed into the backtrace buffer." (interactive) - (if inhibit-redisplay - ;; Don't really try to enter debugger within an eval from redisplay. - debugger-value + (cond + (inhibit-redisplay + ;; Don't really try to enter debugger within an eval from redisplay. + debugger-value) + ((and (eq t (framep (selected-frame))) + (equal "initial_terminal" (terminal-name))) + ;; We're in the initial-frame (where `message' just outputs to stdout) so + ;; there's no tty or GUI frame to display the backtrace and interact with + ;; it: just dump a backtrace to stdout. + ;; This happens for example while handling an error in code from + ;; early-init.el with --debug-init. + (message "Error: %S" args) + (let ((print-escape-newlines t) + (print-escape-control-characters t) + (print-level 8) + (print-length 50) + (skip t)) ;Skip the first frame (i.e. the `debug' frame)! + (mapbacktrace (lambda (_evald func args _flags) + (if skip + (setq skip nil) + (message " %S" (cons func args)))) + 'debug))) + (t (unless noninteractive (message "Entering debugger...")) (let (debugger-value @@ -271,8 +292,14 @@ first will be printed into the backtrace buffer." (with-timeout-unsuspend debugger-with-timeout-suspend) (set-match-data debugger-outer-match-data))) (setq debug-on-next-call debugger-step-after-exit) - debugger-value))) + debugger-value)))) +(defun debugger--print (obj &optional stream) + (condition-case err + (funcall debugger-print-function obj stream) + (error + (message "Error in debug printer: %S" err) + (prin1 obj stream)))) (defun debugger-insert-backtrace (frames do-xrefs) "Format and insert the backtrace FRAMES at point. @@ -287,10 +314,10 @@ Make functions into cross-reference buttons if DO-XREFS is non-nil." (fun-pt (point))) (cond ((and evald (not debugger-stack-frame-as-list)) - (funcall debugger-print-function fun) - (if args (funcall debugger-print-function args) (princ "()"))) + (debugger--print fun) + (if args (debugger--print args) (princ "()"))) (t - (funcall debugger-print-function (cons fun args)) + (debugger--print (cons fun args)) (cl-incf fun-pt))) (when fun-file (make-text-button fun-pt (+ fun-pt (length (symbol-name fun))) @@ -336,7 +363,7 @@ That buffer should be current already." (insert "--returning value: ") (setq pos (point)) (setq debugger-value (nth 1 args)) - (funcall debugger-print-function debugger-value (current-buffer)) + (debugger--print debugger-value (current-buffer)) (setf (cl-getf (nth 3 (car frames)) :debug-on-exit) nil) (insert ?\n)) ;; Watchpoint triggered. @@ -361,7 +388,7 @@ That buffer should be current already." (`error (insert "--Lisp error: ") (setq pos (point)) - (funcall debugger-print-function (nth 1 args) (current-buffer)) + (debugger--print (nth 1 args) (current-buffer)) (insert ?\n)) ;; debug-on-call, when the next thing is an eval. (`t @@ -371,7 +398,7 @@ That buffer should be current already." (_ (insert ": ") (setq pos (point)) - (funcall debugger-print-function + (debugger--print (if (eq (car args) 'nil) (cdr args) args) (current-buffer)) @@ -417,7 +444,7 @@ will be used, such as in a debug on exit from a frame." "from an error" "at function entrance"))) (setq debugger-value val) (princ "Returning " t) - (prin1 debugger-value) + (debugger--print debugger-value) (save-excursion ;; Check to see if we've flagged some frame for debug-on-exit, in which ;; case we'll probably come back to the debugger soon. @@ -532,7 +559,7 @@ The environment used is the one when entering the activation frame at point." (debugger-env-macro (let ((val (backtrace-eval exp nframe base))) (prog1 - (prin1 val t) + (debugger--print val t) (let ((str (eval-expression-print-format val))) (if str (princ str t)))))))) @@ -554,7 +581,7 @@ The environment used is the one when entering the activation frame at point." (insert "\n ") (prin1 symbol (current-buffer)) (insert " = ") - (prin1 value (current-buffer)))))))) + (debugger--print value (current-buffer)))))))) (defun debugger--show-locals () "For the frame at point, insert locals and add text properties." |