1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-05-13 15:13:36 +00:00

sigsegv: New module.

* lib/sigsegv.in.h: New file, from GNU libsigsegv with modifications.
* lib/sigsegv.c: Likewise.
* lib/stackvma.h: Likewise.
* lib/stackvma.c: Likewise.
* m4/sigaltstack.m4: Likewise.
* m4/stack-direction.m4: Likewise.
* modules/sigsegv: New file.
This commit is contained in:
Bruno Haible
2021-05-16 15:20:12 +02:00
parent 1a72950760
commit e54aa61969
8 changed files with 4143 additions and 0 deletions

View File

@@ -1,3 +1,14 @@
2021-05-16 Bruno Haible <bruno@clisp.org>
sigsegv: New module.
* lib/sigsegv.in.h: New file, from GNU libsigsegv with modifications.
* lib/sigsegv.c: Likewise.
* lib/stackvma.h: Likewise.
* lib/stackvma.c: Likewise.
* m4/sigaltstack.m4: Likewise.
* m4/stack-direction.m4: Likewise.
* modules/sigsegv: New file.
2021-05-15 Pádraig Brady <P@draigBrady.com>
realloc-gnu: avoid glibc MALLOC_CHECK_ issue

1372
lib/sigsegv.c Normal file

File diff suppressed because it is too large Load Diff

233
lib/sigsegv.in.h Normal file
View File

@@ -0,0 +1,233 @@
/* Page fault handling library.
Copyright (C) 1998-2021 Bruno Haible <bruno@clisp.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _SIGSEGV_H
#define _SIGSEGV_H
/* Get size_t. */
#include <stddef.h>
/* Define the fault context structure. */
#if defined __linux__ || defined __ANDROID__ \
|| (defined __FreeBSD__ && (defined __arm__ || defined __armhf__ || defined __arm64__)) \
|| defined __NetBSD__ \
|| defined _AIX || defined __sun \
|| defined __CYGWIN__
/* Linux, FreeBSD, NetBSD, AIX, Solaris, Cygwin */
# include <ucontext.h>
#elif (defined __APPLE__ && defined __MACH__)
/* macOS */
# include <sys/ucontext.h>
#elif defined __HAIKU__
/* Haiku */
# include <signal.h>
#endif
/* Correct the value of SIGSTKSZ on some systems.
AIX 64-bit: original value 4096 is too small.
HP-UX: original value 8192 is too small.
Solaris 11/x86_64: original value 8192 is too small. */
#if defined _AIX && defined _ARCH_PPC64
# include <signal.h>
# undef SIGSTKSZ
# define SIGSTKSZ 8192
#endif
#if defined __hpux || (defined __sun && (defined __x86_64__ || defined __amd64__))
# include <signal.h>
# undef SIGSTKSZ
# define SIGSTKSZ 16384
#endif
/* HAVE_SIGSEGV_RECOVERY
is defined if the system supports catching SIGSEGV. */
#if defined __linux__ || defined __ANDROID__ || defined __GNU__ \
|| defined __FreeBSD_kernel__ || (defined __FreeBSD__ && !(defined __sparc__ || defined __sparc64__)) || defined __DragonFly__ \
|| defined __NetBSD__ \
|| defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__) \
|| defined _AIX || defined __sgi || defined __sun \
|| defined __CYGWIN__ || defined __HAIKU__
/* Linux, Hurd, GNU/kFreeBSD, FreeBSD, NetBSD, OpenBSD, macOS, AIX, IRIX, Solaris, Cygwin, Haiku */
# define HAVE_SIGSEGV_RECOVERY 1
#endif
/* HAVE_STACK_OVERFLOW_RECOVERY
is defined if stack overflow can be caught. */
#if defined __linux__ || defined __ANDROID__ || defined __GNU__ \
|| defined __FreeBSD_kernel__ || (defined __FreeBSD__ && !(defined __sparc__ || defined __sparc64__)) || defined __DragonFly__ \
|| (defined __NetBSD__ && !(defined __sparc__ || defined __sparc64__)) \
|| defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__) \
|| defined _AIX || defined __sgi || defined __sun \
|| defined __CYGWIN__ || defined __HAIKU__
/* Linux, Hurd, GNU/kFreeBSD, FreeBSD, NetBSD, OpenBSD, macOS, AIX, IRIX, Solaris, Cygwin, Haiku */
# define HAVE_STACK_OVERFLOW_RECOVERY 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define LIBSIGSEGV_VERSION 0x020D /* version number: (major<<8) + minor */
extern int libsigsegv_version; /* Likewise */
/* -------------------------------------------------------------------------- */
#if 1 /* really only HAVE_SIGSEGV_RECOVERY */
/*
* The mask of bits that are set to zero in a fault address that gets passed
* to a global SIGSEGV handler.
* On some platforms, the precise fault address is not known, only the memory
* page into which the fault address falls. This is apparently allowed by POSIX:
* <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html>
* says: "For some implementations, the value of si_addr may be inaccurate."
* In this case, the returned fault address is rounded down to a multiple of
* getpagesize() = sysconf(_SC_PAGESIZE).
* On such platforms, we define SIGSEGV_FAULT_ADDRESS_ALIGNMENT to be an upper
* bound for getpagesize() (and, like getpagesize(), also a power of 2).
* On the platforms where the returned fault address is the precise one, we
* define SIGSEGV_FAULT_ADDRESS_ALIGNMENT to 1.
*/
# if defined __NetBSD__ && (defined __sparc__ || defined __sparc64__)
/* getpagesize () is 0x1000 or 0x2000, depending on hardware. */
# define SIGSEGV_FAULT_ADDRESS_ALIGNMENT 0x2000UL
# elif defined __linux__ && (defined __s390__ || defined __s390x__)
/* getpagesize () is 0x1000. */
# define SIGSEGV_FAULT_ADDRESS_ALIGNMENT 0x1000UL
# else
# define SIGSEGV_FAULT_ADDRESS_ALIGNMENT 1UL
# endif
/*
* The type of a global SIGSEGV handler.
* The fault address, with the bits (SIGSEGV_FAULT_ADDRESS_ALIGNMENT - 1)
* cleared, is passed as argument.
* The access type (read access or write access) is not passed; your handler
* has to know itself how to distinguish these two cases.
* The second argument is 0, meaning it could also be a stack overflow, or 1,
* meaning the handler should seriously try to fix the fault.
* The return value should be nonzero if the handler has done its job
* and no other handler should be called, or 0 if the handler declines
* responsibility for the given address.
*
* The handler is run at a moment when nothing about the global state of the
* program is known. Therefore it cannot use facilities that manipulate global
* variables or locks. In particular, it cannot use malloc(); use mmap()
* instead. It cannot use fopen(); use open() instead. Etc. All global
* variables that are accessed by the handler should be marked 'volatile'.
*/
typedef int (*sigsegv_handler_t) (void* fault_address, int serious);
/*
* Installs a global SIGSEGV handler.
* This should be called once only, and it ignores any previously installed
* SIGSEGV handler.
* Returns 0 on success, or -1 if the system doesn't support catching SIGSEGV.
*/
extern int sigsegv_install_handler (sigsegv_handler_t handler);
/*
* Deinstalls the global SIGSEGV handler.
* This goes back to the state where no SIGSEGV handler is installed.
*/
extern void sigsegv_deinstall_handler (void);
/*
* Prepares leaving a SIGSEGV handler (through longjmp or similar means).
* Control is transferred by calling CONTINUATION with CONT_ARG1, CONT_ARG2,
* CONT_ARG3 as arguments.
* CONTINUATION must not return.
* The sigsegv_leave_handler function may return if called from a SIGSEGV
* handler; its return value should be used as the handler's return value.
* The sigsegv_leave_handler function does not return if called from a
* stack overflow handler.
*/
extern int sigsegv_leave_handler (void (*continuation) (void*, void*, void*), void* cont_arg1, void* cont_arg2, void* cont_arg3);
#endif /* HAVE_SIGSEGV_RECOVERY */
#if 1 /* really only HAVE_STACK_OVERFLOW_RECOVERY */
/*
* The type of a context passed to a stack overflow handler.
* This type is system dependent; on some platforms it is an 'ucontext_t *',
* on some platforms it is a 'struct sigcontext *', on others merely an
* opaque 'void *'.
*/
# if defined __linux__ || defined __ANDROID__ \
|| (defined __FreeBSD__ && (defined __arm__ || defined __armhf__ || defined __arm64__)) \
|| defined __NetBSD__ \
|| (defined __APPLE__ && defined __MACH__) \
|| defined _AIX || defined __sun \
|| defined __CYGWIN__ || defined __HAIKU__
typedef ucontext_t *stackoverflow_context_t;
# elif defined __GNU__ \
|| defined __FreeBSD_kernel__ || (defined __FreeBSD__ && !(defined __sparc__ || defined __sparc64__)) \
|| defined __OpenBSD__ || defined __sgi
typedef struct sigcontext *stackoverflow_context_t;
# else
typedef void *stackoverflow_context_t;
# endif
/*
* The type of a stack overflow handler.
* Such a handler should perform a longjmp call in order to reduce the amount
* of stack needed. It must not return.
* The emergency argument is 0 when the stack could be repared, or 1 if the
* application should better save its state and exit now.
*
* The handler is run at a moment when nothing about the global state of the
* program is known. Therefore it cannot use facilities that manipulate global
* variables or locks. In particular, it cannot use malloc(); use mmap()
* instead. It cannot use fopen(); use open() instead. Etc. All global
* variables that are accessed by the handler should be marked 'volatile'.
*/
typedef void (*stackoverflow_handler_t) (int emergency, stackoverflow_context_t scp);
/*
* Installs a stack overflow handler.
* The extra_stack argument is a pointer to a pre-allocated area used as a
* stack for executing the handler. It typically comes from a static variable
* or from heap-allocated memoty; placing it on the main stack may fail on
* some operating systems.
* Its size, passed in extra_stack_size, should be sufficiently large. The
* following code determines an appropriate size:
* #include <signal.h>
* #ifndef SIGSTKSZ / * glibc defines SIGSTKSZ for this purpose * /
* # define SIGSTKSZ 16384 / * on most platforms, 16 KB are sufficient * /
* #endif
* Returns 0 on success, or -1 if the system doesn't support catching stack
* overflow.
*/
extern int stackoverflow_install_handler (stackoverflow_handler_t handler,
void* extra_stack, size_t extra_stack_size);
/*
* Deinstalls the stack overflow handler.
*/
extern void stackoverflow_deinstall_handler (void);
#endif /* HAVE_STACK_OVERFLOW_RECOVERY */
/* -------------------------------------------------------------------------- */
#ifdef __cplusplus
}
#endif
#endif /* _SIGSEGV_H */

2064
lib/stackvma.c Normal file

File diff suppressed because it is too large Load Diff

60
lib/stackvma.h Normal file
View File

@@ -0,0 +1,60 @@
/* Determine the virtual memory area of a given address.
Copyright (C) 2002-2021 Bruno Haible <bruno@clisp.org>
Copyright (C) 2003-2006 Paolo Bonzini <bonzini@gnu.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _STACKVMA_H
#define _STACKVMA_H
#include <stdint.h>
/* Describes a virtual memory area, with some info about the gap between
it and the next or previous virtual memory area. */
struct vma_struct
{
uintptr_t start;
uintptr_t end;
#if STACK_DIRECTION < 0
/* Info about the gap between this VMA and the previous one.
addr must be < vma->start. */
int (*is_near_this) (uintptr_t addr, struct vma_struct *vma);
/* Private field, not provided by all sigsegv_get_vma implementations. */
uintptr_t prev_end;
#endif
#if STACK_DIRECTION > 0
/* Info about the gap between this VMA and the next one.
addr must be > vma->end - 1. */
int (*is_near_this) (uintptr_t addr, struct vma_struct *vma);
/* Private field, not provided by all sigsegv_get_vma implementations. */
uintptr_t next_start;
#endif
};
/* Determines the virtual memory area to which a given address belongs,
and returns 0. Returns -1 if it cannot be determined.
This function is used to determine the stack extent when a fault occurs. */
extern int sigsegv_get_vma (uintptr_t address, struct vma_struct *vma);
/* Defined if sigsegv_get_vma actually works (i.e. does not always fail). */
#if defined __linux__ || defined __ANDROID__ \
|| defined __FreeBSD_kernel__ || defined __FreeBSD__ || defined __DragonFly__ \
|| defined __NetBSD__ || defined __OpenBSD__ \
|| (defined __APPLE__ && defined __MACH__) \
|| defined _AIX || defined __sgi || defined __sun \
|| defined __CYGWIN__ || defined __HAIKU__
# define HAVE_STACKVMA 1
#endif
#endif /* _STACKVMA_H */

198
m4/sigaltstack.m4 Normal file
View File

@@ -0,0 +1,198 @@
# sigaltstack.m4 serial 12
dnl Copyright (C) 2002-2021 Bruno Haible <bruno@clisp.org>
dnl Copyright (C) 2008 Eric Blake <ebb9@byu.net>
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_ONCE([sigaltstack setrlimit])
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
#ifndef SIGSTKSZ
# define SIGSTKSZ 16384
#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;
}
int recurse (volatile int n)
{
int sum = 0;
return *recurse_1 (n, &sum);
}
char mystack[2 * SIGSTKSZ];
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. Use the midpoint of mystack, to guard
against a buggy interpretation of ss_sp on IRIX. */
altstack.ss_sp = mystack + SIGSTKSZ;
altstack.ss_size = SIGSTKSZ;
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.])
dnl The ss_sp field of a stack_t is, according to POSIX, the lowest address
dnl of the memory block designated as an alternate stack. But IRIX 5.3
dnl interprets it as the highest address!
AC_CACHE_CHECK([for correct stack_t interpretation],
[sv_cv_sigaltstack_low_base], [
AC_RUN_IFELSE([
AC_LANG_SOURCE([[
#include <stdlib.h>
#include <signal.h>
#if HAVE_SYS_SIGNAL_H
# include <sys/signal.h>
#endif
#ifndef SIGSTKSZ
# define SIGSTKSZ 16384
#endif
volatile char *stack_lower_bound;
volatile char *stack_upper_bound;
static void check_stack_location (volatile char *addr)
{
if (addr >= stack_lower_bound && addr <= stack_upper_bound)
exit (0);
else
exit (1);
}
static void stackoverflow_handler (int sig)
{
char dummy;
check_stack_location (&dummy);
}
int main ()
{
char mystack[2 * SIGSTKSZ];
stack_t altstack;
struct sigaction action;
/* Install the alternate stack. */
altstack.ss_sp = mystack + SIGSTKSZ;
altstack.ss_size = SIGSTKSZ;
stack_lower_bound = (char *) altstack.ss_sp;
stack_upper_bound = (char *) altstack.ss_sp + altstack.ss_size - 1;
altstack.ss_flags = 0; /* no SS_DISABLE */
if (sigaltstack (&altstack, NULL) < 0)
exit (2);
/* Install the SIGSEGV handler. */
sigemptyset (&action.sa_mask);
action.sa_handler = &stackoverflow_handler;
action.sa_flags = SA_ONSTACK;
if (sigaction (SIGSEGV, &action, (struct sigaction *) NULL) < 0)
exit(3);
/* Provoke a SIGSEGV. */
raise (SIGSEGV);
exit (3);
}]])],
[sv_cv_sigaltstack_low_base=yes],
[sv_cv_sigaltstack_low_base=no],
[
dnl FIXME: Put in some more known values here.
case "$host_os" in
irix5*) sv_cv_sigaltstack_low_base="no" ;;
*) sv_cv_sigaltstack_low_base="guessing yes" ;;
esac
])
])
if test "$sv_cv_sigaltstack_low_base" = no; then
AC_DEFINE([SIGALTSTACK_SS_REVERSED], [1],
[Define if sigaltstack() interprets the stack_t.ss_sp field incorrectly,
as the highest address of the alternate stack range rather than as the
lowest address.])
fi
fi
])

104
m4/stack-direction.m4 Normal file
View File

@@ -0,0 +1,104 @@
# stack-direction.m4 serial 6
dnl Copyright (C) 2002-2021 Bruno Haible <bruno@clisp.org>
dnl Copyright (C) 2002-2021 Free Software Foundation, Inc.
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.
# Determine the stack direction. Define the C macro STACK_DIRECTION.
AC_DEFUN([SV_STACK_DIRECTION],
[
AC_REQUIRE([AC_CANONICAL_HOST])
AC_CACHE_CHECK([for stack direction], [sv_cv_stack_direction_msg], [
case "$host_cpu" in
dnl See the #define STACK_GROWS_DOWNWARD in gcc-3.1/gcc/config/*/*.h.
a29k | \
aarch64* | \
alpha* | \
arc | \
arm* | strongarm* | xscale* | \
avr | avr32 | \
bfin | \
c1 | c2 | c32 | c34 | c38 | \
clipper | \
cris | \
d30v | \
elxsi | \
fr30 | \
h8300 | \
i?86 | x86_64 | \
i860 | \
ia64 | \
m32r | \
m68* | \
m88k | \
mcore | \
microblaze | \
mips* | \
mmix | \
mn10200 | \
mn10300 | \
nios2 | \
nds32* | \
ns32k | \
pdp11 | \
pj* | \
powerpc* | rs6000 | \
riscv* | \
romp | \
s390* | \
sh* | \
sparc* | \
v850 | \
vax | \
xtensa)
sv_cv_stack_direction=-1 ;;
c4x | \
dsp16xx | \
i960 | \
hppa* | parisc* | \
stormy16 | \
we32k)
sv_cv_stack_direction=1 ;;
*)
if test $cross_compiling = no; then
cat > conftest.c <<EOF
#include <stdio.h>
int
find_stack_direction (int *addr, int depth)
{
int dir, dummy = 0;
if (! addr)
addr = &dummy;
*addr = addr < &dummy ? 1 : addr == &dummy ? 0 : -1;
dir = depth ? find_stack_direction (addr, depth - 1) : 0;
return dir + dummy;
}
int
main (int argc, char *argv[])
{
printf ("%d\n", find_stack_direction (NULL, argc + 20));
return 0;
}
EOF
AC_TRY_EVAL([ac_link])
sv_cv_stack_direction=`./conftest`
else
sv_cv_stack_direction=0
fi
;;
esac
case $sv_cv_stack_direction in
1) sv_cv_stack_direction_msg="grows up";;
-1) sv_cv_stack_direction_msg="grows down";;
*) sv_cv_stack_direction_msg="unknown";;
esac
])
AC_DEFINE_UNQUOTED([STACK_DIRECTION], [$sv_cv_stack_direction],
[Define as the direction of stack growth for your system.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => spaghetti stack.])
])

101
modules/sigsegv Normal file
View File

@@ -0,0 +1,101 @@
Description:
A simplified variant of GNU libsigsegv.
It implements the most important features of GNU libsigsegv: catching SIGSEGV
and catching stack overflow. It does *not* implement the 'sigsegv_dispatcher'
type (which is not multithread-safe).
It supports all modern Unix-like platforms: Linux, Hurd, FreeBSD, NetBSD,
OpenBSD, macOS, AIX, Solaris, Cygwin, Haiku, even IRIX. It does *not* support
HP-UX, Minix, native Windows; on these platforms the module compiles and
provides a <sigsegv.h> header file, but it does not define HAVE_SIGSEGV_RECOVERY
and HAVE_STACK_OVERFLOW_RECOVERY.
Unlike GNU libsigsegv, which consists of many .h and .c files, this module
compiles to just two object files, rather than a library.
Files:
lib/sigsegv.in.h
lib/sigsegv.c
lib/stackvma.h
lib/stackvma.c
m4/mmap-anon.m4
m4/sigaltstack.m4
m4/stack-direction.m4
m4/libsigsegv.m4
Depends-on:
havelib
host-cpu-c-abi
stdint
getpagesize
configure.ac:
AC_ARG_WITH([libsigsegv],
[AS_HELP_STRING([--with-libsigsegv],
[use the GNU libsigsegv library, when present, instead of the gnulib module 'sigsegv'])])
SIGSEGV_H=sigsegv.h
if test "$with_libsigsegv" = yes; then
gl_LIBSIGSEGV
if test "$gl_cv_lib_sigsegv" = yes; then
SIGSEGV_H=
fi
fi
AC_SUBST([SIGSEGV_H])
AM_CONDITIONAL([GL_GENERATE_SIGSEGV_H], [test -n "$SIGSEGV_H"])
if test -n "$SIGSEGV_H"; then
dnl Persuade glibc <sys/ucontext.h> to declare macros designating register
dnl indices: REG_RSP on x86_64, REG_ESP on i386.
dnl Persuade Solaris OpenIndiana <ucontext.h> to include <sys/regset.h>,
dnl which declares macros designating register indices, such as ESP on i386.
dnl Persuade Solaris OpenIndiana <unistd.h> to declare mincore().
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_REQUIRE([AC_CANONICAL_HOST])
case "$host_os" in
solaris2.11)
AC_DEFINE([SOLARIS11], [1], [Define on Solaris 11 and its derivates.])
;;
esac
gl_FUNC_MMAP_ANON
dnl Stack direction.
SV_STACK_DIRECTION
dnl Catching stack overflow requires an alternate signal stack.
dnl The old "install a guard page" trick would be unreliable, because
dnl we don't know where exactly to place the guard page.
SV_SIGALTSTACK
AC_CHECK_FUNCS_ONCE([getrlimit])
fi
Makefile.am:
BUILT_SOURCES += $(SIGSEGV_H)
if GL_GENERATE_SIGSEGV_H
sigsegv.h: sigsegv.in.h $(top_builddir)/config.status
$(AM_V_GEN)rm -f $@-t $@ && \
{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
cat $(srcdir)/sigsegv.in.h; \
} > $@-t && \
mv $@-t $@
else
sigsegv.h: $(top_builddir)/config.status
rm -f $@
endif
MOSTLYCLEANFILES += sigsegv.h sigsegv.h-t
if GL_GENERATE_SIGSEGV_H
lib_SOURCES += sigsegv.c stackvma.c
endif
Include:
<sigsegv.h>
Link:
$(LTLIBSIGSEGV) when linking with libtool, $(LIBSIGSEGV) otherwise
License:
GPLv2+
Maintainer:
Bruno Haible