bug-gnulib@gnu.org mirror (unofficial)
 help / color / mirror / Atom feed
* c-stack: Catching stack overflow on most platforms without libsigsegv
@ 2021-05-17  1:49 Bruno Haible
  2021-05-18  6:00 ` Paul Eggert
  0 siblings, 1 reply; 3+ messages in thread
From: Bruno Haible @ 2021-05-17  1:49 UTC (permalink / raw)
  To: Paul Eggert; +Cc: bug-gnulib

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

Hi Paul,

Here is a proposed patch to make use of the new 'sigsegv' module
(quasi a mini libsigsegv without library dependencies), so that

  * On most systems, catching stack overflow becomes possible without
    link dependencies. (The only notable exceptions, where GNU libsigsegv
    are still needed, are native Windows and older versions of various
    OSes: Mac OS X 10.5, probably NetBSD 7, and such.)

  * In particular, glibc systems are no longer left behind, compared to
    Solaris.

I have verified this patch by building and m4 snapshot with it on
  - glibc
  - newest glibc > 2.33 snapshot
  - Solaris 11/sparc64
  - Cygwin
  - Minix (just to test a case where catching stack overflow is not supported).

And I had tested the 'sigsegv' module on ca. 58 platforms, from IRIX 6.5 to
musl libc on Linux/s390x.

Bruno


[-- Attachment #2: 0001-c-stack-Catching-stack-overflow-on-most-platforms-wi.patch --]
[-- Type: text/x-patch, Size: 24856 bytes --]

From 7832467d9d79753185664f702c50fb91dd5311eb Mon Sep 17 00:00:00 2001
From: Bruno Haible <bruno@clisp.org>
Date: Mon, 17 May 2021 03:36:35 +0200
Subject: [PATCH] c-stack: Catching stack overflow on most platforms without
 libsigsegv.

* lib/c-stack.c: Remove all Solaris-specific code. Include <sigsegv.h>
always.
* m4/c-stack.m4: Remove all Solaris-specific code.
(gl_C_STACK): Test $with_libsigsegv from module 'sigsegv'.
* modules/c-stack (Files): Remove m4/libsigsegv.m4.
(Depends-on): Add sigsegv. Remove havelib, intprops, inttypes, mempcpy,
sigaction, stdbool.
---
 ChangeLog       |  11 ++
 lib/c-stack.c   | 188 +-------------------------
 m4/c-stack.m4   | 413 ++------------------------------------------------------
 modules/c-stack |   8 +-
 4 files changed, 27 insertions(+), 593 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e3ab1ff..ae60171 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2021-05-16  Bruno Haible  <bruno@clisp.org>
 
+	c-stack: Catching stack overflow on most platforms without libsigsegv.
+	* lib/c-stack.c: Remove all Solaris-specific code. Include <sigsegv.h>
+	always.
+	* m4/c-stack.m4: Remove all Solaris-specific code.
+	(gl_C_STACK): Test $with_libsigsegv from module 'sigsegv'.
+	* modules/c-stack (Files): Remove m4/libsigsegv.m4.
+	(Depends-on): Add sigsegv. Remove havelib, intprops, inttypes, mempcpy,
+	sigaction, stdbool.
+
+2021-05-16  Bruno Haible  <bruno@clisp.org>
+
 	sigsegv, c-stack: Avoid compilation error with glibc >= 2.34.
 	* lib/sigsegv.in.h (SIGSTKSZ): On glibc systems, redefine to a suitable
 	constant.
diff --git a/lib/c-stack.c b/lib/c-stack.c
index 3e8cd25..1965bdd 100644
--- a/lib/c-stack.c
+++ b/lib/c-stack.c
@@ -39,59 +39,27 @@
 
 #include <errno.h>
 #include <inttypes.h>
-
 #include <signal.h>
-#if ! HAVE_STACK_T && ! defined stack_t
-typedef struct sigaltstack stack_t;
-#endif
-
-#include <stdbool.h>
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
-
-/* Pre-2008 POSIX declared ucontext_t in ucontext.h instead of signal.h.  */
-#if HAVE_UCONTEXT_H
-# include <ucontext.h>
-#endif
-
 #include <unistd.h>
 
 #if DEBUG
 # include <stdio.h>
 #endif
 
+#include <sigsegv.h>
+
+#include "exitfail.h"
+#include "getprogname.h"
 #include "idx.h"
+#include "ignore-value.h"
 
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-#if HAVE_LIBSIGSEGV
-# include <sigsegv.h>
-#endif
-
-/* Use libsigsegv only if needed; kernels like Solaris can detect
-   stack overflow without the overhead of an external library.
-   However, BOGUS_SI_ADDR_ON_STACK_OVERFLOW indicates a buggy
-   Solaris kernel, and a too-small LIBSIGSEGV_VERSION indicates a
-   libsigsegv so old that it does not work around the bug.  */
-#define USE_LIBSIGSEGV (!HAVE_XSI_STACK_OVERFLOW_HEURISTIC && HAVE_LIBSIGSEGV \
-                        && ! (BOGUS_SI_ADDR_UPON_STACK_OVERFLOW \
-                              && LIBSIGSEGV_VERSION < 0x020D))
-
-#include "exitfail.h"
-#include "ignore-value.h"
-#include "intprops.h"
-#include "getprogname.h"
-
-#if defined SA_ONSTACK && defined SA_SIGINFO
-# define SIGINFO_WORKS 1
-#else
-# define SIGINFO_WORKS 0
-# ifndef SA_ONSTACK
-#  define SA_ONSTACK 0
-# endif
-#endif
+#if HAVE_STACK_OVERFLOW_RECOVERY
 
 /* Storage for the alternate signal stack.
    64 KiB is not too large for Gnulib-using apps, and is large enough
@@ -113,9 +81,6 @@ static _GL_ASYNC_SAFE void (* volatile segv_action) (int);
 static char const * volatile program_error_message;
 static char const * volatile stack_overflow_message;
 
-#if (USE_LIBSIGSEGV                                           \
-     || (HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING))
-
 /* Output an error message, then exit with status EXIT_FAILURE if it
    appears to have been a stack overflow, or with a core dump
    otherwise.  This function is async-signal-safe.  */
@@ -125,12 +90,6 @@ static char const * volatile progname;
 static _GL_ASYNC_SAFE _Noreturn void
 die (int signo)
 {
-# if !SIGINFO_WORKS && !USE_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
   segv_action (signo);
   char const *message = signo ? program_error_message : stack_overflow_message;
 
@@ -171,10 +130,6 @@ null_action (int signo _GL_UNUSED)
 {
 }
 
-#endif /* SIGALTSTACK || LIBSIGSEGV */
-
-#if USE_LIBSIGSEGV
-
 /* Pacify GCC 9.3.1, which otherwise would complain about segv_handler.  */
 # if 4 < __GNUC__ + (6 <= __GNUC_MINOR__)
 #  pragma GCC diagnostic ignored "-Wsuggest-attribute=pure"
@@ -247,136 +202,7 @@ c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
   return 0;
 }
 
-#elif HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING
-
-# if SIGINFO_WORKS
-
-static size_t volatile page_size;
-
-/* Handle a segmentation violation and exit.  This function is
-   async-signal-safe.  */
-
-static _GL_ASYNC_SAFE _Noreturn void
-segv_handler (int signo, siginfo_t *info, void *context _GL_UNUSED)
-{
-  /* Clear SIGNO if it seems to have been a stack overflow.  */
-
-  /* If si_code is nonpositive, something like raise (SIGSEGV) occurred
-     so it cannot be a stack overflow.  */
-  bool cannot_be_stack_overflow = info->si_code <= 0;
-
-  /* An unaligned address cannot be a stack overflow.  */
-#  if FAULT_YIELDS_SIGBUS
-  cannot_be_stack_overflow |= signo == SIGBUS && info->si_code == BUS_ADRALN;
-#  endif
-
-  /* If we can't easily determine that it is not a stack overflow,
-     assume that the rest of our program is perfect (!) and that
-     this segmentation violation is a stack overflow.
-
-     Note that although both Linux and Solaris provide
-     sigaltstack, SA_ONSTACK, and SA_SIGINFO, currently only
-     Solaris satisfies the XSI heuristic.  This is because
-     Solaris populates uc_stack with the details of the
-     interrupted stack, while Linux populates it with the details
-     of the current stack.  */
-  if (!cannot_be_stack_overflow)
-    {
-#  if BOGUS_SI_ADDR_UPON_STACK_OVERFLOW
-      signo = 0;
-#  else
-      /* If the faulting address is within the stack, or within one
-         page of the stack, assume that it is a stack overflow.  */
-      uintptr_t faulting_address = (uintptr_t) info->si_addr;
-
-      /* On all platforms we know of, the first page is not in the
-         stack to catch null pointer dereferening.  However, all other
-         pages might be in the stack.  */
-      void *stack_base = (void *) (uintptr_t) page_size;
-      uintptr_t stack_size = 0; stack_size -= page_size;
-#   if HAVE_XSI_STACK_OVERFLOW_HEURISTIC
-      /* Tighten the stack bounds via the XSI heuristic.  */
-      ucontext_t const *user_context = context;
-      stack_base = user_context->uc_stack.ss_sp;
-      stack_size = user_context->uc_stack.ss_size;
-#   endif
-      uintptr_t base = (uintptr_t) stack_base,
-        lo = (INT_SUBTRACT_WRAPV (base, page_size, &lo) || lo < page_size
-              ? page_size : lo),
-        hi = ((INT_ADD_WRAPV (base, stack_size, &hi)
-               || INT_ADD_WRAPV (hi, page_size - 1, &hi))
-              ? UINTPTR_MAX : hi);
-      if (lo <= faulting_address && faulting_address <= hi)
-        signo = 0;
-#  endif
-
-#  if DEBUG
-      {
-        char buf[1024];
-        ignore_value (write (STDERR_FILENO, buf,
-                             sprintf (buf,
-                                      ("segv_handler code=%d fault=%p base=%p"
-                                       " size=0x%zx page=0x%zx signo=%d\n"),
-                                      info->si_code, info->si_addr, stack_base,
-                                      stack_size, page_size, signo)));
-      }
-#  endif
-    }
-
-  die (signo);
-}
-# endif
-
-int
-c_stack_action (_GL_ASYNC_SAFE void (*action) (int))
-{
-  stack_t st;
-  st.ss_flags = 0;
-  st.ss_sp = alternate_signal_stack;
-  st.ss_size = sizeof alternate_signal_stack;
-# if SIGALTSTACK_SS_REVERSED
-  /* Irix mistakenly treats ss_sp as the upper bound, rather than
-     lower bound, of the alternate stack.  */
-  st.ss_size -= sizeof (void *);
-  char *ss_sp = st.ss_sp;
-  st.ss_sp = ss_sp + st.ss_size;
-# endif
-  int r = sigaltstack (&st, NULL);
-  if (r != 0)
-    return r;
-
-  segv_action = action ? action : null_action;
-  program_error_message = _("program error");
-  stack_overflow_message = _("stack overflow");
-  progname = getprogname ();
-
-# if SIGINFO_WORKS
-  page_size = sysconf (_SC_PAGESIZE);
-# endif
-
-  struct sigaction act;
-  sigemptyset (&act.sa_mask);
-
-# 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.  */
-  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
-  act.sa_sigaction = segv_handler;
-# else
-  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
-  act.sa_handler = die;
-# endif
-
-# if FAULT_YIELDS_SIGBUS
-  if (sigaction (SIGBUS, &act, NULL) < 0)
-    return -1;
-# endif
-  return sigaction (SIGSEGV, &act, NULL);
-}
-
-#else /* ! (USE_LIBSIGSEGV
-            || (HAVE_DECL_SIGALTSTACK && HAVE_STACK_OVERFLOW_HANDLING)) */
+#else /* !HAVE_STACK_OVERFLOW_RECOVERY */
 
 int
 c_stack_action (_GL_ASYNC_SAFE void (*action) (int)  _GL_UNUSED)
diff --git a/m4/c-stack.m4 b/m4/c-stack.m4
index 3131dd5..7cccb06 100644
--- a/m4/c-stack.m4
+++ b/m4/c-stack.m4
@@ -7,412 +7,15 @@
 
 # Written by Paul Eggert.
 
-# serial 22
-
-AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
-  [
-   AC_REQUIRE([AC_CANONICAL_HOST])
-   AC_CHECK_FUNCS_ONCE([setrlimit])
-   AC_CHECK_HEADERS_ONCE([ucontext.h])
-
-   dnl List of signals that are sent when an invalid virtual memory address
-   dnl is accessed, or when the stack overflows.
-   dnl Either { SIGSEGV } or { SIGSEGV, SIGBUS }.
-   case "$host_os" in
-     sunos4* | freebsd* | dragonfly* | midnightbsd* | openbsd* | mirbsd* | netbsd* | kfreebsd* | knetbsd*) # BSD systems
-       FAULT_YIELDS_SIGBUS=1 ;;
-     hpux*) # HP-UX
-       FAULT_YIELDS_SIGBUS=1 ;;
-     macos* | darwin*) # Mac OS X
-       FAULT_YIELDS_SIGBUS=1 ;;
-     gnu*) # Hurd
-       FAULT_YIELDS_SIGBUS=1 ;;
-     *)
-       FAULT_YIELDS_SIGBUS=0 ;;
-   esac
-   AC_DEFINE_UNQUOTED([FAULT_YIELDS_SIGBUS], [$FAULT_YIELDS_SIGBUS],
-     [Define to 1 if an invalid memory address access may yield a SIGBUS.])
-
-   AC_CACHE_CHECK([for working C stack overflow detection],
-     [gl_cv_sys_stack_overflow_works],
-     [AC_RUN_IFELSE([AC_LANG_SOURCE(
-           [[
-            #include <unistd.h>
-            #include <signal.h>
-            #if HAVE_SETRLIMIT
-            # include <sys/types.h>
-            # include <sys/time.h>
-            # include <sys/resource.h>
-            #endif
-            /* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is
-               no longer a compile-time constant.  But we need a simple
-               constant here.  */
-            #if __GLIBC__ >= 2
-            # undef SIGSTKSZ
-            # if defined __ia64__
-            #  define SIGSTKSZ 262144
-            # else
-            #  define SIGSTKSZ 16384
-            # endif
-            #endif
-            #ifndef SIGSTKSZ
-            # define SIGSTKSZ 16384
-            #endif
-
-            static union
-            {
-              char buffer[2 * SIGSTKSZ];
-              long double ld;
-              long u;
-              void *p;
-            } alternate_signal_stack;
-
-            static void
-            segv_handler (int signo)
-            {
-              _exit (0);
-            }
-
-            static int
-            c_stack_action ()
-            {
-              stack_t st;
-              struct sigaction act;
-              int r;
-
-              st.ss_flags = 0;
-              /* Use the midpoint to avoid Irix sigaltstack bug.  */
-              st.ss_sp = alternate_signal_stack.buffer + SIGSTKSZ;
-              st.ss_size = SIGSTKSZ;
-              r = sigaltstack (&st, 0);
-              if (r != 0)
-                return 1;
-
-              sigemptyset (&act.sa_mask);
-              act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
-              act.sa_handler = segv_handler;
-              #if FAULT_YIELDS_SIGBUS
-              if (sigaction (SIGBUS, &act, 0) < 0)
-                return 2;
-              #endif
-              if (sigaction (SIGSEGV, &act, 0) < 0)
-                return 3;
-              return 0;
-            }
-            static volatile int *
-            recurse_1 (volatile int n, volatile int *p)
-            {
-              if (n >= 0)
-                *recurse_1 (n + 1, p) += n;
-              return p;
-            }
-            static int
-            recurse (volatile int n)
-            {
-              int sum = 0;
-              return *recurse_1 (n, &sum);
-            }
-            int
-            main ()
-            {
-              int result;
-              #if HAVE_SETRLIMIT && defined RLIMIT_STACK
-              /* Before starting the endless recursion, try to be friendly
-                 to the user's machine.  On some Linux 2.2.x systems, there
-                 is no stack limit for user processes at all.  We don't want
-                 to kill such systems.  */
-              struct rlimit rl;
-              rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
-              setrlimit (RLIMIT_STACK, &rl);
-              #endif
-
-              result = c_stack_action ();
-              if (result != 0)
-                return result;
-              return recurse (0);
-            }
-           ]])],
-        [gl_cv_sys_stack_overflow_works=yes],
-        [gl_cv_sys_stack_overflow_works=no],
-        [case "$host_os" in
-                   # Guess no on native Windows.
-           mingw*) gl_cv_sys_stack_overflow_works="guessing no" ;;
-           *)      gl_cv_sys_stack_overflow_works=cross-compiling ;;
-         esac
-        ])
-     ])
-
-  if test "$gl_cv_sys_stack_overflow_works" = yes; then
-   AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], [1],
-     [Define to 1 if extending the stack slightly past the limit causes
-      a SIGSEGV which can be handled on an alternate stack established
-      with sigaltstack.])
-
-    dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
-    dnl of the memory block designated as an alternate stack. But IRIX 5.3
-    dnl interprets it as the highest address!
-    AC_CACHE_CHECK([for correct stack_t interpretation],
-      [gl_cv_sigaltstack_low_base], [
-      AC_RUN_IFELSE([
-        AC_LANG_SOURCE([[
-#include <stdlib.h>
-#include <signal.h>
-#if HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif
-/* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is no longer a
-   compile-time constant.  But we need a simple constant here.  */
-#if __GLIBC__ >= 2
-# undef SIGSTKSZ
-# if defined __ia64__
-#  define SIGSTKSZ 262144
-# else
-#  define SIGSTKSZ 16384
-# endif
-#endif
-#ifndef SIGSTKSZ
-# define SIGSTKSZ 16384
-#endif
-volatile char *stack_lower_bound;
-volatile char *stack_upper_bound;
-static void check_stack_location (volatile char *addr)
-{
-  if (addr >= stack_lower_bound && addr <= stack_upper_bound)
-    exit (0);
-  else
-    exit (1);
-}
-static void stackoverflow_handler (int sig)
-{
-  char dummy;
-  check_stack_location (&dummy);
-}
-int main ()
-{
-  char mystack[2 * SIGSTKSZ];
-  stack_t altstack;
-  struct sigaction action;
-  /* Install the alternate stack.  */
-  altstack.ss_sp = mystack + SIGSTKSZ;
-  altstack.ss_size = SIGSTKSZ;
-  stack_lower_bound = (char *) altstack.ss_sp;
-  stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
-  altstack.ss_flags = 0; /* no SS_DISABLE */
-  if (sigaltstack (&altstack, NULL) < 0)
-    exit (2);
-  /* Install the SIGSEGV handler.  */
-  sigemptyset (&action.sa_mask);
-  action.sa_handler = &stackoverflow_handler;
-  action.sa_flags = SA_ONSTACK;
-  if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
-    exit(3);
-  /* Provoke a SIGSEGV.  */
-  raise (SIGSEGV);
-  exit (4);
-}]])],
-      [gl_cv_sigaltstack_low_base=yes],
-      [gl_cv_sigaltstack_low_base=no],
-      [gl_cv_sigaltstack_low_base=cross-compiling])])
-   if test "$gl_cv_sigaltstack_low_base" = no; then
-      AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
-        [Define if sigaltstack() interprets the stack_t.ss_sp field
-         incorrectly, as the highest address of the alternate stack range
-         rather than as the lowest address.])
-    fi
-
-   case $host_os--$host_cpu in
-     solaris2.11--sparc*)
-        AC_DEFINE([BOGUS_SI_ADDR_UPON_STACK_OVERFLOW], [1],
-          [Define to 1 if the faulting address (info->si_addr)
-           might be incorrect on stack overflow.])
-        gl_bogus_si_addr=1;;
-     *) gl_bogus_si_addr=0;;
-   esac
-
-   AC_CACHE_CHECK([for precise C stack overflow detection],
-     [gl_cv_sys_xsi_stack_overflow_heuristic],
-     [dnl On Linux/sparc64 (both in 32-bit and 64-bit mode), it would be wrong
-      dnl to set HAVE_XSI_STACK_OVERFLOW_HEURISTIC to 1, because the third
-      dnl argument passed to the segv_handler is a 'struct sigcontext *', not
-      dnl an 'ucontext_t *'.  It would lead to a failure of test-c-stack2.sh.
-      dnl If $gl_bogus_si_addr is 1, there is no point to the heuristic.
-      case "${host_os}--${host_cpu}--${gl_bogus_si_addr}" in
-        linux*--sparc* | *--1)
-          gl_cv_sys_xsi_stack_overflow_heuristic=no
-          ;;
-        *)
-          AC_RUN_IFELSE(
-            [AC_LANG_SOURCE(
-               [[
-                #include <unistd.h>
-                #include <signal.h>
-                #if HAVE_UCONTEXT_H
-                # include <ucontext.h>
-                #endif
-                #if HAVE_SETRLIMIT
-                # include <sys/types.h>
-                # include <sys/time.h>
-                # include <sys/resource.h>
-                #endif
-                /* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is
-                   no longer a compile-time constant.  But we need a simple
-                   constant here.  */
-                #if __GLIBC__ >= 2
-                # undef SIGSTKSZ
-                # if defined __ia64__
-                #  define SIGSTKSZ 262144
-                # else
-                #  define SIGSTKSZ 16384
-                # endif
-                #endif
-                #ifndef SIGSTKSZ
-                # define SIGSTKSZ 16384
-                #endif
-
-                static union
-                {
-                  char buffer[2 * SIGSTKSZ];
-                  long double ld;
-                  long u;
-                  void *p;
-                } alternate_signal_stack;
-
-                #if STACK_DIRECTION
-                # define find_stack_direction(ptr) STACK_DIRECTION
-                #else
-                static int
-                find_stack_direction (char const *addr)
-                {
-                  char dummy;
-                  return (! addr ? find_stack_direction (&dummy)
-                          : addr < &dummy ? 1 : -1);
-                }
-                #endif
-
-                static void
-                segv_handler (int signo, siginfo_t *info, void *context)
-                {
-                  if (0 < info->si_code)
-                    {
-                      /* For XSI heuristics to work, we need uc_stack to
-                         describe the interrupted stack (as on Solaris), and
-                         not the currently executing stack (as on Linux).  */
-                      ucontext_t const *user_context = context;
-                      char const *stack_min = 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_min;
-                      size_t page_size = sysconf (_SC_PAGESIZE);
-                      if (find_stack_direction (0) < 0)
-                        s += page_size;
-                      if (s < stack_size + page_size)
-                        _exit (0);
-                      _exit (4);
-                    }
-                  _exit (5);
-                }
-
-                static int
-                c_stack_action ()
-                {
-                  stack_t st;
-                  struct sigaction act;
-                  int r;
-
-                  st.ss_flags = 0;
-                  /* Use the midpoint to avoid Irix sigaltstack bug.  */
-                  st.ss_sp = alternate_signal_stack.buffer + SIGSTKSZ;
-                  st.ss_size = SIGSTKSZ;
-                  r = sigaltstack (&st, 0);
-                  if (r != 0)
-                    return 1;
-
-                  sigemptyset (&act.sa_mask);
-                  act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
-                  act.sa_sigaction = segv_handler;
-                  #if FAULT_YIELDS_SIGBUS
-                  if (sigaction (SIGBUS, &act, 0) < 0)
-                    return 2;
-                  #endif
-                  if (sigaction (SIGSEGV, &act, 0) < 0)
-                    return 3;
-                  return 0;
-                }
-                static volatile int *
-                recurse_1 (volatile int n, volatile int *p)
-                {
-                  if (n >= 0)
-                    *recurse_1 (n + 1, p) += n;
-                  return p;
-                }
-                static int
-                recurse (volatile int n)
-                {
-                  int sum = 0;
-                  return *recurse_1 (n, &sum);
-                }
-                int
-                main ()
-                {
-                  int result;
-                  #if HAVE_SETRLIMIT && defined RLIMIT_STACK
-                  /* Before starting the endless recursion, try to be friendly
-                     to the user's machine.  On some Linux 2.2.x systems, there
-                     is no stack limit for user processes at all.  We don't want
-                     to kill such systems.  */
-                  struct rlimit rl;
-                  rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
-                  setrlimit (RLIMIT_STACK, &rl);
-                  #endif
-
-                  result = c_stack_action ();
-                  if (result != 0)
-                    return result;
-                  return recurse (0);
-                }
-               ]])],
-            [gl_cv_sys_xsi_stack_overflow_heuristic=yes],
-            [gl_cv_sys_xsi_stack_overflow_heuristic=no],
-            [gl_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])
-          ;;
-      esac
-     ])
-
-   if test "$gl_cv_sys_xsi_stack_overflow_heuristic" = yes; then
-     AC_DEFINE([HAVE_XSI_STACK_OVERFLOW_HEURISTIC], [1],
-       [Define to 1 if extending the stack slightly past the limit causes
-        a SIGSEGV, and an alternate stack can be established with sigaltstack,
-        and the signal handler is passed a context that specifies the
-        run time stack.  This behavior is defined by POSIX 1003.1-2001
-        with the X/Open System Interface (XSI) option
-        and is a standardized way to implement a SEGV-based stack
-        overflow detection heuristic.])
-   fi
-  fi])
-
-
-AC_DEFUN([gl_PREREQ_C_STACK],
-  [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
-
-   AC_CHECK_FUNCS_ONCE([sigaltstack])
-   AC_CHECK_DECLS([sigaltstack], , , [[#include <signal.h>]])
-
-   AC_CHECK_HEADERS_ONCE([ucontext.h])
-
-   AC_CHECK_TYPES([stack_t], , , [[#include <signal.h>]])
-
-   dnl c-stack does not need -lsigsegv if the system has XSI heuristics.
-   if test "$gl_cv_sys_xsi_stack_overflow_heuristic" != yes; then
-     gl_LIBSIGSEGV
-     if test "$gl_cv_lib_sigsegv" = yes; then
-       AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
-       AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
-     fi
-   fi
-])
+# serial 23
 
 AC_DEFUN([gl_C_STACK],
 [
-  dnl Prerequisites of lib/c-stack.c.
-  gl_PREREQ_C_STACK
+  dnl 'c-stack' needs -lsigsegv if and only if the 'sigsegv' module needs it.
+  if test "$with_libsigsegv" = yes; then
+    if test "$gl_cv_lib_sigsegv" = yes; then
+      AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
+      AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
+    fi
+  fi
 ])
diff --git a/modules/c-stack b/modules/c-stack
index 4c80f31..32a4120 100644
--- a/modules/c-stack
+++ b/modules/c-stack
@@ -5,7 +5,6 @@ Files:
 lib/c-stack.h
 lib/c-stack.c
 m4/c-stack.m4
-m4/libsigsegv.m4
 
 Depends-on:
 c99
@@ -13,15 +12,10 @@ errno
 exitfail
 getprogname
 gettext-h
-havelib
 idx
 ignore-value
-intprops
-inttypes
-mempcpy
 raise
-sigaction
-stdbool
+sigsegv
 stddef
 unistd
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: c-stack: Catching stack overflow on most platforms without libsigsegv
  2021-05-17  1:49 c-stack: Catching stack overflow on most platforms without libsigsegv Bruno Haible
@ 2021-05-18  6:00 ` Paul Eggert
  2021-05-18 17:40   ` Bruno Haible
  0 siblings, 1 reply; 3+ messages in thread
From: Paul Eggert @ 2021-05-18  6:00 UTC (permalink / raw)
  To: Bruno Haible; +Cc: bug-gnulib

That looks good, thanks. And thanks for all the work with libsigsegv.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: c-stack: Catching stack overflow on most platforms without libsigsegv
  2021-05-18  6:00 ` Paul Eggert
@ 2021-05-18 17:40   ` Bruno Haible
  0 siblings, 0 replies; 3+ messages in thread
From: Bruno Haible @ 2021-05-18 17:40 UTC (permalink / raw)
  To: Paul Eggert; +Cc: bug-gnulib

Paul Eggert wrote:
> That looks good, thanks. And thanks for all the work with libsigsegv.

Pushed.

Bruno




^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-05-18 17:41 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-17  1:49 c-stack: Catching stack overflow on most platforms without libsigsegv Bruno Haible
2021-05-18  6:00 ` Paul Eggert
2021-05-18 17:40   ` Bruno Haible

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).