1 # sigaltstack.m4 serial 15
2 dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
3 dnl This file is free software, distributed under the terms of the GNU
4 dnl General Public License. As a special exception to the GNU General
5 dnl Public License, this file may be distributed as part of a program
6 dnl that contains a configuration script generated by Autoconf, under
7 dnl the same distribution terms as the rest of that program.
9 dnl Written by Bruno Haible and Eric Blake.
11 AC_DEFUN([SV_SIGALTSTACK],
13 AC_REQUIRE([AC_PROG_CC])
14 AC_REQUIRE([AC_CANONICAL_HOST])
16 AC_CHECK_FUNCS_ONCE([sigaltstack setrlimit])
18 if test "$ac_cv_func_sigaltstack" = yes; then
19 AC_CHECK_TYPE([stack_t], ,
20 [AC_DEFINE(stack_t, [struct sigaltstack],
21 [Define to 'struct sigaltstack' if that's the type of the argument to sigaltstack])
26 # include <sys/signal.h>
31 AC_CACHE_CHECK([for working sigaltstack], [sv_cv_sigaltstack], [
32 if test "$ac_cv_func_sigaltstack" = yes; then
34 macos* | darwin[[6-9]]* | darwin[[1-9]][[0-9]]*)
35 # On MacOS X 10.2 or newer, just assume that if it compiles, it will
36 # work. If we were to perform the real test, 1 Crash Report dialog
37 # window would pop up.
39 AC_LANG_PROGRAM([[#include <signal.h>]],
40 [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
41 [sv_cv_sigaltstack="guessing yes"],
42 [sv_cv_sigaltstack=no])
50 # include <sys/signal.h>
53 # include <sys/types.h>
54 # include <sys/time.h>
55 # include <sys/resource.h>
57 void stackoverflow_handler (int sig)
59 /* If we get here, the stack overflow was caught. */
62 volatile int * recurse_1 (volatile int n, volatile int *p)
65 *recurse_1 (n + 1, p) += n;
68 int recurse (volatile int n)
71 return *recurse_1 (n, &sum);
73 char mystack[2 * (1 << 24)];
77 struct sigaction action;
78 #if defined HAVE_SETRLIMIT && defined RLIMIT_STACK
79 /* Before starting the endless recursion, try to be friendly to the user's
80 machine. On some Linux 2.2.x systems, there is no stack limit for user
81 processes at all. We don't want to kill such systems. */
83 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
84 setrlimit (RLIMIT_STACK, &rl);
86 /* Install the alternate stack. Use the midpoint of mystack, to guard
87 against a buggy interpretation of ss_sp on IRIX. */
89 if (sizeof mystack / 2 < SIGSTKSZ)
92 altstack.ss_sp = mystack + sizeof mystack / 2;
93 altstack.ss_size = sizeof mystack / 2;
94 altstack.ss_flags = 0; /* no SS_DISABLE */
95 if (sigaltstack (&altstack, NULL) < 0)
97 /* Install the SIGSEGV handler. */
98 sigemptyset (&action.sa_mask);
99 action.sa_handler = &stackoverflow_handler;
100 action.sa_flags = SA_ONSTACK;
101 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
102 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
103 /* Provoke a stack overflow. */
107 [sv_cv_sigaltstack=yes],
108 [sv_cv_sigaltstack=no],
110 dnl FIXME: Put in some more known values here.
114 AC_LANG_PROGRAM([[#include <signal.h>]],
115 [[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
116 [sv_cv_sigaltstack="guessing yes"],
117 [sv_cv_sigaltstack=no])
127 if test "$sv_cv_sigaltstack" != no; then
128 AC_DEFINE([HAVE_WORKING_SIGALTSTACK], [1],
129 [Define if you have the sigaltstack() function and it works.])
131 dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
132 dnl of the memory block designated as an alternate stack. But IRIX 5.3
133 dnl interprets it as the highest address!
134 AC_CACHE_CHECK([for correct stack_t interpretation],
135 [sv_cv_sigaltstack_low_base], [
140 #if HAVE_SYS_SIGNAL_H
141 # include <sys/signal.h>
143 volatile char *stack_lower_bound;
144 volatile char *stack_upper_bound;
145 static void check_stack_location (volatile char *addr)
147 if (addr >= stack_lower_bound && addr <= stack_upper_bound)
152 static void stackoverflow_handler (int sig)
155 check_stack_location (&dummy);
157 char mystack[2 * (1 << 24)];
161 struct sigaction action;
162 /* Install the alternate stack. */
163 altstack.ss_sp = mystack + sizeof mystack / 2;
164 altstack.ss_size = sizeof mystack / 2;
165 stack_lower_bound = (char *) altstack.ss_sp;
166 stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
167 altstack.ss_flags = 0; /* no SS_DISABLE */
168 if (sigaltstack (&altstack, NULL) < 0)
170 /* Install the SIGSEGV handler. */
171 sigemptyset (&action.sa_mask);
172 action.sa_handler = &stackoverflow_handler;
173 action.sa_flags = SA_ONSTACK;
174 if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
176 /* Provoke a SIGSEGV. */
180 [sv_cv_sigaltstack_low_base=yes],
181 [sv_cv_sigaltstack_low_base=no],
183 dnl FIXME: Put in some more known values here.
185 irix5*) sv_cv_sigaltstack_low_base="no" ;;
186 *) sv_cv_sigaltstack_low_base="guessing yes" ;;
190 if test "$sv_cv_sigaltstack_low_base" = no; then
191 AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
192 [Define if sigaltstack() interprets the stack_t.ss_sp field incorrectly,
193 as the highest address of the alternate stack range rather than as the