GNU bug report logs - #9120
24.0.50; Cannot debug lexical-binded function (closure)

Previous Next

Package: emacs;

Reported by: Kan-Ru Chen <kanru <at> kanru.info>

Date: Tue, 19 Jul 2011 02:34:02 UTC

Severity: normal

Merged with 8458

Found in version 24.0.50

Done: Stefan Monnier <monnier <at> iro.umontreal.ca>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 9120 in the body.
You can then email your comments to 9120 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org:
bug#9120; Package emacs. (Tue, 19 Jul 2011 02:34:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Kan-Ru Chen <kanru <at> kanru.info>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 19 Jul 2011 02:34:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Kan-Ru Chen <kanru <at> kanru.info>
To: bug-gnu-emacs <at> gnu.org
Subject: 24.0.50; Cannot debug lexical-binded function (closure)
Date: Tue, 19 Jul 2011 10:32:22 +0800
The lisp debugger doesn't know the closure form:

(setq lexical-binding t)
(defun my-test nil)
(debug-on-entry 'my-test)
=> (error "my-test is not a user-defined Lisp function")

And if the file was byte-compiled, for example:

(debug-on-entry 'shell)
(shell)
=> call-interactively: Invalid function: (lambda 256 "Run an inferior
shell, with I/O through BUFFER (which defaults to `*shell*'). [rest of
the doc string]

Thus one cannot debug most byte-compiled lisp functions (46 files
under lisp/ have declared lexical-binding).

--
Kanru

In GNU Emacs 24.0.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 2.24.5)
 of 2011-07-19 on isil
configured using `configure  '--with-xpm=no' '--with-gif=no' '--with-tiff=no''




Reply sent to Stefan Monnier <monnier <at> iro.umontreal.ca>:
You have taken responsibility. (Mon, 22 Aug 2011 21:20:03 GMT) Full text and rfc822 format available.

Notification sent to Kan-Ru Chen <kanru <at> kanru.info>:
bug acknowledged by developer. (Mon, 22 Aug 2011 21:20:03 GMT) Full text and rfc822 format available.

Message #10 received at 9120-done <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Kan-Ru Chen <kanru <at> kanru.info>
Cc: 9120-done <at> debbugs.gnu.org
Subject: Re: bug#9120: 24.0.50; Cannot debug lexical-binded function (closure)
Date: Mon, 22 Aug 2011 17:17:03 -0400
> The lisp debugger doesn't know the closure form:
> (setq lexical-binding t)
> (defun my-test nil)
> (debug-on-entry 'my-test)
> => (error "my-test is not a user-defined Lisp function")

> And if the file was byte-compiled, for example:

> (debug-on-entry 'shell)
> (shell)
> => call-interactively: Invalid function: (lambda 256 "Run an inferior
> shell, with I/O through BUFFER (which defaults to `*shell*'). [rest of
> the doc string]

> Thus one cannot debug most byte-compiled lisp functions (46 files
> under lisp/ have declared lexical-binding).

I've installed the patch below which should fix this without breaking
other uses.  Please report any problem you encounter with the new code.


        Stefan


=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2011-08-22 12:46:45 +0000
+++ lisp/ChangeLog	2011-08-22 21:15:10 +0000
@@ -1,3 +1,9 @@
+2011-08-22  Stefan Monnier  <monnier <at> iro.umontreal.ca>
+
+	* emacs-lisp/debug.el (debug-arglist): New function.
+	(debug-convert-byte-code): Use it.  Handle lexical byte-codes.
+	(debug-on-entry-1): Handle interpreted closures (bug#9120).
+
 2011-08-22  Juri Linkov  <juri <at> jurta.org>
 
 	* progmodes/compile.el (compilation-mode-font-lock-keywords):

=== modified file 'lisp/emacs-lisp/debug.el'
--- lisp/emacs-lisp/debug.el	2011-07-15 02:16:55 +0000
+++ lisp/emacs-lisp/debug.el	2011-08-22 21:12:18 +0000
@@ -778,6 +778,7 @@
 			 (not (debugger-special-form-p symbol))))
 		t nil nil (symbol-name fn)))
      (list (if (equal val "") fn (intern val)))))
+  ;; FIXME: Use advice.el.
   (when (debugger-special-form-p function)
     (error "Function %s is a special form" function))
   (if (or (symbolp (symbol-function function))
@@ -835,24 +836,30 @@
     (message "Cancelling debug-on-entry for all functions")
     (mapcar 'cancel-debug-on-entry debug-function-list)))
 
+(defun debug-arglist (definition)
+  ;; FIXME: copied from ad-arglist.
+  "Return the argument list of DEFINITION."
+  (require 'help-fns)
+  (help-function-arglist definition 'preserve-names))
+
 (defun debug-convert-byte-code (function)
   (let* ((defn (symbol-function function))
 	 (macro (eq (car-safe defn) 'macro)))
     (when macro (setq defn (cdr defn)))
-    (unless (consp defn)
-      ;; Assume a compiled code object.
-      (let* ((contents (append defn nil))
+    (when (byte-code-function-p defn)
+      (let* ((args (debug-arglist defn))
 	     (body
-	      (list (list 'byte-code (nth 1 contents)
-			  (nth 2 contents) (nth 3 contents)))))
-	(if (nthcdr 5 contents)
-	    (setq body (cons (list 'interactive (nth 5 contents)) body)))
-	(if (nth 4 contents)
+              `((,(if (memq '&rest args) #'apply #'funcall)
+                 ,defn
+                 ,@(remq '&rest (remq '&optional args))))))
+	(if (> (length defn) 5)
+	    (push `(interactive ,(aref defn 5)) body))
+	(if (aref defn 4)
 	    ;; Use `documentation' here, to get the actual string,
 	    ;; in case the compiled function has a reference
 	    ;; to the .elc file.
 	    (setq body (cons (documentation function) body)))
-	(setq defn (cons 'lambda (cons (car contents) body))))
+	(setq defn `(closure (t) ,args ,@body)))
       (when macro (setq defn (cons 'macro defn)))
       (fset function defn))))
 
@@ -861,11 +868,12 @@
 	 (tail defn))
     (when (eq (car-safe tail) 'macro)
       (setq tail (cdr tail)))
-    (if (not (eq (car-safe tail) 'lambda))
+    (if (not (memq (car-safe tail) '(closure lambda)))
 	;; Only signal an error when we try to set debug-on-entry.
 	;; When we try to clear debug-on-entry, we are now done.
 	(when flag
 	  (error "%s is not a user-defined Lisp function" function))
+      (if (eq (car tail) 'closure) (setq tail (cdr tail)))
       (setq tail (cdr tail))
       ;; Skip the docstring.
       (when (and (stringp (cadr tail)) (cddr tail))
@@ -875,9 +883,9 @@
 	(setq tail (cdr tail)))
       (unless (eq flag (equal (cadr tail) '(implement-debug-on-entry)))
 	;; Add/remove debug statement as needed.
-	(if flag
-	    (setcdr tail (cons '(implement-debug-on-entry) (cdr tail)))
-	  (setcdr tail (cddr tail)))))
+	(setcdr tail (if flag
+                         (cons '(implement-debug-on-entry) (cdr tail))
+                       (cddr tail)))))
     defn))
 
 (defun debugger-list-functions ()





bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 20 Sep 2011 11:24:03 GMT) Full text and rfc822 format available.

bug unarchived. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Tue, 20 Sep 2011 22:38:02 GMT) Full text and rfc822 format available.

Merged 8458 9120. Request was from Glenn Morris <rgm <at> gnu.org> to control <at> debbugs.gnu.org. (Tue, 20 Sep 2011 22:38:02 GMT) Full text and rfc822 format available.

Forcibly Merged 8458 9120. Request was from Stefan Monnier <monnier <at> iro.umontreal.ca> to control <at> debbugs.gnu.org. (Wed, 21 Sep 2011 01:08:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 19 Oct 2011 11:24:03 GMT) Full text and rfc822 format available.

This bug report was last modified 13 years and 325 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.