From: Stefan Monnier Date: Sat, 20 Apr 2024 15:23:58 +0000 (-0400) Subject: (backtrace--print-func-and-args): Fix (part of) bug#70436 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=d57f6d72d1e16b4fa148f1db1d55f13f958aae2c;p=emacs.git (backtrace--print-func-and-args): Fix (part of) bug#70436 The source of bug#70436 is that we print a value into the buffer and then we generate its print representation a second time to get its length to find the bounds of the thing we just printed. Not only it's wasteful, but it risks bugs because the two "prints" can be inconsistent with each other. This is not a complete fix because in the non EVALD case we still use that same broken way. * lisp/emacs-lisp/backtrace.el (backtrace--print-func-and-args): Don't re-print things just to get their length. (backtrace--print-to-string): Skip a temp-buffer indirection. (cherry picked from commit 0536b96011d24797d16d97a59a62f633a3d30472) --- diff --git a/lisp/emacs-lisp/backtrace.el b/lisp/emacs-lisp/backtrace.el index e47e2662afa..120972d6cd8 100644 --- a/lisp/emacs-lisp/backtrace.el +++ b/lisp/emacs-lisp/backtrace.el @@ -678,12 +678,10 @@ characters with appropriate settings of `print-level' and (defun backtrace--print-to-string (sexp &optional limit) ;; This is for use by callers who wrap the call with ;; backtrace--with-output-variables. - (setq limit (or limit backtrace-line-length)) - (with-temp-buffer - (insert (cl-print-to-string-with-limit #'backtrace--print sexp limit)) - ;; Add a unique backtrace-form property. - (put-text-property (point-min) (point) 'backtrace-form (gensym)) - (buffer-string))) + (propertize (cl-print-to-string-with-limit #'backtrace--print sexp + (or limit backtrace-line-length)) + ;; Add a unique backtrace-form property. + 'backtrace-form (gensym))) (defun backtrace-print-frame (frame view) "Insert a backtrace FRAME at point formatted according to VIEW. @@ -722,9 +720,10 @@ Format it according to VIEW." (def (find-function-advised-original fun)) (fun-file (or (symbol-file fun 'defun) (and (subrp def) - (not (eq 'unevalled (cdr (subr-arity def)))) + (not (special-form-p def)) (find-lisp-object-file-name fun def)))) - (fun-pt (point))) + (fun-beg (point)) + (fun-end nil)) (cond ((and evald (not debugger-stack-frame-as-list)) (if (atom fun) @@ -734,6 +733,7 @@ Format it according to VIEW." fun (when (and args (backtrace--line-length-or-nil)) (/ backtrace-line-length 2))))) + (setq fun-end (point)) (if args (insert (backtrace--print-to-string args @@ -749,10 +749,16 @@ Format it according to VIEW." (t (let ((fun-and-args (cons fun args))) (insert (backtrace--print-to-string fun-and-args))) - (cl-incf fun-pt))) + ;; Skip the open-paren. + (cl-incf fun-beg))) (when fun-file - (make-text-button fun-pt (+ fun-pt - (length (backtrace--print-to-string fun))) + (make-text-button fun-beg + (or fun-end + (+ fun-beg + ;; FIXME: `backtrace--print-to-string' will + ;; not necessarily print FUN in the same way + ;; as it did when it was in FUN-AND-ARGS! + (length (backtrace--print-to-string fun)))) :type 'help-function-def 'help-args (list fun fun-file))) ;; After any frame that uses eval-buffer, insert a comment that