By
default, the linker reserves 1 MB of stack space and commits
(physically allocates) one page. The page with the largest
address is committed, and the page below it is set up as a guard
page. No other pages are committed.
By
default, the stack is fully allocated for the first thread of a
process. For all threads other than the first, the operating
system allocates the stack as a sparse object. The total stack
size is rounded up to the nearest multiple of 4K from the size
you specified. The page with the largest address is committed,
and the page below it is set up as a guard page. No other pages
are committed.
When the guard page is accessed, an out of stack exception is generated:
STATUS_GUARD_PAGE_VIOLATION
XCPT_GUARD_PAGE_VIOLATION
The system responds by attempting to get another guard page below the one previously allocated. If this attempt is successful, the original guard page becomes a normal stack page and the next uncommitted page becomes the new guard page:
| attempt to access guard page | after stack growth | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
This process continues until a new guard page can no longer be allocated.
If the system cannot set a new guard page because it has reached the size limit of the stack, a guard page allocation failure exception is generated:
(STATUS_STACK_OVERFLOW)
XCPT_STACK_OVERFLOW
(The same exception is generated when the _alloca function runs out of memory.)
The last
4K of the stack (the final guard page) is reserved to allow
handling of exception condition. If a guard page exception occurs
and not enough stack remains to handle the exception, the program
is terminated.
![]()
Stack Probes
Signal and
Exception Handling