It is extremely difficult to detect that the stack is full, but not carried at all. One of the biggest problems is that the stack frames are variable in size (especially when using variable-length arrays, which are actually just a standard way to do what you did before using alloca()
), so you cannot use simple proxies as the number of stack frames.
One of the simplest methods that are mostly portable is to place a variable (possibly of type char
so that the pointer to it is char*
) at a known depth in the stack and then measure the distance from which point to a variable (of the same type) in the current stack stack using simple pointer arithmetic. Add to the estimate of how much space you are going to allocate, and you have a good guess that the stack is about to explode on you. The problems with this are that you don’t know the direction of the stack growth (no, they do not all grow in the same direction!) And developing the size of the stack space itself is pretty messy (you can try things like system restrictions, but they really quite uncomfortable). Plus, the hacking factor is very high.
Another trick I saw used only for 32-bit Windows was trying to alloca()
enough space and handle a system exception that could have occurred if there was not enough space.
int have_enough_stack_space(void) { int enough_space = 0; __try { alloca(SOME_VALUE_THAT_MEANS_ENOUGH_SPACE); enough_space = 1; } __except (EXCEPTION_EXECUTE_HANDLER) {} return enough_space; }
This code is very portable (for example, it doesn’t expect that it works on 64-bit Windows), and to build with the older gcc some nasty built-in assembler is required! Structured Exclusion Management (this usage) is one of the blackest black arts in Windows. (And do not return
from within the __try
construct.)
source share