25.9 Using a Separate Signal Stack

A signal stack is a special area of memory to be used as the execution stack during signal handlers. It should be fairly large, to avoid any danger that it will overflow in turn; the macro SIGSTKSZ is defined to a canonical size for signal stacks. You can use malloc to allocate the space for the stack. Then call sigaltstack or sigstack to tell the system to use that space for the signal stack.

You don’t need to write signal handlers differently in order to use a signal stack. Switching from one stack to the other happens automatically. (Some non-GNU debuggers on some machines may get confused if you examine a stack trace while a handler that uses the signal stack is running.)

There are two interfaces for telling the system to use a separate signal stack. sigstack is the older interface, which comes from 4.2 BSD. sigaltstack is the newer interface, and comes from 4.4 BSD. The sigaltstack interface has the advantage that it does not require your program to know which direction the stack grows, which depends on the specific machine and operating system.

Data Type: stack_t

This structure describes a signal stack. It contains the following members:

void *ss_sp

This points to the base of the signal stack.

size_t ss_size

This is the size (in bytes) of the signal stack which ‘ss_sp’ points to. You should set this to however much space you allocated for the stack.

There are two macros defined in signal.h that you should use in calculating this size:

SIGSTKSZ

This is the canonical size for a signal stack. It is judged to be sufficient for normal uses.

MINSIGSTKSZ

This is the amount of signal stack space the operating system needs just to implement signal delivery. The size of a signal stack must be greater than this.

For most cases, just using SIGSTKSZ for ss_size is sufficient. But if you know how much stack space your program’s signal handlers will need, you may want to use a different size. In this case, you should allocate MINSIGSTKSZ additional bytes for the signal stack and increase ss_size accordingly.

int ss_flags

This field contains the bitwise OR of these flags:

SS_DISABLE

This tells the system that it should not use the signal stack.

SS_ONSTACK

This is set by the system, and indicates that the signal stack is currently in use. If this bit is not set, then signals will be delivered on the normal user stack.

Function: int sigaltstack (const stack_t *restrict stack, stack_t *restrict oldstack)

Preliminary: | MT-Safe | AS-Unsafe lock/hurd | AC-Unsafe lock/hurd | See POSIX Safety Concepts.

The sigaltstack function specifies an alternate stack for use during signal handling. When a signal is received by the process and its action indicates that the signal stack is used, the system arranges a switch to the currently installed signal stack while the handler for that signal is executed.

If oldstack is not a null pointer, information about the currently installed signal stack is returned in the location it points to. If stack is not a null pointer, then this is installed as the new stack for use by signal handlers.

The return value is 0 on success and -1 on failure. If sigaltstack fails, it sets errno to one of these values:

EINVAL

You tried to disable a stack that was in fact currently in use.

ENOMEM

The size of the alternate stack was too small. It must be greater than MINSIGSTKSZ.

Here is the older sigstack interface. You should use sigaltstack instead on systems that have it.

Data Type: struct sigstack

This structure describes a signal stack. It contains the following members:

void *ss_sp

This is the stack pointer. If the stack grows downwards on your machine, this should point to the top of the area you allocated. If the stack grows upwards, it should point to the bottom.

int ss_onstack

This field is true if the process is currently using this stack.

Function: int sigstack (struct sigstack *stack, struct sigstack *oldstack)

Preliminary: | MT-Safe | AS-Unsafe lock/hurd | AC-Unsafe lock/hurd | See POSIX Safety Concepts.

The sigstack function specifies an alternate stack for use during signal handling. When a signal is received by the process and its action indicates that the signal stack is used, the system arranges a switch to the currently installed signal stack while the handler for that signal is executed.

If oldstack is not a null pointer, information about the currently installed signal stack is returned in the location it points to. If stack is not a null pointer, then this is installed as the new stack for use by signal handlers.

The return value is 0 on success and -1 on failure.