1 # Check prerequisites for compiling lib/c-stack.c.
3 # Copyright (C) 2002, 2003, 2004, 2008 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.
12 AC_DEFUN([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC],
13 [# for STACK_DIRECTION
14 AC_REQUIRE([AC_FUNC_ALLOCA])
15 AC_CHECK_FUNCS_ONCE([setrlimit])
16 AC_CHECK_HEADERS_ONCE([ucontext.h])
18 AC_CACHE_CHECK([for working C stack overflow detection],
19 [ac_cv_sys_stack_overflow_works],
25 # include <sys/types.h>
26 # include <sys/time.h>
27 # include <sys/resource.h>
30 # define SIGSTKSZ 16384
35 char buffer[SIGSTKSZ];
39 } alternate_signal_stack;
42 segv_handler (int signo)
55 st.ss_sp = alternate_signal_stack.buffer;
56 st.ss_size = sizeof alternate_signal_stack.buffer;
57 r = sigaltstack (&st, 0);
61 sigemptyset (&act.sa_mask);
62 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND;
63 act.sa_handler = segv_handler;
64 return sigaction (SIGSEGV, &act, 0);
72 return *p + recurse (array);
78 #if HAVE_SETRLIMIT && defined RLIMIT_STACK
79 /* Before starting the endless recursion, try to be friendly
80 to the user's machine. On some Linux 2.2.x systems, there
81 is no stack limit for user processes at all. We don't want
82 to kill such systems. */
84 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
85 setrlimit (RLIMIT_STACK, &rl);
89 return recurse ("\1");
92 [ac_cv_sys_stack_overflow_works=yes],
93 [ac_cv_sys_stack_overflow_works=no],
94 [ac_cv_sys_stack_overflow_works=cross-compiling])])
96 if test $ac_cv_sys_stack_overflow_works = yes; then
97 AC_DEFINE([HAVE_STACK_OVERFLOW_HANDLING], [1],
98 [Define to 1 if extending the stack slightly past the limit causes
99 a SIGSEGV which can be handled on an alternate stack established
102 AC_CACHE_CHECK([for precise C stack overflow detection],
103 ac_cv_sys_xsi_stack_overflow_heuristic,
109 # include <ucontext.h>
112 # include <sys/types.h>
113 # include <sys/time.h>
114 # include <sys/resource.h>
117 # define SIGSTKSZ 16384
122 char buffer[SIGSTKSZ];
126 } alternate_signal_stack;
129 # define find_stack_direction(ptr) STACK_DIRECTION
132 find_stack_direction (char const *addr)
135 return (! addr ? find_stack_direction (&dummy)
136 : addr < &dummy ? 1 : -1);
141 segv_handler (int signo, siginfo_t *info, void *context)
143 if (0 < info->si_code)
145 /* For XSI heuristics to work, we need uc_stack to describe
146 the interrupted stack (as on Solaris), and not the
147 currently executing stack (as on Linux). */
148 ucontext_t const *user_context = context;
149 char const *stack_min = user_context->uc_stack.ss_sp;
150 size_t stack_size = user_context->uc_stack.ss_size;
151 char const *faulting_address = info->si_addr;
152 size_t s = faulting_address - stack_min;
153 size_t page_size = sysconf (_SC_PAGESIZE);
154 if (find_stack_direction (0) < 0)
156 if (s < stack_size + page_size)
167 struct sigaction act;
171 st.ss_sp = alternate_signal_stack.buffer;
172 st.ss_size = sizeof alternate_signal_stack.buffer;
173 r = sigaltstack (&st, 0);
177 sigemptyset (&act.sa_mask);
178 act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
179 act.sa_sigaction = segv_handler;
180 return sigaction (SIGSEGV, &act, 0);
188 return *p + recurse (array);
194 #if HAVE_SETRLIMIT && defined RLIMIT_STACK
195 /* Before starting the endless recursion, try to be friendly
196 to the user's machine. On some Linux 2.2.x systems, there
197 is no stack limit for user processes at all. We don't want
198 to kill such systems. */
200 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
201 setrlimit (RLIMIT_STACK, &rl);
205 return recurse ("\1");
208 [ac_cv_sys_xsi_stack_overflow_heuristic=yes],
209 [ac_cv_sys_xsi_stack_overflow_heuristic=no],
210 [ac_cv_sys_xsi_stack_overflow_heuristic=cross-compiling])])
212 if test $ac_cv_sys_xsi_stack_overflow_heuristic = yes; then
213 AC_DEFINE(HAVE_XSI_STACK_OVERFLOW_HEURISTIC, 1,
214 [Define to 1 if extending the stack slightly past the limit causes
215 a SIGSEGV, and an alternate stack can be established with sigaltstack,
216 and the signal handler is passed a context that specifies the
217 run time stack. This behavior is defined by POSIX 1003.1-2001
218 with the X/Open System Interface (XSI) option
219 and is a standardized way to implement a SEGV-based stack
220 overflow detection heuristic.])
225 AC_DEFUN([gl_PREREQ_C_STACK],
226 [AC_REQUIRE([AC_SYS_XSI_STACK_OVERFLOW_HEURISTIC])
227 AC_REQUIRE([gl_LIBSIGSEGV])
229 # for STACK_DIRECTION
230 AC_REQUIRE([AC_FUNC_ALLOCA])
232 AC_CHECK_FUNCS_ONCE([sigaltstack])
233 AC_CHECK_DECLS([sigaltstack], , , [#include <signal.h>])
235 AC_CHECK_HEADERS_ONCE([unistd.h ucontext.h])
237 AC_CHECK_TYPES([stack_t], , , [#include <signal.h>])
239 dnl c-stack does not need -lsigsegv if the system has XSI heuristics.
240 if test "$gl_cv_lib_sigsegv" = yes \
241 && test $"ac_cv_sys_xsi_stack_overflow_heuristic" != yes ; then
242 AC_SUBST([LIBCSTACK], [$LIBSIGSEGV])
243 AC_SUBST([LTLIBCSTACK], [$LTLIBSIGSEGV])
247 AC_DEFUN([gl_C_STACK],
249 dnl Prerequisites of lib/c-stack.c.