The focus of these discussions is on dealing with stack limits in a multithreaded environment; however, the same information applies to singlethreaded environments. Although this calling standard is compatible with a multithreaded execution environment, the detailed mechanisms, data structures, and procedures that support this capability are not specified in the standard.
For a multithreaded environment, the following characteristics are assumed:
Detection of a stack overflow condition is important. If a stack overflow
is not detected, a thread that is writing into what it considered to be stack
storage could modify data allocated in that memory for some other purpose.
The results of such a situation would most likely be unpredictable and undesirable.
In some cases, the overflow could result in unreproducible application failures.
Checking for stack overflow is a requirement for procedures that might
execute in a multithreaded environment.
The Digital UNIX calling standard does not require a reserve region.
The general strategy is to access each page of memory down to, and possibly
including, the page corresponding to the intended new value for the stack
pointer (SP). If the stack
is to be extended by an amount larger
than the size of a memory page, a series of accesses is required that works
from higher-addressed pages to lower-addressed pages. Any access that results
in a memory access violation indicates that the code has made an invalid attempt
to extend the stack of the current thread.
There are two methods for stack-limit checking: implicit and explicit.
In addition, the stack reserve region can be checked. The following sections
describe each type of checking.
Generally, the stack frame layout (shown in Section 3.1.2)
and entry code rules (described in Section 3.2.6.1) do
not make it feasible to guarantee access to the lowest address of a new stack
region without introducing an extra access solely for that purpose. Consequently,
this calling standard uses the second strategy. Although the maximum amount
of implicit stack extension is smaller, the check is achieved at no additional
cost.
This calling standard requires the minimum guard region
size to be 8192 bytes, which
is the size of the smallest memory protection granularity allowed by the Alpha
architecture.
These factors are the basis for the following rule: If the stack is
being extended
by an amount less than or equal to
4096 and no reserve region is required, no explicit stack-limit checking is
required.
However, because asynchronous interrupts and calls to other procedures
can also cause stack extension without explicit stack limit checking, stack
extension with implicit limit checking must follow a strict set of conventions:
These conventions ensure that the stack pointer
will not be decremented
so far that it points to accessible storage beyond the stack limit without
having the error detected by one of the following:
As a matter of practice, the system can provide multiple guard pages
in the guard region. When a stack overflow is detected as a result of access
to the guard region, one or more guard pages can be unprotected for use by
the exception handling facility, and one or more guard pages can remain protected
to provide implicit stack limit checking during exception processing. Note
that the size of the guard region and the number of guard pages is defined
by the system, not by this calling standard.
The first access must occur between SP and SP4096
because, in the absence of more specific information, the previous guaranteed
access relative to the current stack pointer
might be as much as 4096 bytes greater than the
current stack pointer address. The last access must be within 4096 bytes
of the intended new value of the stack pointer. These accesses must occur
in order, starting with the highest-addressed segment and working toward the
lowest-addressed segment.
A simple algorithm that satisfies these rules (but can result in twice
the minimum number of accesses) calls for performing a sequence of accesses
in a loop starting with the previous value of SP and then decrementing by
the minimum no-check extension size (4096) up to, but not including, the first
value that is less than the new value for the stack pointer.
The stack must not be extended incrementally in procedure prologues.
A procedure prologue that needs to extend the stack by an amount which is
unknown at compile time or of a known size greater than the minimum implicit
check size (4096) must test new stack segments (as described previously) in
a loop that does not modify SP. The procedure prologue must then update the
stack with one instruction that copies the new stack pointer value into SP.
Note that if a transparent stack extension
is performed, a stack overflow that
occurs in a called procedure might cause the stack to be extended. Therefore,
the TEB stack limit value must be considered volatile and potentially modified
by external procedure calls as well as by the handling of exceptions.
6.1 Stack Limit Checking
A program that is otherwise correct
can fail because of stack overflow. A stack overflow
occurs when extension of the stack (accomplished
by decrementing the stack pointer, SP) allocates addresses not currently reserved
for the current thread's stack.6.1.1 Stack Region Definitions
The various stack regions are defined as follows:
6.1.2 Methods for Stack Limit Checking
Because memory can be accessible
at addresses lower than those occupied by the guard region, compilers must
generate code to ensure that the stack is never extended past the guard pages
into accessible memory not allocated to the thread's stack.Note
6.1.2.1 Implicit Stack Limit Checking
There are two mutually
exclusive strategies for implicit stack limit checking:
6.1.2.2 Explicit Stack Limit Checking
If the stack is being extended
by an amount that is unknown at compile
time or of a known size greater than the maximum implicit check size (4096),
a code sequence that follows the rules for implicit stack limit checking can
be executed in a loop to access the new stack region incrementally in segments
smaller than or equal to the minimum page size (8192 bytes). At least one
access must occur in each such segment.Note
6.1.3 Stack Reserve Region Checking
The size of the stack reserve
region, if one exists, must be included in the increment size used for stack
limit checks. However, the size is not included in the amount by which the
stack is actually extended.
Depending on the reserve size, stack
reserve region checking could completely eliminate the ability to use implicit
stack limit checking.6.2 Stack Overflow Handling
If a stack overflow is detected, one
of the following conditions occurs:
sigstack
(2) reference page.)