Stack Allocation

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
allocated page
allocated page
guard page
unallocated stack space

 
allocated page
allocated page
allocated page
new guard page
unallocated stack space

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