forked from bonzini/smalltalk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sigaltstack.m4
124 lines (120 loc) · 3.81 KB
/
sigaltstack.m4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# sigaltstack.m4 serial 6 (libsigsegv-2.4)
dnl Copyright (C) 2002-2006 Bruno Haible <bruno@clisp.org>
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
dnl Public License, this file may be distributed as part of a program
dnl that contains a configuration script generated by Autoconf, under
dnl the same distribution terms as the rest of that program.
AC_DEFUN([SV_SIGALTSTACK],
[
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS(sigaltstack)
if test "$ac_cv_func_sigaltstack" = yes; then
AC_CHECK_TYPE(stack_t, ,
[AC_DEFINE(stack_t, [struct sigaltstack],
[Define to 'struct sigaltstack' if that's the type of the argument to sigaltstack])
],
[
#include <signal.h>
#if HAVE_SYS_SIGNAL_H
# include <sys/signal.h>
#endif
])
fi
AC_CACHE_CHECK([for working sigaltstack], sv_cv_sigaltstack, [
if test "$ac_cv_func_sigaltstack" = yes; then
case "$host_os" in
macos* | darwin[[6-9]]* | darwin[[1-9]][[0-9]]*)
# On MacOS X 10.2 or newer, just assume that if it compiles, it will
# work. If we were to perform the real test, 1 Crash Report dialog
# window would pop up.
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <signal.h>]],
[[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
[sv_cv_sigaltstack="guessing yes"],
[sv_cv_sigaltstack=no])
;;
*)
AC_RUN_IFELSE([
AC_LANG_SOURCE([[
#include <stdlib.h>
#include <signal.h>
#if HAVE_SYS_SIGNAL_H
# include <sys/signal.h>
#endif
#if HAVE_SETRLIMIT
# include <sys/types.h>
# include <sys/time.h>
# include <sys/resource.h>
#endif
void stackoverflow_handler (int sig)
{
/* If we get here, the stack overflow was caught. */
exit (0);
}
volatile int * recurse_1 (volatile int n, volatile int *p)
{
if (n >= 0)
*recurse_1 (n + 1, p) += n;
return p;
}
volatile int recurse (volatile int n)
{
int sum = 0;
return *recurse_1 (n, &sum);
}
char mystack[16384];
int main ()
{
stack_t altstack;
struct sigaction action;
#if defined HAVE_SETRLIMIT && defined RLIMIT_STACK
/* Before starting the endless recursion, try to be friendly to the user's
machine. On some Linux 2.2.x systems, there is no stack limit for user
processes at all. We don't want to kill such systems. */
struct rlimit rl;
rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
setrlimit (RLIMIT_STACK, &rl);
#endif
/* Install the alternate stack. */
altstack.ss_sp = mystack;
altstack.ss_size = sizeof (mystack);
altstack.ss_flags = 0; /* no SS_DISABLE */
if (sigaltstack (&altstack, NULL) < 0)
exit (1);
/* Install the SIGSEGV handler. */
sigemptyset (&action.sa_mask);
action.sa_handler = &stackoverflow_handler;
action.sa_flags = SA_ONSTACK;
sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
sigaction (SIGBUS, &action, (struct sigaction *) NULL);
/* Provoke a stack overflow. */
recurse (0);
exit (2);
}]])],
[sv_cv_sigaltstack=yes],
[sv_cv_sigaltstack=no],
[
dnl FIXME: Put in some more known values here.
case "$host_os" in
*)
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[#include <signal.h>]],
[[int x = SA_ONSTACK; stack_t ss; sigaltstack ((stack_t*)0, &ss);]])],
[sv_cv_sigaltstack="guessing yes"],
[sv_cv_sigaltstack=no])
;;
esac
])
;;
esac
else
sv_cv_sigaltstack=no
fi
])
if test "$sv_cv_sigaltstack" != no; then
AC_DEFINE(HAVE_WORKING_SIGALTSTACK, 1,
[Define if you have the sigaltstack() function and it works.])
fi
])