1

Let us take an example such as (max 0 (/ 8 0)) -- the problem is the argument to / -- i.e., DIVISORS cannot be 0. The debugging output looks like this:

Debugger entered--Lisp error: (arith-error)
  /(8 0)
  (max 0 (/ 8 0))
  eval((max 0 (/ 8 0)) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

Q:  How can I modify debugger-mode so that the problem function / (on the second line from the top) is a different color -- e.g., text-property "red"; and, perhaps an indication that the problem is the DIVISORS argument?

lawlist
  • 18,826
  • 5
  • 37
  • 118
  • 1
    Highlighting the function should be easy: it's the text before the first `(`. Telling just which argument is problematic is not easy. It depends on the particular error message, and some error messages are not about any particular argument. – Drew Jan 08 '17 at 06:26

1 Answers1

1

The following answer only addresses the issue of highlighting all the C source code functions in the *Backtrace*. The unmodified stock version of debugger-make-xrefs searches the debugging buffer for matches of (symbol-file sym 'defun), which necessarily excludes the built-in C source code functions. Note that the C source code files must be installed to jump to the function definition -- e.g., the source code directory can be configured as follows: (setq find-function-C-source-directory "/path/to/src"). Here is the link to the new feature request: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=25393

(require 'debug)

(defun debugger-make-xrefs (&optional buffer)
  "Attach cross-references to function names in the `*Backtrace*' buffer."
  (interactive "b")
  (with-current-buffer (or buffer (current-buffer))
    (save-excursion
      (setq buffer (current-buffer))
      (let ((inhibit-read-only t)
      (old-end (point-min)) (new-end (point-min)))
  (if debugger-previous-backtrace
      (let (old-start new-start (all-match t))
        (goto-char (point-max))
        (with-temp-buffer
    (insert debugger-previous-backtrace)
    (while (and all-match (not (bobp)))
      (setq old-end (point))
      (forward-line -1)
      (setq old-start (point))
      (with-current-buffer buffer
        (setq new-end (point))
        (forward-line -1)
        (setq new-start (point)))
      (if (not (zerop
          (let ((case-fold-search nil))
            (compare-buffer-substrings
             (current-buffer) old-start old-end
             buffer new-start new-end))))
          (setq all-match nil))))
        (delete-region new-end (point-max))
        (goto-char (point-max))
        (insert (substring debugger-previous-backtrace
         (- old-end (point-min))))
        (narrow-to-region (point-min) new-end)))
  (goto-char (point-min))
  (while (progn
     (goto-char (+ (point) 2))
     (skip-syntax-forward "^w_")
     (not (eobp)))
    (let* ((beg (point))
           (end (progn (skip-syntax-forward "w_") (point)))
           (fn (function-called-at-point)) ;; MODIFICATION
           (sym (intern-soft (buffer-substring-no-properties beg end)))
           ;; MODIFICATION -- excerpt borrowed from `describe-function-1'
           (file 
             (if fn
               (let* (
                  (function fn)
                  (advised (and (symbolp function)
                      (featurep 'nadvice)
                      (advice--p (advice--symbol-function function))))
                   ;; If the function is advised, use the symbol that has the
                   ;; real definition, if that symbol is already set up.
                   (real-function
                    (or (and advised
                                    (advice--cd*r (advice--symbol-function function)))
                        function))
                   ;; Get the real definition.
                   (def (if (symbolp real-function)
                     (or (symbol-function real-function)
                         (signal 'void-function (list real-function)))
                   real-function))
                   (aliased (or (symbolp def)
                         ;; Advised & aliased function.
                         (and advised (symbolp real-function)
                        (not (eq 'autoload (car-safe def))))))
                   (file-name (find-lisp-object-file-name function (if aliased 'defun
                                                                        def))))
                 file-name)
               (and sym (symbol-file sym 'defun)))))
      (when file
        (goto-char beg)
        (re-search-forward "\\(\\sw\\|\\s_\\)+")
        (help-xref-button 0 'help-function-def sym file)))
    (forward-line 1))
  (widen))
      (setq debugger-previous-backtrace (buffer-string)))))
lawlist
  • 18,826
  • 5
  • 37
  • 118