unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#9120: 24.0.50; Cannot debug lexical-binded function (closure)
@ 2011-07-19  2:32 Kan-Ru Chen
  2011-08-22 21:17 ` Stefan Monnier
  0 siblings, 1 reply; 2+ messages in thread
From: Kan-Ru Chen @ 2011-07-19  2:32 UTC (permalink / raw)
  To: 9120

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''





^ permalink raw reply	[flat|nested] 2+ messages in thread

* bug#9120: 24.0.50; Cannot debug lexical-binded function (closure)
  2011-07-19  2:32 bug#9120: 24.0.50; Cannot debug lexical-binded function (closure) Kan-Ru Chen
@ 2011-08-22 21:17 ` Stefan Monnier
  0 siblings, 0 replies; 2+ messages in thread
From: Stefan Monnier @ 2011-08-22 21:17 UTC (permalink / raw)
  To: Kan-Ru Chen; +Cc: 9120-done

> 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@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@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 ()






^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2011-08-22 21:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-07-19  2:32 bug#9120: 24.0.50; Cannot debug lexical-binded function (closure) Kan-Ru Chen
2011-08-22 21:17 ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).