summaryrefslogtreecommitdiffstats
path: root/man/man2/sigaltstack.2
diff options
context:
space:
mode:
Diffstat (limited to 'man/man2/sigaltstack.2')
-rw-r--r--man/man2/sigaltstack.2362
1 files changed, 362 insertions, 0 deletions
diff --git a/man/man2/sigaltstack.2 b/man/man2/sigaltstack.2
new file mode 100644
index 0000000..166999f
--- /dev/null
+++ b/man/man2/sigaltstack.2
@@ -0,0 +1,362 @@
+'\" t
+.\" Copyright (c) 2001, 2017 Michael Kerrisk <mtk.manpages@gmail.com>
+.\"
+.\" SPDX-License-Identifier: Linux-man-pages-copyleft
+.\"
+.\" aeb, various minor fixes
+.TH sigaltstack 2 2024-05-02 "Linux man-pages (unreleased)"
+.SH NAME
+sigaltstack \- set and/or get signal stack context
+.SH LIBRARY
+Standard C library
+.RI ( libc ", " \-lc )
+.SH SYNOPSIS
+.nf
+.B #include <signal.h>
+.P
+.BI "int sigaltstack(const stack_t *_Nullable restrict " ss ,
+.BI " stack_t *_Nullable restrict " old_ss );
+.fi
+.P
+.RS -4
+Feature Test Macro Requirements for glibc (see
+.BR feature_test_macros (7)):
+.RE
+.P
+.BR sigaltstack ():
+.nf
+ _XOPEN_SOURCE >= 500
+.\" || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
+ || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
+ || /* glibc <= 2.19: */ _BSD_SOURCE
+.fi
+.SH DESCRIPTION
+.BR sigaltstack ()
+allows a thread to define a new alternate
+signal stack and/or retrieve the state of an existing
+alternate signal stack.
+An alternate signal stack is used during the
+execution of a signal handler if the establishment of that handler (see
+.BR sigaction (2))
+requested it.
+.P
+The normal sequence of events for using an alternate signal stack
+is the following:
+.TP 3
+1.
+Allocate an area of memory to be used for the alternate
+signal stack.
+.TP
+2.
+Use
+.BR sigaltstack ()
+to inform the system of the existence and
+location of the alternate signal stack.
+.TP
+3.
+When establishing a signal handler using
+.BR sigaction (2),
+inform the system that the signal handler should be executed
+on the alternate signal stack by
+specifying the \fBSA_ONSTACK\fP flag.
+.P
+The \fIss\fP argument is used to specify a new
+alternate signal stack, while the \fIold_ss\fP argument
+is used to retrieve information about the currently
+established signal stack.
+If we are interested in performing just one
+of these tasks, then the other argument can be specified as NULL.
+.P
+The
+.I stack_t
+type used to type the arguments of this function is defined as follows:
+.P
+.in +4n
+.EX
+typedef struct {
+ void *ss_sp; /* Base address of stack */
+ int ss_flags; /* Flags */
+ size_t ss_size; /* Number of bytes in stack */
+} stack_t;
+.EE
+.in
+.P
+To establish a new alternate signal stack,
+the fields of this structure are set as follows:
+.TP
+.I ss.ss_flags
+This field contains either 0, or the following flag:
+.RS
+.TP
+.BR SS_AUTODISARM " (since Linux 4.7)"
+.\" commit 2a74213838104a41588d86fd5e8d344972891ace
+.\" See tools/testing/selftests/sigaltstack/sas.c in kernel sources
+Clear the alternate signal stack settings on entry to the signal handler.
+When the signal handler returns,
+the previous alternate signal stack settings are restored.
+.IP
+This flag was added in order to make it safe
+to switch away from the signal handler with
+.BR swapcontext (3).
+Without this flag, a subsequently handled signal will corrupt
+the state of the switched-away signal handler.
+On kernels where this flag is not supported,
+.BR sigaltstack ()
+fails with the error
+.B EINVAL
+when this flag is supplied.
+.RE
+.TP
+.I ss.ss_sp
+This field specifies the starting address of the stack.
+When a signal handler is invoked on the alternate stack,
+the kernel automatically aligns the address given in \fIss.ss_sp\fP
+to a suitable address boundary for the underlying hardware architecture.
+.TP
+.I ss.ss_size
+This field specifies the size of the stack.
+The constant \fBSIGSTKSZ\fP is defined to be large enough
+to cover the usual size requirements for an alternate signal stack,
+and the constant \fBMINSIGSTKSZ\fP defines the minimum
+size required to execute a signal handler.
+.P
+To disable an existing stack, specify \fIss.ss_flags\fP
+as \fBSS_DISABLE\fP.
+In this case, the kernel ignores any other flags in
+.I ss.ss_flags
+and the remaining fields
+in \fIss\fP.
+.P
+If \fIold_ss\fP is not NULL, then it is used to return information about
+the alternate signal stack which was in effect prior to the
+call to
+.BR sigaltstack ().
+The \fIold_ss.ss_sp\fP and \fIold_ss.ss_size\fP fields return the starting
+address and size of that stack.
+The \fIold_ss.ss_flags\fP may return either of the following values:
+.TP
+.B SS_ONSTACK
+The thread is currently executing on the alternate signal stack.
+(Note that it is not possible
+to change the alternate signal stack if the thread is
+currently executing on it.)
+.TP
+.B SS_DISABLE
+The alternate signal stack is currently disabled.
+.IP
+Alternatively, this value is returned if the thread is currently
+executing on an alternate signal stack that was established using the
+.B SS_AUTODISARM
+flag.
+In this case, it is safe to switch away from the signal handler with
+.BR swapcontext (3).
+It is also possible to set up a different alternative signal stack
+using a further call to
+.BR sigaltstack ().
+.\" FIXME Was it intended that one can set up a different alternative
+.\" signal stack in this scenario? (In passing, if one does this, the
+.\" sigaltstack(NULL, &old_ss) now returns old_ss.ss_flags==SS_AUTODISARM
+.\" rather than old_ss.ss_flags==SS_DISABLE. The API design here seems
+.\" confusing...
+.TP
+.B SS_AUTODISARM
+The alternate signal stack has been marked to be autodisarmed
+as described above.
+.P
+By specifying
+.I ss
+as NULL, and
+.I old_ss
+as a non-NULL value, one can obtain the current settings for
+the alternate signal stack without changing them.
+.SH RETURN VALUE
+.BR sigaltstack ()
+returns 0 on success, or \-1 on failure with
+\fIerrno\fP set to indicate the error.
+.SH ERRORS
+.TP
+.B EFAULT
+Either \fIss\fP or \fIold_ss\fP is not NULL and points to an area
+outside of the process's address space.
+.TP
+.B EINVAL
+\fIss\fP is not NULL and the \fIss_flags\fP field contains
+an invalid flag.
+.TP
+.B ENOMEM
+The specified size of the new alternate signal stack
+.I ss.ss_size
+was less than
+.BR MINSIGSTKSZ .
+.TP
+.B EPERM
+An attempt was made to change the alternate signal stack while
+it was active (i.e., the thread was already executing
+on the current alternate signal stack).
+.SH ATTRIBUTES
+For an explanation of the terms used in this section, see
+.BR attributes (7).
+.TS
+allbox;
+lbx lb lb
+l l l.
+Interface Attribute Value
+T{
+.na
+.nh
+.BR sigaltstack ()
+T} Thread safety MT-Safe
+.TE
+.SH STANDARDS
+POSIX.1-2008.
+.P
+.B SS_AUTODISARM
+is a Linux extension.
+.SH HISTORY
+POSIX.1-2001, SUSv2, SVr4.
+.SH NOTES
+The most common usage of an alternate signal stack is to handle the
+.B SIGSEGV
+signal that is generated if the space available for the
+standard stack is exhausted: in this case, a signal handler for
+.B SIGSEGV
+cannot be invoked on the standard stack; if we wish to handle it,
+we must use an alternate signal stack.
+.P
+Establishing an alternate signal stack is useful if a thread
+expects that it may exhaust its standard stack.
+This may occur, for example, because the stack grows so large
+that it encounters the upwardly growing heap, or it reaches a
+limit established by a call to \fB\%setrlimit(RLIMIT_STACK, &rlim)\fP.
+If the standard stack is exhausted, the kernel sends
+the thread a \fBSIGSEGV\fP signal.
+In these circumstances the only way to catch this signal is
+on an alternate signal stack.
+.P
+On most hardware architectures supported by Linux, stacks grow
+downward.
+.BR sigaltstack ()
+automatically takes account
+of the direction of stack growth.
+.P
+Functions called from a signal handler executing on an alternate
+signal stack will also use the alternate signal stack.
+(This also applies to any handlers invoked for other signals while
+the thread is executing on the alternate signal stack.)
+Unlike the standard stack, the system does not
+automatically extend the alternate signal stack.
+Exceeding the allocated size of the alternate signal stack will
+lead to unpredictable results.
+.P
+A successful call to
+.BR execve (2)
+removes any existing alternate
+signal stack.
+A child process created via
+.BR fork (2)
+inherits a copy of its parent's alternate signal stack settings.
+The same is also true for a child process created using
+.BR clone (2),
+unless the clone flags include
+.B CLONE_VM
+and do not include
+.BR CLONE_VFORK ,
+in which case any alternate signal stack that was established in the parent
+is disabled in the child process.
+.P
+.BR sigaltstack ()
+supersedes the older
+.BR sigstack ()
+call.
+For backward compatibility, glibc also provides
+.BR sigstack ().
+All new applications should be written using
+.BR sigaltstack ().
+.SS History
+4.2BSD had a
+.BR sigstack ()
+system call.
+It used a slightly
+different struct, and had the major disadvantage that the caller
+had to know the direction of stack growth.
+.SH BUGS
+In Linux 2.2 and earlier, the only flag that could be specified
+in
+.I ss.sa_flags
+was
+.BR SS_DISABLE .
+In the lead up to the release of the Linux 2.4 kernel,
+.\" Linux 2.3.40
+.\" After quite a bit of web and mail archive searching,
+.\" I could not find the patch on any mailing list, and I
+.\" could find no place where the rationale for this change
+.\" explained -- mtk
+a change was made to allow
+.BR sigaltstack ()
+to allow
+.I ss.ss_flags==SS_ONSTACK
+with the same meaning as
+.I ss.ss_flags==0
+(i.e., the inclusion of
+.B SS_ONSTACK
+in
+.I ss.ss_flags
+is a no-op).
+On other implementations, and according to POSIX.1,
+.B SS_ONSTACK
+appears only as a reported flag in
+.IR old_ss.ss_flags .
+On Linux, there is no need ever to specify
+.B SS_ONSTACK
+in
+.IR ss.ss_flags ,
+and indeed doing so should be avoided on portability grounds:
+various other systems
+.\" See the source code of Illumos and FreeBSD, for example.
+give an error if
+.B SS_ONSTACK
+is specified in
+.IR ss.ss_flags .
+.SH EXAMPLES
+The following code segment demonstrates the use of
+.BR sigaltstack ()
+(and
+.BR sigaction (2))
+to install an alternate signal stack that is employed by a handler
+for the
+.B SIGSEGV
+signal:
+.P
+.in +4n
+.EX
+stack_t ss;
+\&
+ss.ss_sp = malloc(SIGSTKSZ);
+if (ss.ss_sp == NULL) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+}
+\&
+ss.ss_size = SIGSTKSZ;
+ss.ss_flags = 0;
+if (sigaltstack(&ss, NULL) == \-1) {
+ perror("sigaltstack");
+ exit(EXIT_FAILURE);
+}
+\&
+sa.sa_flags = SA_ONSTACK;
+sa.sa_handler = handler(); /* Address of a signal handler */
+sigemptyset(&sa.sa_mask);
+if (sigaction(SIGSEGV, &sa, NULL) == \-1) {
+ perror("sigaction");
+ exit(EXIT_FAILURE);
+}
+.EE
+.in
+.SH SEE ALSO
+.BR execve (2),
+.BR setrlimit (2),
+.BR sigaction (2),
+.BR siglongjmp (3),
+.BR sigsetjmp (3),
+.BR signal (7)