X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=m4%2Fc-stack.m4;h=4f0300bf7dc5ffda646fb524fdd71b47340e4634;hb=77041ebc885b2af4e2d48fd49cf5529759351076;hp=9511e8f965708608bbdb05e94c65fabc1955afa3;hpb=f49d92a13f08f505fe855afce40f173a6e7c922c;p=gnulib.git diff --git a/m4/c-stack.m4 b/m4/c-stack.m4 index 9511e8f96..4f0300bf7 100644 --- a/m4/c-stack.m4 +++ b/m4/c-stack.m4 @@ -1,41 +1,120 @@ # Check prerequisites for compiling lib/c-stack.c. -# Copyright (C) 2002, 2003, 2004 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 -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Copyright (C) 2002, 2003, 2004, 2008 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. # Written by Paul Eggert. +# serial 6 + AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], [# for STACK_DIRECTION AC_REQUIRE([AC_FUNC_ALLOCA]) - AC_CHECK_FUNCS(setrlimit) + AC_CHECK_FUNCS_ONCE([setrlimit]) + AC_CHECK_HEADERS_ONCE([ucontext.h]) AC_CACHE_CHECK([for working C stack overflow detection], + [ac_cv_sys_stack_overflow_works], + [AC_TRY_RUN( + [ + #include + #include + #if HAVE_SETRLIMIT + # include + # include + # include + #endif + #ifndef SIGSTKSZ + # define SIGSTKSZ 16384 + #endif + + static union + { + char buffer[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; + st.ss_sp = alternate_signal_stack.buffer; + st.ss_size = sizeof alternate_signal_stack.buffer; + r = sigaltstack (&st, 0); + if (r != 0) + return r; + + sigemptyset (&act.sa_mask); + act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND; + act.sa_handler = segv_handler; + return sigaction (SIGSEGV, &act, 0); + } + + static int + recurse (char *p) + { + char array[500]; + array[0] = 1; + return *p + recurse (array); + } + + int + main () + { + #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 + + return c_stack_action () || recurse ("\1"); + } + ], + [ac_cv_sys_stack_overflow_works=yes], + [ac_cv_sys_stack_overflow_works=no], + [ac_cv_sys_stack_overflow_works=cross-compiling])]) + + if test $ac_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.]) + + AC_CACHE_CHECK([for precise C stack overflow detection], ac_cv_sys_xsi_stack_overflow_heuristic, [AC_TRY_RUN( [ #include #include - #include + #if HAVE_UCONTEXT_H + # include + #endif #if HAVE_SETRLIMIT # include # include # include #endif + #ifndef SIGSTKSZ + # define SIGSTKSZ 16384 + #endif static union { @@ -62,6 +141,9 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], { 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; @@ -78,7 +160,7 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], } static int - c_stack_action (void) + c_stack_action () { stack_t st; struct sigaction act; @@ -106,7 +188,7 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], } int - main (void) + main () { #if HAVE_SETRLIMIT && defined RLIMIT_STACK /* Before starting the endless recursion, try to be friendly @@ -118,8 +200,7 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], setrlimit (RLIMIT_STACK, &rl); #endif - c_stack_action (); - return recurse ("\1"); + return c_stack_action () || recurse ("\1"); } ], [ac_cv_sys_xsi_stack_overflow_heuristic=yes], @@ -132,28 +213,34 @@ AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC], 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 + with the X/Open System Interface (XSI) option and is a standardized way to implement a SEGV-based stack - overflow detection heuristic.]) - fi]) + overflow detection heuristic.]) + fi + fi]) AC_DEFUN([gl_PREREQ_C_STACK], [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC]) + AC_REQUIRE([gl_LIBSIGSEGV]) # for STACK_DIRECTION AC_REQUIRE([AC_FUNC_ALLOCA]) - AC_CHECK_FUNCS(getcontext sigaltstack) - AC_CHECK_DECLS([getcontext], , , [#include ]) + AC_CHECK_FUNCS_ONCE([sigaltstack]) AC_CHECK_DECLS([sigaltstack], , , [#include ]) - AC_CHECK_HEADERS_ONCE(sys/time.h unistd.h) - AC_CHECK_HEADERS(sys/resource.h ucontext.h) + AC_CHECK_HEADERS_ONCE([unistd.h ucontext.h]) - AC_CHECK_MEMBERS([struct sigaction.sa_sigaction], , , [#include ]) + AC_CHECK_TYPES([stack_t], , , [#include ]) - AC_CHECK_TYPES([stack_t], , , [#include ])]) + dnl c-stack does not need -lsigsegv if the system has XSI heuristics. + if test "$gl_cv_lib_sigsegv" = yes \ + && test $"ac_cv_sys_xsi_stack_overflow_heuristic" != yes ; then + AC_SUBST([LIBCSTACK], [$LIBSIGSEGV]) + AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV]) + fi +]) AC_DEFUN([gl_C_STACK], [