emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 0536b96011d: (backtrace--print-func-and-args): Fix (part of) bug#


From: Stefan Monnier
Subject: master 0536b96011d: (backtrace--print-func-and-args): Fix (part of) bug#70436
Date: Sat, 20 Apr 2024 11:24:06 -0400 (EDT)

branch: master
commit 0536b96011d24797d16d97a59a62f633a3d30472
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    (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.
---
 lisp/emacs-lisp/backtrace.el | 28 +++++++++++++++++-----------
 1 file changed, 17 insertions(+), 11 deletions(-)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]