From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Kan-Ru Chen <kanru@kanru.info>
Cc: 9120-done@debbugs.gnu.org
Subject: bug#9120: 24.0.50; Cannot debug lexical-binded function (closure)
Date: Mon, 22 Aug 2011 17:17:03 -0400 [thread overview]
Message-ID: <jwvbovhrvvg.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <87oc0r3sqx.fsf@isil.kanru.info> (Kan-Ru Chen's message of "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).
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 ()
prev parent reply other threads:[~2011-08-22 21:17 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvbovhrvvg.fsf-monnier+emacs@gnu.org \
--to=monnier@iro.umontreal.ca \
--cc=9120-done@debbugs.gnu.org \
--cc=kanru@kanru.info \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.