1 # Check prerequisites for compiling lib/c-stack.c.
3 # Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
4 # This file is free software; the Free Software Foundation
5 # gives unlimited permission to copy and/or distribute it,
6 # with or without modifications, as long as this notice is preserved.
8 # Written by Paul Eggert.
10 AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
11 [# for STACK_DIRECTION
12 AC_REQUIRE([AC_FUNC_ALLOCA])
13 AC_CHECK_FUNCS(setrlimit)
15 AC_CACHE_CHECK([for working C stack overflow detection],
16 ac_cv_sys_xsi_stack_overflow_heuristic,
23 # include <sys/types.h>
24 # include <sys/time.h>
25 # include <sys/resource.h>
30 char buffer[SIGSTKSZ];
34 } alternate_signal_stack;
37 # define find_stack_direction(ptr) STACK_DIRECTION
40 find_stack_direction (char const *addr)
43 return (! addr ? find_stack_direction (&dummy)
44 : addr < &dummy ? 1 : -1);
49 segv_handler (int signo, siginfo_t *info, void *context)
51 if (0 < info->si_code)
53 ucontext_t const *user_context = context;
54 char const *stack_min = user_context->uc_stack.ss_sp;
55 size_t stack_size = user_context->uc_stack.ss_size;
56 char const *faulting_address = info->si_addr;
57 size_t s = faulting_address - stack_min;
58 size_t page_size = sysconf (_SC_PAGESIZE);
59 if (find_stack_direction (0) < 0)
61 if (s < stack_size + page_size)
76 st.ss_sp = alternate_signal_stack.buffer;
77 st.ss_size = sizeof alternate_signal_stack.buffer;
78 r = sigaltstack (&st, 0);
82 sigemptyset (&act.sa_mask);
83 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
84 act.sa_sigaction = segv_handler;
85 return sigaction (SIGSEGV, &act, 0);
93 return *p + recurse (array);
99 #if HAVE_SETRLIMIT && defined RLIMIT_STACK
100 /* Before starting the endless recursion, try to be friendly
101 to the user's machine. On some Linux 2.2.x systems, there
102 is no stack limit for user processes at all. We don't want
103 to kill such systems. */
105 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
106 setrlimit (RLIMIT_STACK, &rl);
110 return recurse ("\1");
113 [ac_cv_sys_xsi_stack_overflow_heuristic=yes],
114 [ac_cv_sys_xsi_stack_overflow_heuristic=no],
115 [ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])])
117 if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then
118 AC_DEFINE(HAVE_XSI_STACK_OVERFLOW_HEURISTIC, 1,
119 [Define to 1 if extending the stack slightly past the limit causes
120 a SIGSEGV, and an alternate stack can be established with sigaltstack,
121 and the signal handler is passed a context that specifies the
122 run time stack. This behavior is defined by POSIX 1003.1-2001
123 with the X/Open System Interface (XSI) option
124 and is a standardized way to implement a SEGV-based stack
125 overflow detection heuristic.])
129 AC_DEFUN([gl_PREREQ_C_STACK],
130 [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
132 # for STACK_DIRECTION
133 AC_REQUIRE([AC_FUNC_ALLOCA])
135 AC_CHECK_FUNCS(getcontext sigaltstack)
136 AC_CHECK_DECLS([getcontext], , , [#include <ucontext.h>])
137 AC_CHECK_DECLS([sigaltstack], , , [#include <signal.h>])
139 AC_CHECK_HEADERS_ONCE(sys/time.h unistd.h)
140 AC_CHECK_HEADERS(sys/resource.h ucontext.h)
142 AC_CHECK_MEMBERS([struct sigaction.sa_sigaction], , , [#include <signal.h>])
144 AC_CHECK_TYPES([stack_t], , , [#include <signal.h>])])
146 AC_DEFUN([gl_C_STACK],
148 dnl Prerequisites of lib/c-stack.c.