The Linux Programming Interface

(nextflipdebug5) #1
Signals: Signal Handlers 435

specifying NULL for the sigstack argument. Otherwise, each of these arguments
points to a structure of the following type:


typedef struct {
void *ss_sp; /* Starting address of alternate stack */
int ss_flags; /* Flags: SS_ONSTACK, SS_DISABLE */
size_t ss_size; /* Size of alternate stack */
} stack_t;

The ss_sp and ss_size fields specify the size and location of the alternate signal stack.
When actually using the alternate signal stack, the kernel automatically takes care
of aligning the value given in ss_sp to an address boundary that is suitable for the
hardware architecture.
Typically, the alternate signal stack is either statically allocated or dynamically
allocated on the heap. SUSv3 specifies the constant SIGSTKSZ to be used as a typical
value when sizing the alternate stack, and MINSIGSTKSZ as the minimum size required
to invoke a signal handler. On Linux/x86-32, these constants are defined with the
values 8192 and 2048, respectively.
The kernel doesn’t resize an alternate signal stack. If the stack overflows the
space we have allocated for it, then chaos results (e.g., overwriting of variables
beyond the limits of the stack). This is not usually a problem—because we normally
use an alternate signal stack to handle the special case of the standard stack over-
flowing, typically only one or a few frames are allocated on the stack. The job of the
SIGSEGV handler is either to perform some cleanup and terminate the process or to
unwind the standard stack using a nonlocal goto.
The ss_flags field contains one of the following values:


SS_ONSTACK
If this flag is set when retrieving information about the currently estab-
lished alternate signal stack (old_sigstack), it indicates that the process is
currently executing on the alternate signal stack. Attempts to establish a
new alternate signal stack while the process is already running on an alter-
nate signal stack result in an error (EPERM) from sigaltstack().


SS_DISABLE
Returned in old_sigstack, this flag indicates that there is no currently estab-
lished alternate signal stack. When specified in sigstack, this disables a
currently established alternate signal stack.


Listing 21-3 demonstrates the establishment and use of an alternate signal stack.
After establishing an alternate signal stack and a handler for SIGSEGV, this program
calls a function that infinitely recurses, so that the stack overflows and the process
is sent a SIGSEGV signal. When we run the program, this is what we see:


$ ulimit -s unlimited
$ ./t_sigaltstack
Top of standard stack is near 0xbffff6b8
Alternate stack is at 0x804a948-0x804cfff
Call 1 - top of stack near 0xbff0b3ac
Call 2 - top of stack near 0xbfe1714c
Many intervening lines of output removed
Call 2144 - top of stack near 0x4034120c
Free download pdf