Stack overflow: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
tolto wlink che non indirizza alla pagina di spiegazione della parola
Migliorato la pagina
 
(30 versioni intermedie di 21 utenti non mostrate)
Riga 1:
{{nota disambigua|il sito di Q&A omonimo|Stack Overflow (sito)|Stack Overflow}}
In [[informatica]], uno '''''stack overflow''''' avviene quando è richiesto l'uso di una quantità troppo elevata di [[Memoria (informatica)|memoria]] nello [[Allocazione dinamica della memoria|''stack'']].
 
In molti [[linguaggi di programmazione]], lo [[Call stack|stack delle chiamate]] contiene una quantità limitata di memoria, che viene fissata di solito all'avvio del programma. La dimensione dello stack dipende da molteplici fattori, inclusi il linguaggio di programmazione, l'[[Architettura (computer)|architettura]] della macchina, l'uso del ''[[multithreading]],'' e la disponibilità di memoria nel sistema. Quando vieneè usata troppa memoria nello ''stack'' si dice che avviene un ''[[Overflow aritmetico|overflow]]'', e tipicamente come conseguenza di questa situazione si verifica un [[Crash (informatica)|crash]] del programma<ref name="fortran1">{{Cita web|cognome=Burley|nome=James Craig|titolo=Using and Porting GNU Fortran|url=http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.95.2/html_node/g77_597.html|data=1º giugno 1991|urlmorto=sì|urlarchivio=https://www.webcitation.org/6BBbWyyAU?url=http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.95.2/html_node/g77_597.html|dataarchivio=5 ottobre 2012}}</ref>. Questa classe di [[bug]] solitamente è causata da uno dei due tipi di errori di programmazione<ref name="devx">{{Cita web|cognome=Danny|nome=Kalev|titolo=Understanding Stack Overflow|url=http://www.devx.com/tips/Tip/14276|data=5 settembre 2000}}</ref>: la ricorsione infinita e l'uso di variabili di stack molto grandi.
| cognome = Burley
| nome = James Craig
| titolo = Using and Porting GNU Fortran
| url= http://sunsite.ualberta.ca/Documentation/Gnu/gcc-2.95.2/html_node/g77_597.html
| data=1 giugno 1991 }}</ref>. Questa classe di [[bug]] solitamente è causata da uno dei due tipi di errori di programmazione<ref name="devx">
{{Cita web
| cognome = Danny
| nome = Kalev
| titolo = Understanding Stack Overflow
| url=http://www.devx.com/tips/Tip/14276
| data=5 settembre 2000 }}</ref>: la ricorsione infinita e l'uso di variabili di stack molto grandi.
 
== Ricorsione infinita ==
{{Vedi anche|Loop infinito}}
La causa più comune di uno stack overflow è una [[ricorsione]] con profondità eccessiva o infinita.
 
I linguaggi che implementano la tecnica [[Algoritmo_ricorsivo#Eliminazione_della_ricorsione|''tail recursion'']], come ad esempio il linguaggio [[Scheme]], permettono una particolare ricorsione infinita che possapuò essere eseguita senza ''stack overflow''. Questo avviene poiché le chiamate che fanno uso di ''tail- recursion'' non richiedono uno spazio aggiuntivo nello ''stack''<ref name="tailRecur">{{Cita web|titolo=An Introduction to Scheme and its Implementation|url=http://www.federated.com/~jim/schintro-v14/schintro_73.html|data=19 febbraio 1997|urlmorto=sì|urlarchivio=https://web.archive.org/web/20070810213035/http://www.federated.com/~jim/schintro-v14/schintro_73.html|dataarchivio=10 agosto 2007}}</ref>.
| titolo = An Introduction to Scheme and its Implementation
| url=http://www.federated.com/~jim/schintro-v14/schintro_73.html
| data=19 febbraio 1997 }} </ref>
.
 
== Variabili di stack molto grandi ==
L'altra causa principale dello ''stack overflow'' è il tentativo di allocare più memoria nello stack di quella chedisponibile ènello disponibilestack. Questo avviene tipicamente quando si crea un [[array]] di [[Variabile (informatica)#Visibilità di una variabile|variabili locali]] molto grande. Per questo motivo gli array più grandi di qualche [[kilobyte]] dovrebbero essere allocati [[allocazioneAllocazione dinamica della memoria|allocati dinamicamente]] anziché allocarli come variabili locali<ref name="onlamp">{{Cita web|cognome=Feldman|nome=Howard|titolo=Modern Memory Management, Part 2|url=http://www.onlamp.com/pub/a/onlamp/2005/11/23/memory-management-2.html|data=23 novembre 2005|accesso=10 novembre 2009|dataarchivio=20 settembre 2012|urlarchivio=https://web.archive.org/web/20120920112622/http://onlamp.com/pub/a/onlamp/2005/11/23/memory-management-2.html|urlmorto=sì}}</ref>.
| cognome = Feldman
| nome = Howard
| titolo = Modern Memory Management, Part 2
| url=http://www.onlamp.com/pub/a/onlamp/2005/11/23/memory-management-2.html
| data=23 novembre 2005 }} </ref>.
 
== Cause che possono ridurre la dimensione dello stack disponibile e quindi rendere più probabile uno ''stack overflow'' ==
Gli ''stack overflow'' sono aggravati da qualsiasi cosa riduca la dimensione effettiva dello ''stack'' di un programma.
 
Ad esempio un programma che viene eseguito come ''[[Thread (informatica)|thread]]'' singolo potrebbe funzionare correttamente, ma se lo stesso programma vieneè eseguito con ''thread'' multipli si verifica un ''crash'' del programma. Ciò avviene, perché molti programmi che usano i ''thread'' hanno a disposizione uno ''stack'' più piccolo per ogni singolo ''thread'' rispetto ada un programma che non usiusa i ''thread''.
 
Allo stesso modo, chi studia lo [[sviluppo (informatica)|sviluppo]] di un [[kernel]] è invitato a non usare [[algoritmo ricorsivo|algoritmi ricorsivi]] e [[buffer]] molto grandi nello stack<ref name="apple1">{{Cita web|editore=[[Apple Inc]].|titolo=Kernel Programming Guide: Performance and Stability Tips|url=https://developer.apple.com/DOCUMENTATION/Darwin/Conceptual/KernelProgramming/style/chapter_5_section_5.html|data=7 novembre 2006|urlmorto=sì|urlarchivio=https://web.archive.org/web/20081207013401/http://developer.apple.com/DOCUMENTATION/Darwin/Conceptual/KernelProgramming/style/chapter_5_section_5.html|dataarchivio=7 dicembre 2008}}</ref><ref name="xenotime">{{Cita web|cognome=Dunlap|nome=Randy|titolo=Linux Kernel Development: Getting Started|url=http://www.xenotime.net/linux/mentor/linux-mentoring.pdf|data=19 maggio 2005|urlmorto=sì|urlarchivio=https://web.archive.org/web/20120227142532/http://www.xenotime.net/linux/mentor/linux-mentoring.pdf|dataarchivio=27 febbraio 2012}}</ref>.
Allo stesso modo, le persone che si avvicinano allo [[sviluppo (informatica)| sviluppo]] di un [[kernel]] sono invitate a non usare [[algoritmo ricorsivo|algoritmi ricorsivi]] e [[buffer]] molto grandi nello stack<ref name="apple1">{{Cita web
| editore= [[Apple Inc]].
| titolo = Kernel Programming Guide: Performance and Stability Tips
| url=http://developer.apple.com/DOCUMENTATION/Darwin/Conceptual/KernelProgramming/style/chapter_5_section_5.html
| data=7 novembre 2006 }} </ref><ref name="xenotime">{{Cita web
| cognome = Dunlap
| nome = Randy
| titolo = Linux Kernel Development: Getting Started
| url=http://www.xenotime.net/linux/mentor/linux-mentoring.pdf
| data=19 maggio 2005 }} </ref>.
 
== Esempi nel linguaggio [[C (linguaggio)|C]]/[[C++]] ==
=== Ricorsione infinita con una funzione ===
 
<syntaxhighlight lang="c" line="1" copy=1>
===Ricorsione infinita con una funzione===
void gf(void) {
<source lang="c">
void f() {;
}
f();
int main(void) {
}
f();
int main(void) {
return f()0;
}
return 0;
</syntaxhighlight>
}
</source>
 
Questo frammento di codice invoca la [[funzione (informatica)|funzione]] <code>f()</code>, e la funzione <code>f()</code> a sua volta richiama se stessa, generando in tal modo una ricorsione infinita.
 
=== Ricorsione infinita con due funzioni (mutuale) ===
<sourcesyntaxhighlight lang="c" line="1" copy=1>
void f(void);
void g(void);
 
int main(void) {
f();
 
return 0;
}
intvoid mainf(void) {
fg();
}
return 0;
}
void fg(void) {
gf();
}
</syntaxhighlight>
void g(void) {
f();
}
</source>
 
La funzione <code>f()</code> e la funzione <code>g()</code> si richiamano continuamente a vicenda, finché non si verifica lo ''stack overflow''.
 
=== Variabile nello stack eccessivamente grande ===
<sourcesyntaxhighlight lang="c" line="1" copy=1>
int main(void) {
double n[10000000];
return 0;
}
</syntaxhighlight>
</source>
 
L'array dichiarato in questo frammento di codice richiede più memoria di quella disponibile nello ''stack'', causando così uno ''stack overflow''.
 
== Note ==
<references />
 
== Voci correlate ==
* [[Heap overflow]]
* [[Buffer overflow]]
 
== Collegamenti esterni ==
* {{FOLDOC||stack overflow}}
 
{{Portale|informatica}}
 
[[Categoria:Gestione del software]]
[[Categoria:Terminologia informatica]]
 
[[cs:Přetečení zásobníku]]
[[en:Stack buffer overflow]]
[[es:Desbordamiento de pila]]
[[fr:Dépassement de pile]]
[[ja:スタックオーバーフロー]]
[[ko:스택 버퍼 오버플로우]]
[[pl:Przepełnienie stosu]]
[[uk:Переповнення стекового буфера]]