For following code, the last output (which is max stack depth is keeping changing):
#include <stdio.h>
#include <windows.h>
int depth=0;
void func(){
int x=depth;
printf("%d\n",depth++);
func();
printf("%d\n",x);
}
int main(){
func();
return 0;
}
// compiled by cl /F 1 test.c
The first time is 3717
, the second is 3700
, the third is 3695
.
I thought for constant stack size, max stack depth should be constant. but why is it changing?
On the Microsoft Windows platform running x86/x64 CPUs, the memory reserved for the stack always ends on a page boundary and a stack overflow will occur when the stack grows beyond that page boundary. A page is normally 4096 bytes of memory.
Without Address Space Layout Randomization (ASLR), the stack will also start at a page boundary, which means the maximum stack size will be a multiple of the page size. By default, the stack has a maximum size of 1 MiB, which is 256 pages of 4096 bytes.
However, with ASLR active, the starting address of the stack is no longer on a page boundary, but is random. Since the memory reserved for the stack still ends on a page boundary, this means that the maximum stack size is random and is no longer a multiple of the page size.
This randomness of the maximum stack size is the reason why the time of the stack overflow is also random.
The Microsoft linker builds executable files with ASLR enabled by default. In order to disable ASLR, you must add the /DYNAMICBASE:NO
option when invoking the linker. Afterwards, the stack overflow should occur at exactly the same time whenever you run your program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With