all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Pip Cet <pipcet@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 39962@debbugs.gnu.org, pieter-l@vanoostrum.org, rms@gnu.org,
	eggert@cs.ucla.edu
Subject: bug#39962: 27.0.90; Crash in Emacs 27.0.90
Date: Sat, 14 Mar 2020 15:34:14 +0000	[thread overview]
Message-ID: <CAOqdjBemiVsiLULRhWZ3uKjTQzB0OazWMOzHQggPSqHf2KOvxQ@mail.gmail.com> (raw)
In-Reply-To: <CAOqdjBcyz4NJCkTotKRs_gJRTc8Ki2RsnX2imOw7cexLgWhEqg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1292 bytes --]

On Sat, Mar 14, 2020 at 9:16 AM Pip Cet <pipcet@gmail.com> wrote:
> I don't think it's desirable as default behavior, at this point. It
> seems not entirely trivial to get it to work, at least in the case
> where system libraries aren't built with -fsplit-stack.

It turns out my problems were due to vfork, which doesn't appear to
work with -fsplit-stack and non-split-stack libraries.

The attached patch works, but it appears the standard behavior of
-fsplit-stack is to allocate the stack one page at a time, so it runs
into Linux system limits after 128K stack pages (with guard pages).
That corresponds to somewhere between 4M and 8M symbols in the linked
list, using my test program.

To make this work, configure with CFLAGS="-fsplit-stack", edit
config.h to define USE_SPLIT_STACK and #define vfork fork.

Note that this version marks the entire mapped stack, not just the
area that is actually used; that should be easy enough to fix, but it
doesn't appear to cause any immediate problems.

So, in summary, it's possible to get it to work, but you have to work
around the vfork limitation, and it doesn't help all that much because
the allocation strategy needs to be adjusted, and even then it would
need some extra work not to mark stack areas that were once used but
now aren't.

[-- Attachment #2: 0001-split-stack-support.patch --]
[-- Type: text/x-patch, Size: 8851 bytes --]

From 6f8d155a596e514eb5cc96c4d7c4cc43bbe02739 Mon Sep 17 00:00:00 2001
From: Pip Cet <pipcet@gmail.com>
Date: Sat, 14 Mar 2020 15:30:15 +0000
Subject: [PATCH] split-stack support

---
 src/alloc.c  | 17 +++++++++++++++++
 src/emacs.c  |  4 ++++
 src/eval.c   |  5 ++++-
 src/lisp.h   | 14 +++++++++++++-
 src/lread.c  |  2 ++
 src/print.c  |  2 ++
 src/sysdep.c |  2 +-
 src/thread.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
 src/thread.h |  8 ++++++++
 9 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/src/alloc.c b/src/alloc.c
index a35b48cfb2..76ebf4db92 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5062,13 +5062,26 @@ mark_stack (char const *bottom, char const *end)
    It is invalid to run any Lisp code or to allocate any GC memory
    from FUNC.  */
 
+extern void * __splitstack_find (void *segment_arg, void *sp, size_t *len,
+				 void **next_segment, void **next_sp,
+				 void **initial_sp);
+
+
 NO_INLINE void
 flush_stack_call_func (void (*func) (void *arg), void *arg)
 {
   void *end;
   struct thread_state *self = current_thread;
   SET_STACK_TOP_ADDRESS (&end);
+#ifdef USE_SPLIT_STACK
+  self->splitstack_stack =
+    __splitstack_find (NULL, NULL, &self->splitstack_stack_size,
+		       &self->splitstack_next_segment,
+		       &self->splitstack_next_sp,
+		       &self->splitstack_initial_sp);
+#else
   self->stack_top = end;
+#endif
   func (arg);
   eassert (current_thread == self);
 }
@@ -5973,7 +5986,9 @@ maybe_garbage_collect (void)
 garbage_collect (void)
 {
   struct buffer *nextb;
+#ifndef USE_SPLIT_STACK
   char stack_top_variable;
+#endif
   bool message_p;
   ptrdiff_t count = SPECPDL_INDEX ();
   struct timespec start;
@@ -6013,6 +6028,7 @@ garbage_collect (void)
     message_p = false;
 
   /* Save a copy of the contents of the stack, for debugging.  */
+#ifndef USE_SPLIT_STACK
 #if MAX_SAVE_STACK > 0
   if (NILP (Vpurify_flag))
     {
@@ -6040,6 +6056,7 @@ garbage_collect (void)
 	}
     }
 #endif /* MAX_SAVE_STACK > 0 */
+#endif
 
   if (garbage_collection_messages)
     message1_nolog ("Garbage collecting...");
diff --git a/src/emacs.c b/src/emacs.c
index ea9c4cd79d..f8b947e2d8 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -928,7 +928,9 @@ main (int argc, char **argv)
 {
   /* Variable near the bottom of the stack, and aligned appropriately
      for pointers.  */
+#ifndef USE_SPLIT_STACK
   void *stack_bottom_variable;
+#endif
 
   bool no_loadup = false;
   char *junk = 0;
@@ -941,8 +943,10 @@ main (int argc, char **argv)
   /* If we use --chdir, this records the original directory.  */
   char const *original_pwd = 0;
 
+#ifndef USE_SPLIT_STACK
   /* Record (approximately) where the stack begins.  */
   stack_bottom = (char *) &stack_bottom_variable;
+#endif
 
   const char *dump_mode = NULL;
   int skip_args = 0;
diff --git a/src/eval.c b/src/eval.c
index 4559a0e1f6..0f57383581 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2147,7 +2147,10 @@ record_in_backtrace (Lisp_Object function, Lisp_Object *args, ptrdiff_t nargs)
   specpdl_ptr->bt.kind = SPECPDL_BACKTRACE;
   specpdl_ptr->bt.debug_on_exit = false;
   specpdl_ptr->bt.function = function;
-  current_thread->stack_top = specpdl_ptr->bt.args = args;
+#ifndef USE_SPLIT_STACK
+  current_thread->stack_top =
+#endif
+    specpdl_ptr->bt.args = args;
   specpdl_ptr->bt.nargs = nargs;
   grow_specpdl ();
 
diff --git a/src/lisp.h b/src/lisp.h
index a379977d35..a09ca273a8 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2145,7 +2145,19 @@ CHAR_TABLE_EXTRA_SLOTS (struct Lisp_Char_Table *ct)
 /* Save and restore the instruction and environment pointers,
    without affecting the signal mask.  */
 
-#ifdef HAVE__SETJMP
+#define USE_SPLITSTACK
+#ifdef USE_SPLITSTACK
+typedef struct {
+  sigjmp_buf jmpbuf;
+  void *splitstack_context[10];
+} sys_jmp_buf[1];
+
+extern void __splitstack_getcontext (void *context[10]);
+extern void __splitstack_setcontext (void *context[10]);
+
+# define sys_setjmp(j) (__splitstack_getcontext(j[0].splitstack_context), (sigsetjmp (j[0].jmpbuf, 0) ? ({ __splitstack_setcontext(j[0].splitstack_context); 1; }) : ({ __splitstack_setcontext(j[0].splitstack_context); 0; })))
+# define sys_longjmp(j, v) siglongjmp (j[0].jmpbuf, v)
+#elif defined HAVE__SETJMP
 typedef jmp_buf sys_jmp_buf;
 # define sys_setjmp(j) _setjmp (j)
 # define sys_longjmp(j, v) _longjmp (j, v)
diff --git a/src/lread.c b/src/lread.c
index eabf3b938c..a3da7f9965 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2745,7 +2745,9 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
   bool uninterned_symbol = false;
   bool multibyte;
   char stackbuf[stackbufsize];
+#ifndef USE_SPLIT_STACK
   current_thread->stack_top = stackbuf;
+#endif
 
   *pch = 0;
 
diff --git a/src/print.c b/src/print.c
index 634169dbdb..ca684b6d86 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1853,7 +1853,9 @@ print_object (Lisp_Object obj, Lisp_Object printcharfun, bool escapeflag)
 		     max ((sizeof " with data 0x"
 			   + (sizeof (uintmax_t) * CHAR_BIT + 4 - 1) / 4),
 			  40)))];
+#ifndef USE_SPLIT_STACK
   current_thread->stack_top = buf;
+#endif
   maybe_quit ();
 
   /* Detect circularities and truncate them.  */
diff --git a/src/sysdep.c b/src/sysdep.c
index 149d80f19e..e4d0f67d27 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -1807,7 +1807,7 @@ handle_arith_signal (int sig)
   xsignal0 (Qarith_error);
 }
 
-#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT
+#if defined HAVE_STACK_OVERFLOW_HANDLING && !defined WINDOWSNT && !defined USE_SPLIT_STACK
 
 /* Alternate stack used by SIGSEGV handler below.  */
 
diff --git a/src/thread.c b/src/thread.c
index df1a705382..e9e2c84340 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -619,6 +619,51 @@ thread_select (select_func *func, int max_fds, fd_set *rfds,
 
 \f
 
+#ifdef USE_SPLIT_STACK
+extern void * __splitstack_find (void *segment_arg, void *sp, size_t *len,
+				 void **next_segment, void **next_sp,
+				 void **initial_sp);
+
+
+static void
+mark_one_thread (struct thread_state *thread)
+{
+  mark_specpdl (thread->m_specpdl, thread->m_specpdl_ptr);
+
+  mark_stack (thread->splitstack_stack, ((char *)thread->splitstack_stack) + thread->splitstack_stack_size);
+  {
+    void *next_segment = thread->splitstack_next_segment;
+    void *next_sp = thread->splitstack_next_sp;
+    void *initial_sp = thread->splitstack_initial_sp;
+    void *stack;
+    size_t stack_size;
+
+    while ((stack = __splitstack_find (next_segment, next_sp, &stack_size,
+				       &next_segment, &next_sp,
+				       &initial_sp)) != NULL)
+      {
+	mark_stack (stack, ((char *)stack) + stack_size);
+      }
+  }
+
+  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);
+    }
+
+  /* No need to mark Lisp_Object members like m_last_thing_searched,
+     as mark_threads_callback does that by calling mark_object.  */
+}
+#else
 static void
 mark_one_thread (struct thread_state *thread)
 {
@@ -646,6 +691,7 @@ mark_one_thread (struct thread_state *thread)
   /* No need to mark Lisp_Object members like m_last_thing_searched,
      as mark_threads_callback does that by calling mark_object.  */
 }
+#endif
 
 static void
 mark_threads_callback (void *ignore)
@@ -717,12 +763,14 @@ run_thread (void *state)
 {
   /* Make sure stack_top and m_stack_bottom are properly aligned as GC
      expects.  */
-  max_align_t stack_pos;
 
   struct thread_state *self = state;
   struct thread_state **iter;
 
+#ifndef USE_SPLIT_STACK
+  max_align_t stack_pos;
   self->m_stack_bottom = self->stack_top = (char *) &stack_pos;
+#endif
   self->thread_id = sys_thread_self ();
 
   if (self->thread_name)
diff --git a/src/thread.h b/src/thread.h
index a09929fa44..4f49aacd8e 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -63,6 +63,13 @@ #define saved_last_thing_searched (current_thread->m_saved_last_thing_searched)
   Lisp_Object event_object;
   /* event_object must be the last Lisp field.  */
 
+#ifdef USE_SPLIT_STACK
+  void *splitstack_stack;
+  void *splitstack_next_segment;
+  void *splitstack_next_sp;
+  void *splitstack_initial_sp;
+  size_t splitstack_stack_size;
+#else
   /* An address near the bottom of the stack.
      Tells GC how to save a copy of the stack.  */
   char const *m_stack_bottom;
@@ -76,6 +83,7 @@ #define stack_bottom (current_thread->m_stack_bottom)
      calls ... F, then at least one of the functions in the chain
      should set this to the address of a local variable.  */
   void const *stack_top;
+#endif
 
   struct catchtag *m_catchlist;
 #define catchlist (current_thread->m_catchlist)
-- 
2.25.1


  reply	other threads:[~2020-03-14 15:34 UTC|newest]

Thread overview: 119+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-06 23:55 bug#39962: 27.0.90; Crash in Emacs 27.0.90 Pieter van Oostrum
2020-03-07  7:48 ` Eli Zaretskii
2020-03-07  8:40   ` Pieter van Oostrum
2020-03-07  8:41   ` Pieter van Oostrum
2020-03-07 10:51     ` Eli Zaretskii
2020-03-07 11:06   ` Pieter van Oostrum
2020-03-07 13:10     ` Eli Zaretskii
2020-03-07 15:06       ` Pieter van Oostrum
2020-03-07 15:17         ` Eli Zaretskii
2020-03-07 15:49           ` Pieter van Oostrum
2020-03-07 16:07             ` Eli Zaretskii
2020-03-07 17:21               ` Pieter van Oostrum
2020-03-07 18:01                 ` Eli Zaretskii
2020-03-07 19:14                   ` Pieter van Oostrum
2020-03-07 19:21                     ` Eli Zaretskii
2020-03-07 22:07                       ` Pieter van Oostrum
2020-03-09  4:00     ` Pip Cet
2020-03-08  7:42 ` Paul Eggert
2020-03-08  9:34   ` Pieter van Oostrum
2020-03-08 10:05     ` Paul Eggert
2020-03-08 21:37       ` Pieter van Oostrum
2020-03-08 21:58         ` Pieter van Oostrum
2020-03-08 22:34         ` Paul Eggert
2020-03-08 23:58           ` Pieter van Oostrum
2020-03-09  0:01             ` Paul Eggert
2020-03-09 13:26               ` Pieter van Oostrum
2020-03-09 17:10                 ` Eli Zaretskii
2020-03-09 19:48                   ` Pieter van Oostrum
2020-03-10 13:37                     ` Pieter van Oostrum
2020-03-09 19:51                   ` Paul Eggert
2020-03-09 21:32                     ` Pieter van Oostrum
2020-03-10 10:52                       ` Pieter van Oostrum
2020-03-10 14:19                         ` Pip Cet
2020-03-10 16:36                           ` Pieter van Oostrum
2020-03-11 14:32                             ` Pip Cet
2020-03-11 15:16                               ` Pieter van Oostrum
2020-03-11 15:43                                 ` Pip Cet
2020-03-11 15:51                                   ` Paul Eggert
2020-03-11 16:21                                     ` Eli Zaretskii
2020-03-11 17:52                                   ` Eli Zaretskii
2020-03-11 18:53                                     ` Pip Cet
2020-03-11 19:34                                       ` Eli Zaretskii
2020-03-12 10:32                                         ` Pip Cet
2020-03-12 15:23                                           ` Eli Zaretskii
2020-03-12 20:36                                             ` Pip Cet
2020-03-13  9:39                                               ` Eli Zaretskii
2020-03-13 13:56                                                 ` Pip Cet
2020-03-13 16:30                                                   ` Eli Zaretskii
2020-03-14  9:02                                                     ` Pip Cet
2020-03-14 15:39                                                       ` Pip Cet
2020-03-14 16:00                                                         ` Paul Eggert
2020-03-14 16:15                                                           ` Pip Cet
2020-03-14 16:57                                                             ` Eli Zaretskii
2020-03-14 18:34                                                               ` Pip Cet
2020-03-14 19:09                                                                 ` Paul Eggert
2020-03-14 20:10                                                                   ` Eli Zaretskii
2020-03-15 12:12                                                                     ` Pip Cet
2020-03-15 14:53                                                                       ` Eli Zaretskii
2020-03-15 12:09                                                                   ` Pip Cet
2020-03-15 14:50                                                                     ` Eli Zaretskii
2020-03-16 16:31                                                     ` Stefan Monnier
2020-03-11 20:03                                   ` Pieter van Oostrum
2020-03-12 13:55                                     ` Pip Cet
2020-03-12 18:13                                       ` Pieter van Oostrum
2020-03-12 20:00                                         ` Pip Cet
2020-03-13  8:09                                           ` Eli Zaretskii
2020-03-13  8:39                                             ` Pip Cet
2020-03-13  9:19                                               ` Eli Zaretskii
2020-03-13 17:43                                                 ` Pieter van Oostrum
2020-03-14  3:38                                                 ` Richard Stallman
2020-03-14  8:37                                                   ` Eli Zaretskii
2020-03-14  9:16                                                     ` Pip Cet
2020-03-14 15:34                                                       ` Pip Cet [this message]
2020-03-13 17:42                                             ` Pieter van Oostrum
2020-03-13 19:34                                               ` Eli Zaretskii
2020-03-13 21:35                                                 ` Pieter van Oostrum
2020-03-14  8:08                                                   ` Eli Zaretskii
2020-03-14 21:32                                                     ` Pieter van Oostrum
2020-03-15 19:49                                                       ` Pieter van Oostrum
2020-03-15 19:57                                                         ` Eli Zaretskii
2020-03-15 23:26                                                           ` Pieter van Oostrum
2020-03-16 10:44                                                             ` Pieter van Oostrum
2020-03-16 15:07                                                               ` Eli Zaretskii
2020-03-16 15:33                                                               ` Pip Cet
2020-03-16 17:19                                                                 ` Pip Cet
2020-03-17  3:29                                                                   ` Pieter van Oostrum
2020-03-17  4:54                                                                     ` Pip Cet
2020-03-17  5:20                                                                       ` Pip Cet
2020-03-17  8:45                                                                         ` Pieter van Oostrum
2020-03-17 13:54                                                                           ` Pip Cet
2020-03-17 15:27                                                                             ` Pieter van Oostrum
2020-03-17 20:16                                                                               ` Pip Cet
2020-03-17 23:32                                                                                 ` Pieter van Oostrum
2020-03-18 15:05                                                                                   ` Eli Zaretskii
2020-03-19 13:23                                                                                     ` Pieter van Oostrum
2020-03-19 13:57                                                                                       ` Pip Cet
2020-03-21 21:22                                                                                         ` Pieter van Oostrum
2020-03-22 14:21                                                                                           ` Eli Zaretskii
2020-03-22 15:48                                                                                           ` Pip Cet
2020-03-23 19:34                                                                                             ` Pip Cet
2020-03-17  8:40                                                                       ` Pieter van Oostrum
2020-03-17 15:33                                                                     ` Eli Zaretskii
2020-03-17 20:59                                                                       ` Paul Eggert
2020-03-18  6:17                                                                         ` Pip Cet
2020-03-18  9:22                                                                           ` Robert Pluim
2020-03-18 11:38                                                                             ` Pieter van Oostrum
2020-03-18 11:57                                                                               ` Paul Eggert
2020-03-18 14:08                                                                               ` Pip Cet
2020-03-19 19:17                                                                                 ` Pieter van Oostrum
2020-03-19 19:31                                                                                   ` Pip Cet
2020-03-19 21:30                                                                                     ` Pieter van Oostrum
2020-03-18 14:08                                                                           ` Eli Zaretskii
2020-03-16 18:36                                                                 ` Pieter van Oostrum
2020-03-13  7:58                                         ` Eli Zaretskii
2020-03-10 15:10                         ` Eli Zaretskii
2020-03-10 18:23                           ` Pieter van Oostrum
2020-03-11  8:22                         ` Paul Eggert
2022-04-30 12:38 ` Lars Ingebrigtsen
2022-05-29 13:19   ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAOqdjBemiVsiLULRhWZ3uKjTQzB0OazWMOzHQggPSqHf2KOvxQ@mail.gmail.com \
    --to=pipcet@gmail.com \
    --cc=39962@debbugs.gnu.org \
    --cc=eggert@cs.ucla.edu \
    --cc=eliz@gnu.org \
    --cc=pieter-l@vanoostrum.org \
    --cc=rms@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.