NEWS.stable: update
[gnulib.git] / lib / c-stack.c
index 4657548..7f0f488 100644 (file)
@@ -1,7 +1,6 @@
 /* Stack overflow handling.
 
-   Copyright (C) 2002, 2004, 2006, 2008, 2009, 2010 Free Software Foundation,
-   Inc.
+   Copyright (C) 2002, 2004, 2006, 2008-2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -53,6 +52,12 @@ typedef struct sigaltstack stack_t;
 #endif
 #ifndef SIGSTKSZ
 # define SIGSTKSZ 16384
+#elif HAVE_LIBSIGSEGV && SIGSTKSZ < 16384
+/* libsigsegv 2.6 through 2.8 have a bug where some architectures use
+   more than the Linux default of an 8k alternate stack when deciding
+   if a fault was caused by stack overflow.  */
+# undef SIGSTKSZ
+# define SIGSTKSZ 16384
 #endif
 
 #include <stdlib.h>
@@ -75,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
@@ -104,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)));
@@ -218,7 +229,7 @@ c_stack_action (void (*action) (int))
 # if STACK_DIRECTION
 #  define find_stack_direction(ptr) STACK_DIRECTION
 # else
-#  if ! SIGACTION_WORKS || HAVE_XSI_STACK_OVERFLOW_HEURISTIC
+#  if ! SIGINFO_WORKS || HAVE_XSI_STACK_OVERFLOW_HEURISTIC
 static int
 find_stack_direction (char const *addr)
 {
@@ -228,7 +239,7 @@ find_stack_direction (char const *addr)
 #  endif
 # endif
 
-# if SIGACTION_WORKS
+# if SIGINFO_WORKS
 
 /* Handle a segmentation violation and exit.  This function is
    async-signal-safe.  */
@@ -311,7 +322,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.  */