X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=483fbb9a9bbdd10cb8b06e3b7e5398425e31dcab;hp=935f34e5f6c67f14f4b7d3dc87781408e0e4345d;hb=cf7518466ba15ab1759e5bc312ab99798b8cf2ac;hpb=2bb235e9ba8e8d532251205d30b82455dc119894 diff --git a/process.tex b/process.tex index 935f34e..483fbb9 100644 --- a/process.tex +++ b/process.tex @@ -380,7 +380,10 @@ programma C viene suddiviso nei seguenti segmenti: del chiamante (tipo il contenuto di alcuni registri della CPU). Poi la funzione chiamata alloca qui lo spazio per le sue variabili locali: in questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno - della funzione lo spazio è automaticamente rilasciato. + della funzione lo spazio è automaticamente rilasciato. Al ritorno della + funzione lo spazio è automaticamente ripulito. La pulizia in C e C++ viene + fatta dal chiamante.\footnote{a meno che non sia stato specificato + l'utilizzo di una calling convention diversa da quella standard.} La dimensione di questo segmento aumenta seguendo la crescita dello stack del programma, ma non viene ridotta quando quest'ultimo si restringe. @@ -538,15 +541,18 @@ routine di allocazione non più utilizzata, quello che in inglese viene chiamato \textit{memory-leak}, (cioè \textsl{perdita di memoria}). -Un caso tipico che illustra il problema è quello in cui l'allocazione di una -variabile viene fatta da una subroutine per un uso locale, ma la memoria non -viene liberata; la funzione esce e la memoria resta allocata (fino alla -terminazione del processo). Chiamate ripetute alla stessa subroutine -continueranno ad allocarne ancora, causando a lungo andare un esaurimento -della memoria disponibile e l'impossibilità di proseguire il programma. Il -problema è che l'esaurimento che può avvenire in qualunque momento, e senza -nessuna relazione con la subroutine che contiene l'errore, per questo motivo è -sempre complesso trovare un \textit{memory leak}. +Un caso tipico che illustra il problema è quello in cui in una subroutine si +alloca della memoria per uso locale senza liberarla prima di uscire. La +memoria resta così allocata fino alla terminazione del processo. Chiamate +ripetute alla stessa subroutine continueranno ad effettuare altre allocazioni, +causando a lungo andare un esaurimento della memoria disponibile (e la +probabile l'impossibilità di proseguire l'esecuzione programma). + +Il problema è che l'esaurimento della memoria può avvenire in qualunque +momento, in corrispondenza ad una qualunque chiamata di \func{malloc}, che può +essere in una sezione del codice che non ha alcuna relazione con la subroutine +che contiene l'errore. Per questo motivo è sempre molto difficile trovare un +\textit{memory leak}. Per ovviare a questi problemi l'implementazione delle routine di allocazione delle \acr{glibc} mette a disposizione una serie di funzionalità (su cui @@ -1173,7 +1179,7 @@ problematiche generali che possono emergere nella programmazione e di quali precauzioni o accorgimenti occorre prendere per risolverle. Queste problematiche non sono specifiche di sistemi unix-like o multitasking, ma avendo trattato in questo capitolo il comportamento dei processi visti come -entità a se stanti, le riportiamo qui. +entità a sé stanti, le riportiamo qui. \subsection{Il passaggio delle variabili e dei valori di ritorno} @@ -1258,8 +1264,8 @@ inoltre che l'ultimo degli argomenti fissi sia di tipo per compatibilità; ad esempio i tipi \type{float} vengono convertiti automaticamente a \type{double} ed i \type{char} e gli \type{short} ad \type{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso - a se stesso.} il che esclude array, puntatori a funzioni e interi di tipo -\type{char} o \type{short} (con segno o meno). Un'ulteriore restrizione di + a sé stesso.} il che esclude array, puntatori a funzioni e interi di tipo +\type{char} o \type{short} (con segno o meno). Una restrizione ulteriore di alcuni compilatori è di non dichiarare l'ultimo parametro fisso come \type{register}. @@ -1284,7 +1290,7 @@ in generale potrebbero essere stati effettivamente forniti, e nella esecuzione delle \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti saranno ignorati; se invece si richiedono più argomenti di quelli forniti si -otterranno dei valori indefiniti. Nel caso del \cmd{gcc} poi l'uso della macro +otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro \macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per compatibilità. @@ -1334,7 +1340,7 @@ motivo \macro{va\_list} direttamente ad un altra variabile dello stesso tipo. Per risolvere questo problema lo standard ISO C99\footnote{alcuni sistemi che non hanno questa macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome proposto - in una bozza dello standard} ha previsto un'ulteriore macro che permette di + in una bozza dello standard} ha previsto una macro ulteriore che permette di eseguire la copia di un puntatore alla lista degli argomenti: \begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)} Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti @@ -1395,10 +1401,12 @@ dinamicamente con una delle funzioni della famiglia \func{malloc}. \label{sec:proc_longjmp} Il controllo del flusso di un programma in genere viene effettuato con le -varie istruzioni del linguaggio C, la più bistrattata delle quali è il -\code{goto}, ampiamente deprecato in favore di costrutti più puliti; esiste -però un caso in l'uso di questa istruzione porta all'implementazione più -efficiente, quello dell'uscita in caso di errore. +varie istruzioni del linguaggio C; fra queste la più bistrattata è il +\code{goto}, che viene deprecato in favore dei costrutti della programmazione +strutturata, che rendono il codice più leggibile e mantenibile . Esiste però +un caso in cui l'uso di questa istruzione porta all'implementazione più +efficiente e chiara anche dal punto di vista della struttura del programma, +quello dell'uscita in caso di errore. Il C però non consente di effettuare un salto ad una label definita in un'altra funzione, per cui se l'errore avviene in funzioni profondamente @@ -1406,7 +1414,6 @@ annidate occorre usare quello che viene chiamato un salto \textsl{non-locale}; questo viene fatto usando salvando il contesto dello stack nel punto in cui si vuole tornare in caso di errore, e ripristinandolo quando l'occorrenza capita. - La funzione che permette di salvare il contesto dello stack è \func{setjmp}, il cui prototipo è: