]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix some glitches in previous change.
authorDmitry Antipov <dmantipov@yandex.ru>
Wed, 27 Aug 2014 04:15:20 +0000 (08:15 +0400)
committerDmitry Antipov <dmantipov@yandex.ru>
Wed, 27 Aug 2014 04:15:20 +0000 (08:15 +0400)
* sysdep.c (stack_direction): Replace stack_grows_down
to simplify calculation of stack boundaries.
(handle_sigsegv): Check whether we really crash somewhere near
to stack boundary, and handle fatal signal as usual if not.
(init_sigsegv): Adjust accordingly.

src/ChangeLog
src/keyboard.c
src/sysdep.c

index 44b0bcf0b789d6997311f4d47f3287cb51ad9c9b..8bc6c1069ad0367c066f4effc2af3e6719d37c02 100644 (file)
@@ -1,3 +1,12 @@
+2014-08-27  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       Fix some glitches in previous change.
+       * sysdep.c (stack_direction): Replace stack_grows_down
+       to simplify calculation of stack boundaries.
+       (handle_sigsegv): Check whether we really crash somewhere near
+       to stack boundary, and handle fatal signal as usual if not.
+       (init_sigsegv): Adjust accordingly.
+
 2014-08-26  Dmitry Antipov  <dmantipov@yandex.ru>
 
        Handle C stack overflow caused by too nested Lisp evaluation.
index ed00b38a7dbbe45c84626d14413b1111dd2f9266..79b3aec3304bd118bd02c6d62725e20279e0e602 100644 (file)
@@ -11028,7 +11028,7 @@ syms_of_keyboard (void)
 #ifdef HAVE_STACK_OVERFLOW_HANDLING
   recover_top_level_message
     = build_pure_c_string ("Re-entering top level after C stack overflow");
-#endif  
+#endif
   DEFVAR_LISP ("top-level-message", Vtop_level_message,
               doc: /* Message displayed by `normal-top-level'.  */);
   Vtop_level_message = regular_top_level_message;
index c0d651b296a0844ae8985c46bd5bde370b58cc89..7b93cb93b85678a11d7d191fccea61ba3dbb5536 100644 (file)
@@ -1720,9 +1720,9 @@ handle_arith_signal (int sig)
 
 #ifdef HAVE_STACK_OVERFLOW_HANDLING
 
-/* True if stack grows down as expected on most OS/ABI variants.  */
+/* -1 if stack grows down as expected on most OS/ABI variants, 1 otherwise.  */
 
-static bool stack_grows_down;
+static int stack_direction;
 
 /* Alternate stack used by SIGSEGV handler below.  */
 
@@ -1741,17 +1741,25 @@ handle_sigsegv (int sig, siginfo_t *siginfo, void *arg)
 
       if (!getrlimit (RLIMIT_STACK, &rlim))
        {
-         enum { STACK_EXTRA = 16 * 1024 };
-         char *fault_addr = (char *) siginfo->si_addr;
-         unsigned long used = (stack_grows_down
-                               ? stack_bottom - fault_addr
-                               : fault_addr - stack_bottom);
-
-         if (used + STACK_EXTRA > rlim.rlim_cur)
-           /* Most likely this is it.  */
+         enum { STACK_DANGER_ZONE = 16 * 1024 };
+         char *beg, *end, *addr;
+
+         beg = stack_bottom;
+         end = stack_bottom + stack_direction * rlim.rlim_cur;
+         if (beg > end)
+           addr = beg, beg = end, end = addr;
+         addr = (char *) siginfo->si_addr;
+         /* If we're somewhere on stack and too close to
+            one of its boundaries, most likely this is it.  */
+         if (beg < addr && addr < end
+             && (addr - beg < STACK_DANGER_ZONE
+                 || end - addr < STACK_DANGER_ZONE))
            siglongjmp (return_to_command_loop, 1);
        }
     }
+
+  /* Otherwise we can't do anything with this.  */
+  deliver_fatal_thread_signal (sig);
 }
 
 /* Return true if we have successfully set up SIGSEGV handler on alternate
@@ -1763,7 +1771,7 @@ init_sigsegv (void)
   struct sigaction sa;
   stack_t ss;
 
-  stack_grows_down = ((char *) &ss < stack_bottom);
+  stack_direction = ((char *) &ss < stack_bottom) ? -1 : 1;
 
   ss.ss_sp = sigsegv_stack;
   ss.ss_size = sizeof (sigsegv_stack);