1 # sigaltstack.m4 serial 14
2 dnl Copyright (C) 2002-2021 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_ONCE([sigaltstack setrlimit])
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>
56 void stackoverflow_handler (int sig)
58 /* If we get here, the stack overflow was caught. */
61 volatile int * recurse_1 (volatile int n, volatile int *p)
64 *recurse_1 (n + 1, p) += n;
67 int recurse (volatile int n)
70 return *recurse_1 (n, &sum);
72 char mystack[2 * (1 << 24)];
76 struct sigaction action;
77 #if defined HAVE_SETRLIMIT && defined RLIMIT_STACK
78 /* Before starting the endless recursion, try to be friendly to the user's
79 machine. On some Linux 2.2.x systems, there is no stack limit for user
80 processes at all. We don't want to kill such systems. */
82 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
83 setrlimit (RLIMIT_STACK, &rl);
85 /* Install the alternate stack. Use the midpoint of mystack, to guard
86 against a buggy interpretation of ss_sp on IRIX. */
88 if (sizeof mystack / 2 < SIGSTKSZ)
91 altstack.ss_sp = mystack + sizeof mystack / 2;
92 altstack.ss_size = sizeof mystack / 2;
93 altstack.ss_flags = 0; /* no SS_DISABLE */
94 if (sigaltstack (&altstack, NULL) < 0)
96 /* Install the SIGSEGV handler. */
97 sigemptyset (&action.sa_mask);
98 action.sa_handler = &stackoverflow_handler;
99 action.sa_flags = SA_ONSTACK;
100 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
101 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
102 /* Provoke a stack overflow. */
106 [sv_cv_sigaltstack=yes],
107 [sv_cv_sigaltstack=no],
109 dnl FIXME: Put in some more known values here.
113 AC_LANG_PROGRAM([[#include <signal.h>]],
114 [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
115 [sv_cv_sigaltstack="guessing yes"],
116 [sv_cv_sigaltstack=no])
126 if test "$sv_cv_sigaltstack" != no; then
127 AC_DEFINE([HAVE_WORKING_SIGALTSTACK], [1],
128 [Define if you have the sigaltstack() function and it works.])
130 dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
131 dnl of the memory block designated as an alternate stack. But IRIX 5.3
132 dnl interprets it as the highest address!
133 AC_CACHE_CHECK([for correct stack_t interpretation],
134 [sv_cv_sigaltstack_low_base], [
139 #if HAVE_SYS_SIGNAL_H
140 # include <sys/signal.h>
142 volatile char *stack_lower_bound;
143 volatile char *stack_upper_bound;
144 static void check_stack_location (volatile char *addr)
146 if (addr >= stack_lower_bound && addr <= stack_upper_bound)
151 static void stackoverflow_handler (int sig)
154 check_stack_location (&dummy);
156 char mystack[2 * (1 << 24)];
160 struct sigaction action;
161 /* Install the alternate stack. */
162 altstack.ss_sp = mystack + sizeof mystack / 2;
163 altstack.ss_size = sizeof mystack / 2;
164 stack_lower_bound = (char *) altstack.ss_sp;
165 stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
166 altstack.ss_flags = 0; /* no SS_DISABLE */
167 if (sigaltstack (&altstack, NULL) < 0)
169 /* Install the SIGSEGV handler. */
170 sigemptyset (&action.sa_mask);
171 action.sa_handler = &stackoverflow_handler;
172 action.sa_flags = SA_ONSTACK;
173 if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
175 /* Provoke a SIGSEGV. */
179 [sv_cv_sigaltstack_low_base=yes],
180 [sv_cv_sigaltstack_low_base=no],
182 dnl FIXME: Put in some more known values here.
184 irix5*) sv_cv_sigaltstack_low_base="no" ;;
185 *) sv_cv_sigaltstack_low_base="guessing yes" ;;
189 if test "$sv_cv_sigaltstack_low_base" = no; then
190 AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
191 [Define if sigaltstack() interprets the stack_t.ss_sp field incorrectly,
192 as the highest address of the alternate stack range rather than as the