emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Asynchronous bug


From: Stefan Monnier
Subject: Re: Asynchronous bug
Date: Thu, 01 May 2003 15:19:24 -0400

>     Watchpoints showed that the value of `nil' is modified in `unbind_to'.
>     The way it works is that specpdl_ptr->symbol changes from non-nil
>     to nil in the time between the nil test and the use of the value.
> 
> The problem was evident when I looked at the code of unbind_to.
> Does this patch fix it?
> 
> *** eval.c.~1.206.~   Mon Apr 28 17:12:08 2003
> --- eval.c    Thu May  1 02:15:49 2003
> ***************
> *** 3070,3083 ****
>   
>     while (specpdl_ptr != specpdl + count)
>       {
> !       --specpdl_ptr;
>   
> !       if (specpdl_ptr->func != 0)
> !     (*specpdl_ptr->func) (specpdl_ptr->old_value);
>         /* Note that a "binding" of nil is really an unwind protect,
>        so in that case the "old value" is a list of forms to evaluate.  */
> !       else if (NILP (specpdl_ptr->symbol))
> !     Fprogn (specpdl_ptr->old_value);
>         /* If the symbol is a list, it is really (SYMBOL WHERE
>        . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
>        frame.  If WHERE is a buffer or frame, this indicates we
> --- 3070,3083 ----
>   
>     while (specpdl_ptr != specpdl + count)
>       {
> !       struct specbinding *this_binding = specpdl_ptr - 1;
>   
> !       if (this_binding->func != 0)
> !     (*this_binding->func) (this_binding->old_value);
>         /* Note that a "binding" of nil is really an unwind protect,
>        so in that case the "old value" is a list of forms to evaluate.  */
> !       else if (NILP (this_binding->symbol))
> !     Fprogn (this_binding->old_value);
>         /* If the symbol is a list, it is really (SYMBOL WHERE
>        . CURRENT-BUFFER) where WHERE is either nil, a buffer, or a
>        frame.  If WHERE is a buffer or frame, this indicates we
> ***************
> *** 3085,3114 ****
>        binding.  WHERE nil means that the variable had the default
>        value when it was bound.  CURRENT-BUFFER is the buffer that
>            was current when the variable was bound.  */
> !       else if (CONSP (specpdl_ptr->symbol))
>       {
>         Lisp_Object symbol, where;
>   
> !       symbol = XCAR (specpdl_ptr->symbol);
> !       where = XCAR (XCDR (specpdl_ptr->symbol));
>   
>         if (NILP (where))
> !         Fset_default (symbol, specpdl_ptr->old_value);
>         else if (BUFFERP (where))
> !         set_internal (symbol, specpdl_ptr->old_value, XBUFFER (where), 1);
>         else
> !         set_internal (symbol, specpdl_ptr->old_value, NULL, 1);
>       }
>         else
>       {
>         /* If variable has a trivial value (no forwarding), we can
>            just set it.  No need to check for constant symbols here,
>            since that was already done by specbind.  */
> !       if (!MISCP (SYMBOL_VALUE (specpdl_ptr->symbol)))
> !         SET_SYMBOL_VALUE (specpdl_ptr->symbol, specpdl_ptr->old_value);
>         else
> !         set_internal (specpdl_ptr->symbol, specpdl_ptr->old_value, 0, 1);
>       }
>       }
>   
>     if (NILP (Vquit_flag) && quitf)
> --- 3085,3116 ----
>        binding.  WHERE nil means that the variable had the default
>        value when it was bound.  CURRENT-BUFFER is the buffer that
>            was current when the variable was bound.  */
> !       else if (CONSP (this_binding->symbol))
>       {
>         Lisp_Object symbol, where;
>   
> !       symbol = XCAR (this_binding->symbol);
> !       where = XCAR (XCDR (this_binding->symbol));
>   
>         if (NILP (where))
> !         Fset_default (symbol, this_binding->old_value);
>         else if (BUFFERP (where))
> !         set_internal (symbol, this_binding->old_value, XBUFFER (where), 1);
>         else
> !         set_internal (symbol, this_binding->old_value, NULL, 1);
>       }
>         else
>       {
>         /* If variable has a trivial value (no forwarding), we can
>            just set it.  No need to check for constant symbols here,
>            since that was already done by specbind.  */
> !       if (!MISCP (SYMBOL_VALUE (this_binding->symbol)))
> !         SET_SYMBOL_VALUE (this_binding->symbol, this_binding->old_value);
>         else
> !         set_internal (this_binding->symbol, this_binding->old_value, 0, 1);
>       }
> + 
> +       --specpdl_ptr;
>       }
>   
>     if (NILP (Vquit_flag) && quitf)

Isn't this going to cause the unwind-protect to be re-executed
if a signal is thrown while executing
(*specpdl_ptr->func) (specpdl_ptr->old_value);
now that specpdl_ptr is decremented afterwards ?


        Stefan





reply via email to

[Prev in Thread] Current Thread [Next in Thread]