_Noreturn: new module
[gnulib.git] / lib / c-stack.c
index 72790d7..e48b97c 100644 (file)
@@ -80,9 +80,9 @@ typedef struct sigaltstack stack_t;
 #include "ignore-value.h"
 
 #if defined SA_ONSTACK && defined SA_SIGINFO
-# define SIGACTION_WORKS 1
+# define SIGINFO_WORKS 1
 #else
-# define SIGACTION_WORKS 0
+# define SIGINFO_WORKS 0
 # ifndef SA_ONSTACK
 #  define SA_ONSTACK 0
 # endif
@@ -109,6 +109,12 @@ static void
 die (int signo)
 {
   char const *message;
+#if !SIGINFO_WORKS && !HAVE_LIBSIGSEGV
+  /* We can't easily determine whether it is a stack overflow; so
+     assume that the rest of our program is perfect (!) and that
+     this segmentation violation is a stack overflow.  */
+  signo = 0;
+#endif /* !SIGINFO_WORKS && !HAVE_LIBSIGSEGV */
   segv_action (signo);
   message = signo ? program_error_message : stack_overflow_message;
   ignore_value (write (STDERR_FILENO, program_name, strlen (program_name)));
@@ -217,23 +223,7 @@ c_stack_action (void (*action) (int))
 
 #elif HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING
 
-/* Direction of the C runtime stack.  This function is
-   async-signal-safe.  */
-
-# if STACK_DIRECTION
-#  define find_stack_direction(ptr) STACK_DIRECTION
-# else
-#  if ! SIGACTION_WORKS || HAVE_XSI_STACK_OVERFLOW_HEURISTIC
-static int
-find_stack_direction (char const *addr)
-{
-  char dummy;
-  return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1;
-}
-#  endif
-# endif
-
-# if SIGACTION_WORKS
+# if SIGINFO_WORKS
 
 /* Handle a segmentation violation and exit.  This function is
    async-signal-safe.  */
@@ -260,17 +250,14 @@ segv_handler (int signo, siginfo_t *info,
   if (0 < info->si_code)
     {
       /* If the faulting address is within the stack, or within one
-         page of the stack end, assume that it is a stack
-         overflow.  */
+         page of the stack, assume that it is a stack overflow.  */
       ucontext_t const *user_context = context;
       char const *stack_base = user_context->uc_stack.ss_sp;
       size_t stack_size = user_context->uc_stack.ss_size;
       char const *faulting_address = info->si_addr;
-      size_t s = faulting_address - stack_base;
       size_t page_size = sysconf (_SC_PAGESIZE);
-      if (find_stack_direction (NULL) < 0)
-        s += page_size;
-      if (s < stack_size + page_size)
+      size_t s = faulting_address - stack_base + page_size;
+      if (s < stack_size + 2 * page_size)
         signo = 0;
 
 #   if DEBUG
@@ -316,7 +303,7 @@ c_stack_action (void (*action) (int))
 
   sigemptyset (&act.sa_mask);
 
-# if SIGACTION_WORKS
+# if SIGINFO_WORKS
   /* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
      this is not true on Solaris 8 at least.  It doesn't hurt to use
      SA_NODEFER here, so leave it in.  */