1 # sigaltstack.m4 serial 11 (libsigsegv-2.9)
2 dnl Copyright (C) 2002-2006, 2008-2010 Bruno Haible <bruno@clisp.org>
3 dnl Copyright (C) 2008 Eric Blake <ebb9@byu.net>
4 dnl This file is free software, distributed under the terms of the GNU
5 dnl General Public License. As a special exception to the GNU General
6 dnl Public License, this file may be distributed as part of a program
7 dnl that contains a configuration script generated by Autoconf, under
8 dnl the same distribution terms as the rest of that program.
10 AC_DEFUN([SV_SIGALTSTACK],
12 AC_REQUIRE([AC_PROG_CC])
13 AC_REQUIRE([AC_CANONICAL_HOST])
15 AC_CHECK_FUNCS([sigaltstack])
17 if test "$ac_cv_func_sigaltstack" = yes; then
18 AC_CHECK_TYPE([stack_t], ,
19 [AC_DEFINE(stack_t, [struct sigaltstack],
20 [Define to 'struct sigaltstack' if that's the type of the argument to sigaltstack])
25 # include <sys/signal.h>
30 AC_CACHE_CHECK([for working sigaltstack], [sv_cv_sigaltstack], [
31 if test "$ac_cv_func_sigaltstack" = yes; then
33 macos* | darwin[[6-9]]* | darwin[[1-9]][[0-9]]*)
34 # On MacOS X 10.2 or newer, just assume that if it compiles, it will
35 # work. If we were to perform the real test, 1 Crash Report dialog
36 # window would pop up.
38 AC_LANG_PROGRAM([[#include <signal.h>]],
39 [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
40 [sv_cv_sigaltstack="guessing yes"],
41 [sv_cv_sigaltstack=no])
49 # include <sys/signal.h>
52 # include <sys/types.h>
53 # include <sys/time.h>
54 # include <sys/resource.h>
57 # define SIGSTKSZ 16384
59 void stackoverflow_handler (int sig)
61 /* If we get here, the stack overflow was caught. */
64 volatile int * recurse_1 (volatile int n, volatile int *p)
67 *recurse_1 (n + 1, p) += n;
70 int recurse (volatile int n)
73 return *recurse_1 (n, &sum);
75 char mystack[2 * SIGSTKSZ];
79 struct sigaction action;
80 #if defined HAVE_SETRLIMIT && defined RLIMIT_STACK
81 /* Before starting the endless recursion, try to be friendly to the user's
82 machine. On some Linux 2.2.x systems, there is no stack limit for user
83 processes at all. We don't want to kill such systems. */
85 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
86 setrlimit (RLIMIT_STACK, &rl);
88 /* Install the alternate stack. Use the midpoint of mystack, to guard
89 against a buggy interpretation of ss_sp on IRIX. */
90 altstack.ss_sp = mystack + SIGSTKSZ;
91 altstack.ss_size = SIGSTKSZ;
92 altstack.ss_flags = 0; /* no SS_DISABLE */
93 if (sigaltstack (&altstack, NULL) < 0)
95 /* Install the SIGSEGV handler. */
96 sigemptyset (&action.sa_mask);
97 action.sa_handler = &stackoverflow_handler;
98 action.sa_flags = SA_ONSTACK;
99 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
100 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
101 /* Provoke a stack overflow. */
105 [sv_cv_sigaltstack=yes],
106 [sv_cv_sigaltstack=no],
108 dnl FIXME: Put in some more known values here.
112 AC_LANG_PROGRAM([[#include <signal.h>]],
113 [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
114 [sv_cv_sigaltstack="guessing yes"],
115 [sv_cv_sigaltstack=no])
125 if test "$sv_cv_sigaltstack" != no; then
126 AC_DEFINE([HAVE_WORKING_SIGALTSTACK], [1],
127 [Define if you have the sigaltstack() function and it works.])
129 dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
130 dnl of the memory block designated as an alternate stack. But IRIX 5.3
131 dnl interprets it as the highest address!
132 AC_CACHE_CHECK([for correct stack_t interpretation],
133 [sv_cv_sigaltstack_low_base], [
138 #if HAVE_SYS_SIGNAL_H
139 # include <sys/signal.h>
142 # define SIGSTKSZ 16384
144 volatile char *stack_lower_bound;
145 volatile char *stack_upper_bound;
146 static void check_stack_location (volatile char *addr)
148 if (addr >= stack_lower_bound && addr <= stack_upper_bound)
153 static void stackoverflow_handler (int sig)
156 check_stack_location (&dummy);
160 char mystack[2 * SIGSTKSZ];
162 struct sigaction action;
163 /* Install the alternate stack. */
164 altstack.ss_sp = mystack + SIGSTKSZ;
165 altstack.ss_size = SIGSTKSZ;
166 stack_lower_bound = (char *) altstack.ss_sp;
167 stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
168 altstack.ss_flags = 0; /* no SS_DISABLE */
169 if (sigaltstack (&altstack, NULL) < 0)
171 /* Install the SIGSEGV handler. */
172 sigemptyset (&action.sa_mask);
173 action.sa_handler = &stackoverflow_handler;
174 action.sa_flags = SA_ONSTACK;
175 if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
177 /* Provoke a SIGSEGV. */
181 [sv_cv_sigaltstack_low_base=yes],
182 [sv_cv_sigaltstack_low_base=no],
184 dnl FIXME: Put in some more known values here.
186 irix5*) sv_cv_sigaltstack_low_base="no" ;;
187 *) sv_cv_sigaltstack_low_base="guessing yes" ;;
191 if test "$sv_cv_sigaltstack_low_base" = no; then
192 AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
193 [Define if sigaltstack() interprets the stack_t.ss_sp field incorrectly,
194 as the highest address of the alternate stack range rather than as the