X-Git-Url: https://gapil.gnulinux.it/gitweb/?a=blobdiff_plain;f=process.tex;h=c3a801c623fac9ed041d83225c8a023b82824082;hb=db19b7f83b55cfd8add75de54130661a0baeacd3;hp=7260dbb354d5bbb6a55edb9f60900ae9507684fc;hpb=76c2def510b553794baef8313e00d64b75652c3c;p=gapil.git diff --git a/process.tex b/process.tex index 7260dbb..c3a801c 100644 --- a/process.tex +++ b/process.tex @@ -528,20 +528,82 @@ viene opportunamente liberata (quello che in inglese viene chiamato \textit{memory-leak}, traducibile come \textsl{perdita di memoria}). Un caso tipico è quando l'allocazione viene fatta da una subroutine per un uso -locale, ma la memoria non viene liberata una volta usata; in questo caso la -memoria resta allocata, causando a lungo andare un esaurimento della memoria -disponibile con un conseguente crash dell'applicazione in un momento del tutto -scorrelato rispetto al verificarsi della condizione di errore. - +locale, ma la memoria non viene liberata una volta usata; chiamate ripetute +alla stessa suubroutine causeranno a lungo andare un esaurimento della memoria +disponibile, con un conseguente crash dell'applicazione che può avvenire in +qualunque momento senza nessuna relazione con la subroutine che contiene +l'errore. + +Per questo motivo l'implementazione delle routine di allocazione delle glibc +mette a disposizione una serie di funzionalità (su cui torneremo in +\secref{sec:proc_mem_advanced}) che permettono di tracciare le allocazioni e +le disallocazione, e definisce anche una serie di possibili agganci che +permettono di sostituire alle funzioni di libreria una propria versione (che +può essere più o meno specializzata per il debugging). \subsection{La funzione \texttt{alloca}} \label{sec:proc_mem_alloca} +Una alternativa possibile all'uso di \texttt{malloc}, che non soffre del tipo +di problemi di memomry leak descritti in precedenza è la funzione +\texttt{alloca} che invece che allocare la memoria nello heap usa lo il +segmento di stack della funzione corrente. La sintassi è identica: +\begin{prototype}{stdlib.h}{void *alloca(size\_t size)} + Alloca \texttt{size} bytes nel segmento di stack della funzione chiamante. + La memoria non viene inizializzata. + + La funzione restituisce il puntatore alla zona di memoria allocata in caso + di successo e \texttt{NULL} in caso di fallimento, nel qual caso + \texttt{errno} viene settata a \texttt{ENOMEM}. +\end{prototype} +ma in questo caso non è più necessario liberare la memoria in quanto questa +viene rilasciata automaticamente al ritorno della funzione. + +Come è evidente questa funzione ha molti vantaggi, e permette di evitare i +problemi di memory leak non essendo più necessaria la deallocazione esplicita; +una delle ragioni principali per usarla è però che funziona anche quando si +usa \texttt{longjump} per uscire con un salto non locale da una funzione (vedi +\secref{sec:proc_longjmp}), + +Un altro vantaggio e che in Linux la funzione è molto veloce e non viene +sprecato spazio, infatti non è necessario gestire un pool di memoria da +riservare e si evitano anche problemi di frammentazione. + +Gli svantaggi sono che la funzione non è disponibile su tutti gli unix quando +non è possibile aumentare le dimensioni dello stack una volta chiamata una +funzione e quindi l'uso limita la portabilità dei programmi, inoltre se si +cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un +segnale di \textit{segmentation violation} analogo a quello che si avrebbe da +una ricorsione infinita. \subsection{Le funzioni \texttt{brk} e \texttt{sbrk}} \label{sec:proc_mem_sbrk} +L'uso di queste funzioni è necessario solo quando si voglia accedere alle +analoghe system call a cui fanno da interfaccia (ad esempio per implementare +una propria versione di \texttt{malloc}. Le funzione sono: +\begin{prototype}{unistd.h}{int *brk(void end_data_segment)} + Sposta la fine del segmento dei dati all'indirizzo specificato da + \texttt{end_data_segment}. + + La funzione restituisce 0 in caso di successo e -1 in caso di fallimento, + nel qual caso \texttt{errno} viene settata a \texttt{ENOMEM}. +\end{prototype} +\begin{prototype}{unistd.h}{int *sbrk(ptrdiff\_t increment)} + Incrementa lo spazio dati di un programma di \texttt{increment}. + + La funzione restituisce il puntatore all'inzio della nuova zona di memoria + allocata in caso di successo e \texttt{NULL} in caso di fallimento, nel qual + caso \texttt{errno} viene settata a \texttt{ENOMEM}. +\end{prototype} + +Queste funzioni sono state deliberatamente escluse dallo standard POSIX.1 e +per i programmi normali è opportuno usare le funzioni di allocazione standard +descritte in precedenza, che sono costruite su di esse. In genere si usa +\texttt{sbrk} con un valore zero per ottenere l'attuale posizione della fine +del segmento dati. + \subsection{La personalizzazione delle funzioni di allocazione} \label{sec:proc_mem_malloc_custom} @@ -552,7 +614,7 @@ scorrelato rispetto al verificarsi della condizione di errore. \section{Il controllo di flusso non locale} -\label{sec:proc_flux} +\label{sec:proc_longjmp} \section{La gestione di parametri e opzioni}