1 # sigaltstack-siglongjmp.m4
2 # serial 8 (libsigsegv-2.15)
3 dnl Copyright (C) 2002-2024 Bruno Haible <bruno@clisp.org>
4 dnl This file is free software, distributed under the terms of the GNU
5 dnl General Public License as published by the Free Software Foundation;
6 dnl either version 2 of the License, or (at your option) any later version.
7 dnl As a special exception to the GNU General Public License, this file
8 dnl may be distributed as part of a program that contains a configuration
9 dnl script generated by Autoconf, under the same distribution terms as
10 dnl the rest of that program.
12 dnl How to siglongjmp out of a signal handler, in such a way that the
13 dnl alternate signal stack remains functional.
14 dnl SV_TRY_LEAVE_HANDLER_SIGLONGJMP(KIND, CACHESYMBOL, KNOWN-SYSTEMS,
15 dnl INCLUDES, RESETCODE)
16 AC_DEFUN([SV_TRY_LEAVE_HANDLER_SIGLONGJMP],
18 AC_REQUIRE([AC_PROG_CC])
19 AC_REQUIRE([AC_CANONICAL_HOST])
21 AC_CACHE_CHECK([whether a signal handler can be left through siglongjmp$1], [$2], [
29 # include <sys/types.h>
30 # include <sys/time.h>
31 # include <sys/resource.h>
33 /* In glibc >= 2.34, when _GNU_SOURCE is defined, SIGSTKSZ is no longer a
34 compile-time constant. But we need a simple constant here. */
38 # define SIGSTKSZ 262144
40 # define SIGSTKSZ 16384
44 # define SIGSTKSZ 16384
48 void stackoverflow_handler (int sig)
52 siglongjmp (mainloop, pass);
54 volatile int * recurse_1 (volatile int n, volatile int *p)
57 *recurse_1 (n + 1, p) += n;
60 int recurse (volatile int n)
63 return *recurse_1 (n, &sum);
65 char mystack[2 * SIGSTKSZ];
69 struct sigaction action;
71 /* On BeOS, this would hang, burning CPU time. Better fail than hang. */
74 #if defined HAVE_SETRLIMIT && defined RLIMIT_STACK
75 /* Before starting the endless recursion, try to be friendly to the user's
76 machine. On some Linux 2.2.x systems, there is no stack limit for user
77 processes at all. We don't want to kill such systems. */
79 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
80 setrlimit (RLIMIT_STACK, &rl);
82 /* Install the alternate stack. Use the midpoint of mystack, to guard
83 against a buggy interpretation of ss_sp on IRIX. */
84 altstack.ss_sp = mystack + SIGSTKSZ;
85 altstack.ss_size = SIGSTKSZ;
86 altstack.ss_flags = 0; /* no SS_DISABLE */
87 if (sigaltstack (&altstack, NULL) < 0)
89 /* Install the SIGSEGV handler. */
90 sigemptyset (&action.sa_mask);
91 action.sa_handler = &stackoverflow_handler;
92 action.sa_flags = SA_ONSTACK;
93 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
94 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
95 /* Provoke two stack overflows in a row. */
96 if (sigsetjmp (mainloop, 1) < 2)
106 m4_if([$3], [], [], [[$3]) $2=yes ;;])
107 *) $2="guessing no" ;;