Problem reported by Steve Kemp (Bug#27585).
* src/eval.c (near_C_stack_top): Remove. All uses replaced
by current_thread->stack_top.
(record_in_backtrace): Set current_thread->stack_top.
This is for when the Lisp interpreter calls itself.
* src/lread.c (read1): Set current_thread->stack_top.
This is for recursive s-expression reads.
* src/print.c (print_object): Set current_thread->stack_top.
This is for recursive s-expression printing.
* src/thread.c (mark_one_thread): Get stack top first.
* src/thread.h (struct thread_state.stack_top): Now void *, not char *.
return pdl;
}
-/* Return a pointer to somewhere near the top of the C stack. */
-void *
-near_C_stack_top (void)
-{
- return backtrace_args (backtrace_top ());
-}
-
void
init_eval_once (void)
{
specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
specpdl_ptr->bt.debug_on_exit = false;
specpdl_ptr->bt.function = function;
- specpdl_ptr->bt.args = args;
+ current_thread->stack_top = specpdl_ptr->bt.args = args;
specpdl_ptr->bt.nargs = nargs;
grow_specpdl ();
ATTRIBUTE_FORMAT_PRINTF (1, 0);
extern void un_autoload (Lisp_Object);
extern Lisp_Object call_debugger (Lisp_Object arg);
-extern void *near_C_stack_top (void);
extern void init_eval_once (void);
extern Lisp_Object safe_call (ptrdiff_t, Lisp_Object, ...);
extern Lisp_Object safe_call1 (Lisp_Object, Lisp_Object);
bool uninterned_symbol = false;
bool multibyte;
char stackbuf[MAX_ALLOCA];
+ current_thread->stack_top = stackbuf;
*pch = 0;
char buf[max (sizeof "from..to..in " + 2 * INT_STRLEN_BOUND (EMACS_INT),
max (sizeof " . #" + INT_STRLEN_BOUND (printmax_t),
40))];
-
+ current_thread->stack_top = buf;
maybe_quit ();
/* Detect circularities and truncate them. */
/* The known top and bottom of the stack. The actual stack may
extend a bit beyond these boundaries. */
char *bot = stack_bottom;
- char *top = near_C_stack_top ();
+ char *top = current_thread->stack_top;
/* Log base 2 of the stack heuristic ratio. This ratio is the size
of the known stack divided by the size of the guard area past the
static void
mark_one_thread (struct thread_state *thread)
{
- struct handler *handler;
- Lisp_Object tem;
+ /* Get the stack top now, in case mark_specpdl changes it. */
+ void *stack_top = thread->stack_top;
mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
- mark_stack (thread->m_stack_bottom, thread->stack_top);
+ mark_stack (thread->m_stack_bottom, stack_top);
- for (handler = thread->m_handlerlist; handler; handler = handler->next)
+ for (struct handler *handler = thread->m_handlerlist;
+ handler; handler = handler->next)
{
mark_object (handler->tag_or_ch);
mark_object (handler->val);
if (thread->m_current_buffer)
{
+ Lisp_Object tem;
XSETBUFFER (tem, thread->m_current_buffer);
mark_object (tem);
}
char *m_stack_bottom;
#define stack_bottom (current_thread->m_stack_bottom)
- /* An address near the top of the stack. */
- char *stack_top;
+ /* The address of an object near the C stack top, used to determine
+ which words need to be scanned by the garbage collector. This is
+ also used to detect heuristically whether segmentation violation
+ address indicates stack overflow, as opposed to some internal
+ error in Emacs. If the C function F calls G which calls H which
+ calls ... F, then at least one of the functions in the chain
+ should set this to the address of a local variable. */
+ void *stack_top;
struct catchtag *m_catchlist;
#define catchlist (current_thread->m_catchlist)