User-Level Native Thread Primitives (GThread) Library White Paper (G06.27+, H06.03+, J06.03+)
User-Level Native Thread Primitives (GThread Library) 02/15/2012
540065-004 Page 43 of 44
too short, it can be skipped over (native stack frames often contain “gaps” in which
nothing is stored), but a longer guard area requires more time to validate. Furthermore,
while the TNS/R architecture involves a single memory stack growing towards lower
memory addresses, TNS/E introduces a new architecture (two stacks, growing in opposite
directions) requiring two guard areas.
2) Clients perform a simple check by retrieving the StackUsed element of the thread control
block and validate that it is less than the stack space allocated. Since the value of
StackUsed is only updated on a call to GTHREAD_SETJMP_ (typically prior to
switching thread contexts) overflow detection is very limited. The approach is faster than
the guard page approach, but it does not provide detection of a stack overflow that could
have occurred prior to the call to GTHREAD_SETJMP_. Indeed, it is common for a
thread to suspend at a “quiet” point, when the stack occupancy is much smaller than
when the thread was active.
3) Clients perform a ‘pre-check’ of the stack by determining how much additional stack
growth occurs along a specific code path. Certain threading clients use this approach
prior to launching methods of known stack frame size. This predictive method has
advantages over the guard area or StackUsed approaches in that it permits the client to
handle ‘potential’ overflows gracefully, rather than dealing with an overflow occurrence.
The approach does not handle a ‘miscalculation’ by the client (and the resulting
overflow), or situations where the stack growth is unknown.
Both the second and third approaches are more complicated on TNS/E because there are two
stacks that somewhat independently approach their limits. Limited support for these approaches is
provided by the GTH_STACK_CHECK_ACTIVE_, GTH_STACK_CHECK_THREAD_,
GTH_STACK_CHECK_ACTIVE2_, and GTH_STACK_CHECK_THREAD2_ interfaces.
A basic problem common to all these approaches is that, when an overflow actually occurs, the
program response to the overflow is non-deterministic; it could range anywhere between no effect
(corruption did not affect active data), to a very serious data corruption or (in privileged threads)
a CPU halt. The following changes only address preserving the current level of overflow
protection provided.
Clients using the ‘guard area’ approach to stack overflow detection need to modify code to
provide guard areas that ‘bracket’ the allocated stack space (the client can no longer rely on just
checking the lower address range of a stack). Since this is different from what is required for
TNS/R, code associated with assigning and checking the additional guard area should be placed
within ‘TNS/E only’ compiler toggles.
Clients using either the StackUsed or pre-check approaches, both of which directly access thread
control block elements as part of the overflow determination, need to change to use the following
interfaces:
For StackUsed checking:
GTH_STACK_CHECK_THREAD_( GThread_CB cb, int32 stack_delta )
GTH_STACK_CHECK_THREAD2_(GThread_CB cb, int32 mem_delta, int32 reg_delta)