I am running a program with a recursive call on a Debian OS. My stack size is
-s: stack size (kbytes) 8192
As far as I've learned, the stack size must be fixed, and should be the same that must be allocated to a program at every run unless it is explicitly changed with ulimit
.
The recursive function is a decrements a given number until it reaches 0
. This is written in Rust.
fn print_till_zero(x: &mut i32) {
*x -= 1;
println!("Variable is {}", *x);
while *x != 0 {
print_till_zero(x);
}
}
and the value is passed as
static mut Y: i32 = 999999999;
unsafe {
print_till_zero(&mut Y);
}
Since the stack allocated to the program is fixed, and theoretically must not change, I was expecting a stack overflow at the same value each time, but it is not, which means the stack allocation is variadic.
Run 1:
====snip====
Variable is 999895412
Variable is 999895411
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Run 2:
====snip====
Variable is 999895352
Variable is 999895351
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Although the difference is subtle, shouldn't it be ideally causing the stack overflow at the same variable? Why is it happening at different times, implying different stack size for each run? This is not specific to Rust; a similar behavior is observed in C:
#pragma GCC push_options
#pragma GCC optimize ("O0")
#include<stdio.h>
void rec(int i){
printf("%d,",i);
rec(i-1);
fflush(stdout);
}
int main(){
setbuf(stdout,NULL);
rec(1000000);
}
#pragma GCC pop_options
Output:
Run 1:
738551,738550,[1] 7052 segmentation fault
Run 2:
738438,738437,[1] 7125 segmentation fault