Uruchomiłem program z wywołaniem rekurencyjnym w systemie operacyjnym Debian. Mój rozmiar stosu jestDlaczego występuje przepełnienie stosu przy różnym zużyciu stosu przy każdym uruchomieniu zamiast ustalonej kwoty?
-s: stack size (kbytes) 8192
ile nauczyłem, rozmiar stosu musi być stałe i powinny być takie same, które muszą zostać przypisane do programu na każdym biegu, chyba że jest to wyraźnie zmieniło ulimit
.
Funkcja rekurencyjna jest zmniejszana o podaną liczbę aż do 0
. To jest napisane w Rust.
fn print_till_zero(x: &mut i32) {
*x -= 1;
println!("Variable is {}", *x);
while *x != 0 {
print_till_zero(x);
}
}
i wartość jest przekazywana jako
static mut Y: i32 = 999999999;
unsafe {
print_till_zero(&mut Y);
}
Ponieważ stos przydzielone do programu jest stała, i teoretycznie nie musi się zmienić, spodziewałem przepełnienie stosu przy tej samej wartości za każdym razem, ale nie jest, co oznacza, że alokacja jest variadic.
przejazd 1:
====snip====
Variable is 999895412
Variable is 999895411
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
uruchomić 2:
====snip====
Variable is 999895352
Variable is 999895351
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
chociaż różnica jest subtelna, nie powinien on być najlepiej powodując przepełnienie stosu w tej samej wielkości? Dlaczego dzieje się to w różnym czasie, sugerując różne rozmiary stosu w każdym biegu? To nie jest specyficzne dla Rust; Podobne zachowanie obserwuje się w 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
wyjściowa:
przejazd 1:
738551,738550,[1] 7052 segmentation fault
uruchomić 2:
738438,738437,[1] 7125 segmentation fault
Przepełnienie nastąpi tylko wtedy, gdy błędy strony stosu. Oznacza to, że wskaźnik stosu przechodzi na stronę niezaładowaną/odłożoną.Miejsce rozpoczęcia stosu nie musi znajdować się na dokładnej granicy strony, ale może zależeć od miejsca załadowania programu, więc wyzwalacz warunku przepełnienia (błąd strony) będzie inny. –
Czy [this] (http://stackoverflow.com/questions/31180563/why-are-stackoverflow-errors-chaotic) wygląda podobnie? – Art
@RichardCritten Czy więc strona poza przyznanym rozmiarem stosu musi być niezobowiązującą stroną w prawo? Proszę popraw mnie jeżeli się mylę. – nohup