GNU bug report logs -
#5662
flet not undone on lisp nesting error
Previous Next
Reported by: Dan Davison <davison <at> stats.ox.ac.uk>
Date: Mon, 1 Mar 2010 02:34:02 UTC
Severity: normal
Found in versions 24.3, 23.4, 24.5
Fixed in version 25.0.94
Done: Noam Postavsky <npostavs <at> users.sourceforge.net>
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 5662 in the body.
You can then email your comments to 5662 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org
:
bug#5662
; Package
emacs
.
(Mon, 01 Mar 2010 02:34:02 GMT)
Full text and
rfc822 format available.
Acknowledgement sent
to
Dan Davison <davison <at> stats.ox.ac.uk>
:
New bug report received and forwarded. Copy sent to
bug-gnu-emacs <at> gnu.org
.
(Mon, 01 Mar 2010 02:34:02 GMT)
Full text and
rfc822 format available.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
If I trigger a lisp nesting error with an infinite recursion inside a
let and an flet binding, then the effects of the flet are not undone,
resulting in a change of binding at the top-level.
(defun g () 'g-orig)
(setq a 'a-orig)
(defun h ()
(let ((a 'a-new))
(flet ((g () 'g-new))
(h))))
(h) ;; <-- Lisp nesting exceeds `max-lisp-eval-depth'
(g) ;; g-new !
a ;; a-orig
Dan
If Emacs crashed, and you have the Emacs process in the gdb debugger,
please include the output from the following gdb commands:
`bt full' and `xbacktrace'.
If you would like to further debug the crash, please read the file
/usr/share/emacs/23.1/etc/DEBUG for instructions.
In GNU Emacs 23.1.1 (i486-pc-linux-gnu, GTK+ Version 2.18.3)
of 2009-11-10 on vernadsky, modified by Debian
Windowing system distributor `The X.Org Foundation', version 11.0.10604000
configured using `configure '--build=i486-linux-gnu' '--host=i486-linux-gnu' '--prefix=/usr' '--sharedstatedir=/var/lib' '--libexecdir=/usr/lib' '--localstatedir=/var/lib' '--infodir=/usr/share/info' '--mandir=/usr/share/man' '--with-pop=yes' '--enable-locallisppath=/etc/emacs23:/etc/emacs:/usr/local/share/emacs/23.1/site-lisp:/usr/local/share/emacs/site-lisp:/usr/share/emacs/23.1/site-lisp:/usr/share/emacs/site-lisp:/usr/share/emacs/23.1/leim' '--with-x=yes' '--with-x-toolkit=gtk' '--with-toolkit-scroll-bars' 'build_alias=i486-linux-gnu' 'host_alias=i486-linux-gnu' 'CFLAGS=-DDEBIAN -g -O2' 'LDFLAGS=-g' 'CPPFLAGS=''
Important settings:
value of $LC_ALL: nil
value of $LC_COLLATE: nil
value of $LC_CTYPE: nil
value of $LC_MESSAGES: nil
value of $LC_MONETARY: nil
value of $LC_NUMERIC: nil
value of $LC_TIME: nil
value of $LANG: en_GB.UTF-8
value of $XMODIFIERS: nil
locale-coding-system: utf-8-unix
default-enable-multibyte-characters: t
Major mode: Article
Minor modes in effect:
erc-list-mode: t
erc-menu-mode: t
erc-autojoin-mode: t
erc-ring-mode: t
erc-networks-mode: t
erc-pcomplete-mode: t
erc-track-mode: t
erc-track-minor-mode: t
erc-match-mode: t
erc-button-mode: t
erc-fill-mode: t
erc-stamp-mode: t
erc-netsplit-mode: t
erc-irccontrols-mode: t
erc-noncommands-mode: t
erc-move-to-prompt-mode: t
erc-readonly-mode: t
show-paren-mode: t
recentf-mode: t
yas/minor-mode: t
diff-auto-refine-mode: t
shell-dirtrack-mode: t
tooltip-mode: t
mouse-wheel-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
global-auto-composition-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
line-number-mode: t
transient-mark-mode: t
Recent input:
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <tab>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <tab>
C-x C-s <up> <up> <f1> <up> M-g <return> 1 0 0 <return>
<down> <down> <down> <return> <down> <return> <escape>
SPC SPC <up> <down> <prior> <prior> <escape> <up> <return>
<escape> <escape> <down> <return> <escape> <next> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <up> <up> <up> <prior> <prior> <next>
<next> <escape> <down> <down> <f10> <down> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <down>
<down> <down> <down> <down> <down> <down> <next> <prior>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <down> <down>
<down> <down> <down> <down> <down> <down> <down> <up>
<up> <up> <up> <up> <up> <down> <return> <escape> <up>
<up> <up> <up> <up> <up> <up> <up> <up> <up> <up> <up>
<up> <up> <up> <prior> <prior> <down> <down> <escape>
<escape> <next> <up> <escape> <escape> <next> <prior>
<prior> <escape> <up> <down> q <return> 2 0 0 <return>
C-s f l e t C-s C-s <down> <up> <up> <return> <escape>
<down> C-SPC M-> M-w M-x r e p o r t <tab> b u <tab>
<return>
Recent messages:
End of message
nnimap: Setting marks in INBOX...done
No more unread newsgroups
Retrieving newsgroup: INBOX...
nnimap: Updating info for INBOX...done
Fetching headers for INBOX...done
Generating summary...done
Mark saved where search started
Mark set
Saved text from "If I trigger a lisp nesting error with a"
Information forwarded
to
owner <at> debbugs.gnu.org, bug-gnu-emacs <at> gnu.org
:
bug#5662
; Package
emacs
.
(Fri, 05 Mar 2010 20:31:02 GMT)
Full text and
rfc822 format available.
Message #8 received at 5662 <at> debbugs.gnu.org (full text, mbox):
> If I trigger a lisp nesting error with an infinite recursion inside a
> let and an flet binding, then the effects of the flet are not undone,
> resulting in a change of binding at the top-level.
> (defun g () 'g-orig)
> (setq a 'a-orig)
> (defun h ()
> (let ((a 'a-new))
> (flet ((g () 'g-new))
> (h))))
> (h) ;; <-- Lisp nesting exceeds `max-lisp-eval-depth'
> (g) ;; g-new !
> a ;; a-orig
I can indeed reproduce it. I'm not sure yet what's going on, but it
might be due to the "Lisp nesting exceeds `max-lisp-eval-depth'" error
happening in the unwind-protect code (i.e. while undoing the `g'
binding). The explanation can't be quite so simple, but my gut feeling
tells me it's got to do with it.
Stefan
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#5662
; Package
emacs
.
(Tue, 11 Nov 2014 03:08:02 GMT)
Full text and
rfc822 format available.
Message #11 received at 5662 <at> debbugs.gnu.org (full text, mbox):
You can see the bug of 'unwind-protect' using the following code.
We must see the message “finally”, but are not output.
```elisp
(defun endless-recursive ()
(endless-recursive))
(unwind-protect
(endless-recursive) ;; body
(message "finally”)) ;; unwind-forms
```
The `unwind-protect’ will call the `eval_sub’ function.
And, the `eval_sub’ function check whether the infinite recursion as following code.
```c
/* ./src/eval.c:2086: */
if (++lisp_eval_depth > max_lisp_eval_depth)
{
if (max_lisp_eval_depth < 100)
max_lisp_eval_depth = 100;
if (lisp_eval_depth > max_lisp_eval_depth)
error ("Lisp nesting exceeds `max-lisp-eval-depth'");
}
```
The cause of problem is that `unwind-forms’ will call the `eval_sub’ function.
Of course, the `eval_sub’ function check for infinite recursion.
Consequently, the `unwind-protect’ wouldn't evaluate.
You must be noted step 7~10.
Problem's steps:
1. eval.c:1208:Funwind_protect: record_unwind_protect (unwind_body, XCDR (args));
2. eval.c:1209:Funwind_protect: val = eval_sub (XCAR (args));
3. eval.c:2090:eval_sub: if (lisp_eval_depth > max_lisp_eval_depth) error ("Lisp nesting exceeds `max-lisp-eval-depth'”);
4. eval.c:1582:xsignal: Fsignal (error_symbol, data);
5. eval.c:1558:Fsignal: unwind_to_catch (h, unwind_data);
6. eval.c:1161:unwind_to_catch: unbind_to (handlerlist->pdlcount, Qnil);
7. eval.c:3305:unbind_to: unwind_body // specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg);
8. eval.c:476:unwind_body: Fprogn (body);
9. eval.c:462:Fprogn: val = eval_sub (XCAR (body));
10. eval.c:2090:eval_sub: if (lisp_eval_depth > max_lisp_eval_depth) error ("Lisp nesting exceeds `max-lisp-eval-depth’”)
You can avoid this problem using `ignore-errors’ macro.
(eval.c:1175:unwind_to_catch: lisp_eval_depth = catch->lisp_eval_depth;)
```elisp
(defun endless-recursive ()
(endless-recursive))
(unwind-protect
(ignore-errors (endless-recursive))
(message "finally"))
```
> On Mar 6, 2010, at 5:30 AM, Stefan Monnier <monnier <at> iro.umontreal.ca> wrote:
>
>> If I trigger a lisp nesting error with an infinite recursion inside a
>> let and an flet binding, then the effects of the flet are not undone,
>> resulting in a change of binding at the top-level.
>
>> (defun g () 'g-orig)
>> (setq a 'a-orig)
>
>> (defun h ()
>> (let ((a 'a-new))
>> (flet ((g () 'g-new))
>> (h))))
>> (h) ;; <-- Lisp nesting exceeds `max-lisp-eval-depth'
>> (g) ;; g-new !
>> a ;; a-orig
>
> I can indeed reproduce it. I'm not sure yet what's going on, but it
> might be due to the "Lisp nesting exceeds `max-lisp-eval-depth'" error
> happening in the unwind-protect code (i.e. while undoing the `g'
> binding). The explanation can't be quite so simple, but my gut feeling
> tells me it's got to do with it.
>
>
> Stefan
>
>
>
>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#5662
; Package
emacs
.
(Tue, 11 Nov 2014 15:51:01 GMT)
Full text and
rfc822 format available.
Message #14 received at 5662 <at> debbugs.gnu.org (full text, mbox):
> The cause of problem is that `unwind-forms’ will call the `eval_sub’
> function. Of course, the `eval_sub’ function check for infinite
> recursion. Consequently, the `unwind-protect’ wouldn't evaluate.
Thanks for digging into it. Indeed, I think I see it now: in
`unbind_to' we run the unwind_forms without updating lisp_eval_depth, so
they're run with the lisp_eval_depth of the place where the signal
was thrown, so if the signal was thrown because lisp_eval_depth >
max_lisp_eval_depth, then the unwind forms will all fail by signaling
error ("Lisp nesting exceeds `max-lisp-eval-depth'").
This said, at the time we run those unwind forms, the C stack is still
at the same "very deep" state as when the error was signaled, so the
lisp_eval_depth value is not completely wrong (more specifically, it
would be unwise in general to simply set it to the value corresponding
to the target of the longjmp, even though in your particular case you
could argue that it would be right).
So maybe the best solution would be to temporarily increase
max-lisp-eval-depth like we do for call_debugger. Not sure how best to
do that, since the way it's done in call_debugger could have too high
a performance cost (it's not a problem for call_debugger since that's
an exceptional situation).
Stefan
> You must be noted step 7~10.
> Problem's steps:
> 1. eval.c:1208:Funwind_protect: record_unwind_protect (unwind_body, XCDR (args));
> 2. eval.c:1209:Funwind_protect: val = eval_sub (XCAR (args));
> 3. eval.c:2090:eval_sub: if (lisp_eval_depth > max_lisp_eval_depth) error ("Lisp nesting exceeds `max-lisp-eval-depth'”);
> 4. eval.c:1582:xsignal: Fsignal (error_symbol, data);
> 5. eval.c:1558:Fsignal: unwind_to_catch (h, unwind_data);
> 6. eval.c:1161:unwind_to_catch: unbind_to (handlerlist->pdlcount, Qnil);
> 7. eval.c:3305:unbind_to: unwind_body // specpdl_ptr->unwind_ptr.func (specpdl_ptr->unwind_ptr.arg);
> 8. eval.c:476:unwind_body: Fprogn (body);
> 9. eval.c:462:Fprogn: val = eval_sub (XCAR (body));
> 10. eval.c:2090:eval_sub: if (lisp_eval_depth > max_lisp_eval_depth) error ("Lisp nesting exceeds `max-lisp-eval-depth’”)
> You can avoid this problem using `ignore-errors’ macro.
> (eval.c:1175:unwind_to_catch: lisp_eval_depth = catch->lisp_eval_depth;)
> ```elisp
> (defun endless-recursive ()
> (endless-recursive))
> (unwind-protect
> (ignore-errors (endless-recursive))
> (message "finally"))
> ```
>> On Mar 6, 2010, at 5:30 AM, Stefan Monnier <monnier <at> iro.umontreal.ca> wrote:
>>
>>> If I trigger a lisp nesting error with an infinite recursion inside a
>>> let and an flet binding, then the effects of the flet are not undone,
>>> resulting in a change of binding at the top-level.
>>
>>> (defun g () 'g-orig)
>>> (setq a 'a-orig)
>>
>>> (defun h ()
>>> (let ((a 'a-new))
>>> (flet ((g () 'g-new))
>>> (h))))
>>> (h) ;; <-- Lisp nesting exceeds `max-lisp-eval-depth'
>>> (g) ;; g-new !
>>> a ;; a-orig
>>
>> I can indeed reproduce it. I'm not sure yet what's going on, but it
>> might be due to the "Lisp nesting exceeds `max-lisp-eval-depth'" error
>> happening in the unwind-protect code (i.e. while undoing the `g'
>> binding). The explanation can't be quite so simple, but my gut feeling
>> tells me it's got to do with it.
>>
>>
>> Stefan
>>
>>
>>
>>
Information forwarded
to
bug-gnu-emacs <at> gnu.org
:
bug#5662
; Package
emacs
.
(Thu, 02 Jun 2016 01:16:01 GMT)
Full text and
rfc822 format available.
Message #17 received at 5662 <at> debbugs.gnu.org (full text, mbox):
found 5662 23.4
found 5662 24.3
found 5662 24.5
fixed 5662 25.0.94
close 5662
quit
Seems to have been fixed in Emacs 25. I could reproduce in several
earlier versions (had to add a (require 'cl) to demo code).
bug Marked as found in versions 23.4.
Request was from
Noam Postavsky <npostavs <at> users.sourceforge.net>
to
control <at> debbugs.gnu.org
.
(Thu, 02 Jun 2016 01:16:02 GMT)
Full text and
rfc822 format available.
bug Marked as found in versions 24.3.
Request was from
Noam Postavsky <npostavs <at> users.sourceforge.net>
to
control <at> debbugs.gnu.org
.
(Thu, 02 Jun 2016 01:16:02 GMT)
Full text and
rfc822 format available.
bug Marked as found in versions 24.5.
Request was from
Noam Postavsky <npostavs <at> users.sourceforge.net>
to
control <at> debbugs.gnu.org
.
(Thu, 02 Jun 2016 01:16:02 GMT)
Full text and
rfc822 format available.
bug Marked as fixed in versions 25.0.94.
Request was from
Noam Postavsky <npostavs <at> users.sourceforge.net>
to
control <at> debbugs.gnu.org
.
(Thu, 02 Jun 2016 01:16:02 GMT)
Full text and
rfc822 format available.
bug closed, send any further explanations to
5662 <at> debbugs.gnu.org and Dan Davison <davison <at> stats.ox.ac.uk>
Request was from
Noam Postavsky <npostavs <at> users.sourceforge.net>
to
control <at> debbugs.gnu.org
.
(Thu, 02 Jun 2016 01:16: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
.
(Thu, 30 Jun 2016 11:24:04 GMT)
Full text and
rfc822 format available.
This bug report was last modified 8 years and 352 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.