emacs-devel
[Top][All Lists]
Advanced

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

Re: Lisp debugger problems.


From: Lute Kamstra
Subject: Re: Lisp debugger problems.
Date: Mon, 28 Feb 2005 10:44:41 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (gnu/linux)

Lute Kamstra <address@hidden> writes:

[...]

> I investigated this problem a bit more.  It seems that the bug only
> happens when the body of a function contains just one sexp.  For
> example, when I do:
>
>   (defun fun (a) "Docstring." (interactive) (1+ a))
>   (debug-on-entry 'fun)
>   (fun 1)
>
> to enter the debugger and then type j to invoke debugger-jump, then
> the return value is nil (wrong).  But when I do:
>
>   (defun fun (a) "Docstring." (interactive) a (1+ a))
>   (debug-on-entry 'fun)
>   (fun 1)
>
> to enter the debugger and then type j to invoke debugger-jump, then
> the return value is 2 (right).
>
> debug-on-entry inserts (debug 'debug) into the definition of fun:
>
>   (defun fun (a) "Docstring." (interactive) (1+ a))
>   (symbol-function 'fun)
>     => (lambda (a) "Docstring." (interactive) (1+ a))
>   (debug-on-entry 'fun)
>   (symbol-function 'fun)
>     => (lambda (a) "Docstring." (interactive) (debug (quote debug)) (1+ a))
>
> So when fun is called, it invokes the debugger.  Then the debugger
> calls debugger-jump, which changes the definition of fun by removing
> (debug 'debug).  So the definition of fun is changed in the middle
> of a call to fun.  My guess is that this somehow confuses the lisp
> interpreter (in case the body of fun consists of just one sexp) and
> causes it to produce the wrong return value.

What actually happens is that removing (debug 'debug) causes the sexp
immediately following it not to be evaluated.  The following patch
fixes this.  (As a bonus, checking for functions with an empty body is
not necessary anymore.)  Shall I commit it?

Lute.


*** lisp/emacs-lisp/debug.el    27 Feb 2005 09:57:51 -0000      1.67
--- lisp/emacs-lisp/debug.el    28 Feb 2005 09:29:13 -0000
***************
*** 25,31 ****
  
  ;;; Commentary:
  
! ;; This is a major mode documented in the Emacs manual.
  
  ;;; Code:
  
--- 25,31 ----
  
  ;;; Commentary:
  
! ;; This is a major mode documented in the Emacs Lisp manual.
  
  ;;; Code:
  
***************
*** 476,483 ****
        (insert ? )))
    (beginning-of-line))
  
- 
- 
  (put 'debugger-env-macro 'lisp-indent-function 0)
  (defmacro debugger-env-macro (&rest body)
    "Run BODY in original environment."
--- 476,481 ----
***************
*** 698,719 ****
        (debug-on-entry-1 function (cdr defn) flag)
        (or (eq (car defn) 'lambda)
          (error "%s not user-defined Lisp function" function))
!       (let ((tail (cddr defn)))
        ;; Skip the docstring.
!       (if (stringp (car tail)) (setq tail (cdr tail)))
        ;; Skip the interactive form.
!       (if (eq 'interactive (car-safe (car tail))) (setq tail (cdr tail)))
!       (unless (eq flag (equal (car tail) '(debug 'debug)))
!         ;; If the function has no body, add nil as a body element.
!         (when (null tail)
!           (setq tail (list nil))
!           (nconc defn tail))
          ;; Add/remove debug statement as needed.
!         (if (not flag)
!             (progn (setcar tail (cadr tail))
!                    (setcdr tail (cddr tail)))
!           (setcdr tail (cons (car tail) (cdr tail)))
!           (setcar tail '(debug 'debug))))
        defn))))
  
  (defun debugger-list-functions ()
--- 696,711 ----
        (debug-on-entry-1 function (cdr defn) flag)
        (or (eq (car defn) 'lambda)
          (error "%s not user-defined Lisp function" function))
!       (let ((tail (cdr defn)))
        ;; Skip the docstring.
!       (when (stringp (cadr tail)) (setq tail (cdr tail)))
        ;; Skip the interactive form.
!       (when (eq 'interactive (car-safe (cadr tail))) (setq tail (cdr tail)))
!       (unless (eq flag (equal (cadr tail) '(debug 'debug)))
          ;; Add/remove debug statement as needed.
!         (if flag
!             (setcdr tail (cons '(debug 'debug) (cdr tail)))
!           (setcdr tail (cddr tail))))
        defn))))
  
  (defun debugger-list-functions ()






reply via email to

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