GNU libsigsegv
GNU libsigsegv is a library for handling page faults in user mode. A page fault occurs when a program tries to access to a region of memory that is currently not available. Catching and handling a page fault is a useful technique for implementing:
- pageable virtual memory,
- memory-mapped access to persistent databases,
- generational garbage collectors,
- stack overflow handlers,
- distributed shared memory,
- ...
This library supports three sets of functions, all defined in <sigsegv.h>
:
- Global SIGSEGV handlers:
sigsegv_install_handler
,sigsegv_deinstall_handler
.- Local SIGSEGV handlers (a handler per memory area):
sigsegv_init
,sigsegv_register
,sigsegv_unregister
,sigsegv_dispatch
.- Stack overflow handlers:
stackoverflow_install_handler
,stackoverflow_deinstall_handler
.
Each of the three APIs can be used independently or simultaneously. For examples of the use of the APIs, see:
- Global SIGSEGV handlers: see tests/sigsegv1.c.
- Local SIGSEGV handlers: see tests/sigsegv2.c.
- Stack overflow handlers: see tests/stackoverflow1.c.
About portability
Some platforms don't support this functionality. In <sigsegv.h>
, the
preprocessor macro HAVE_SIGSEGV_RECOVERY
will be defined if global and
local SIGSEGV
handlers are available, and the preprocessor macro
HAVE_STACK_OVERFLOW_RECOVERY
will be defined if stack overflow handlers
are available. Note that the declared functions are available in all cases;
on platforms where HAVE_SIGSEGV_RECOVERY
or HAVE_STACK_OVERFLOW_RECOVERY
is
not defined, they will simply always return an error code or do nothing.
The list of platforms where this library is known to work is contained in the file PORTING.
About pageable virtual memory
Pageable virtual memory is usually done in the operating system's kernel. This library helps in implementing the others.
Installing a page fault handler is usually more efficient than doing access checks in software at every access, because it's effectively the hardware (the MMU) which checks whether a page is present or not.
Note that if you use system calls (like read()) to write into write-
protected pages, the system will react by returning -1 and setting
errno
to EFAULT
, instead of signalling SIGSEGV
and restarting the system
call. In this case, the program has to do what the SIGSEGV
handler would
do, and then restart the read() operation. Some buggy systems (SunOS 4)
go into an endless loop on this occasion; on these systems you have to
make sure that an area is writable _before_ you call read() on it,
About stack overflow handlers
In some applications, the stack overflow handler performs some cleanup or notifies the user and then immediately terminates the application. In other applications, the stack overflow handler longjmps back to a central point in the application. This library supports both uses. In the second case, the handler must ensure to restore the normal signal mask (because many signals are blocked while the handler is executed), and must also call sigsegv_leave_handler() to transfer control; then only it can longjmp away.
Note that longjmping back to a central point in the application can leave the application in an inconsistent state, because
- no cleanup is executed for call frames that are being unwound,
- the code being executed while the stack overflow occurred might leave data structures in an intermediate, inconsistent state.
- a main thread, which creates the other threads,
- worker threads, which may cause stack overflows, and in which all
cleanups are registered through the
pthread_cleanup_push
function, - a handler thread, which contains the handler for stack overflow and
other kinds of SIGSEGV. The handler will call
pthread_cancel
on the worker thread whose stack overflowed.
pthread_sigmask
on all threads except
the handler thread, in order to ensure that the SIGSEGV signal gets handled
in the designated handler thread.If you want to avoid the second problem together with the first problem, you need to enclose code that manipulates data structures in a way that is not safe to be interrupted within calls to
pthread_setcancelstate
or
pthread_setcanceltype
.If you want to avoid just the second problem, you need to manipulate all data structures in a way that is safe to be interrupted at any moment and also compile your program with the gcc flag
-fnon-call-exceptions
.
About shared libraries
This library builds as a static library by default. This seems useful because of the small size of the library (4 KB). Of course, you can build it as a shared library by specifying the configure option '--enable-shared'.
Using libsigsegv in your package
- For the APIs, see the comments in the
<sigsegv.h>
file (generated fromsrc/sigsegv.h.in
). - An autoconf macro for determining where libsigsegv is installed and how to link with it is part of GNU gnulib, see http://www.gnu.org/software/gnulib/MODULES.html#module=libsigsegv
Downloading libsigsegv
libsigsegv can be downloaded from https://ftp.gnu.org/gnu/libsigsegv/libsigsegv-2.14.tar.gz.
Mailing lists
libsigsegv has the following mailing lists:
- bug-libsigsegv is used to discuss most aspects of libsigsegv, including general user help, development and enhancement requests, as well as bug reports.
Announcements about libsigsegv and most other GNU software are made on info-gnu (archive).
Getting involved
Development of libsigsegv, and GNU in general, is a volunteer effort, and you can contribute. For information, please read How to help GNU. If you'd like to get involved, it's a good idea to join the discussion mailing list (see above).
- Development
- For development sources, issue trackers, and other information, please see the libsigsegv project page at savannah.gnu.org.
- Maintainer
- libsigsegv is currently being maintained by Bruno Haible, Eric Blake, and Paolo Bonzini. Please use the mailing lists for contact.
Licensing
libsigsegv 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.