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.
Full log
View this message in rfc822 format
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
>
>
>
>
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.