• Noam Postavsky's avatar
    Don't signal during backtrace unrewind (Bug#40088) · 8944310d
    Noam Postavsky authored
    backtrace_eval_unrewind is used to temporarily reverse
    let-bindings (it's called with a positive argument to reverse
    bindings, and then a negative argument to re-apply them) by
    backtrace--locals and backtrace-eval.  For the SPECPDL_LET_DEFAULT and
    SPECPDL_LET_LOCAL cases (which occur for let-bindings on buffer-local
    variables), the code calls Fdefault_value and Fbuffer_local_value on
    the symbol.
    
    For symbols which are unbound at top-level, the first (with positive
    argument) call to backtrace_eval_unrewind will set the symbol's value
    to unbound (putting the current value in the specpdl's "old value"
    slot).  On the second (with negative argument) call,
    backtrace_eval_unrewind attempts to retrieve the symbol's value with
    Fdefault_value or Fbuffer_local_value, but that raises a void-variable
    signal.  This interrupts the restoration of the let-bindings, so any
    other variables more recent on the stack will now have the wrong
    value.
    
    * src/data.c (default_value): Make non-static.
    * src/lisp.h: Declare it.
    * src/eval.c (backtrace_eval_unrewind): Replace the calls to
    Fdefault_value and Fbuffer_local_value with default_value and
    buffer_local_value, respectively.  The latter do exactly the same as
    the former, except if the symbol's value is Qunbound they just return
    it instead of signaling void-variable.
    8944310d
data.c 114 KB