+\itindbeg{page~fault}
+
+Quando un processo cerca di accedere ad una pagina che non è nella memoria
+reale, avviene quello che viene chiamato un \textit{page fault}; la gestione
+della memoria genera un'interruzione e passa il controllo al kernel il quale
+sospende il processo e si incarica di mettere in RAM la pagina richiesta,
+effettuando tutte le operazioni necessarie per reperire lo spazio necessario,
+per poi restituire il controllo al processo.
+
+Dal punto di vista di un processo questo meccanismo è completamente
+trasparente, e tutto avviene come se tutte le pagine fossero sempre
+disponibili in memoria. L'unica differenza avvertibile è quella dei tempi di
+esecuzione, che passano dai pochi nanosecondi necessari per l'accesso in RAM
+se la pagina è direttamente disponibile, a tempi estremamente più lunghi,
+dovuti all'intervento del kernel, qualora sia necessario reperire pagine
+riposte nella \textit{swap}.
+
+\itindend{page~fault}
+
+Normalmente questo è il prezzo da pagare per avere un multitasking reale, ed
+in genere il sistema è molto efficiente in questo lavoro; quando però ci siano
+esigenze specifiche di prestazioni è possibile usare delle funzioni che
+permettono di bloccare il meccanismo della paginazione e mantenere fisse delle
+pagine in memoria (vedi sez.~\ref{sec:proc_mem_lock}).
+
+\index{paginazione|)}
+\index{memoria~virtuale|)}
+
+\subsection{La struttura della memoria di un processo}
+\label{sec:proc_mem_layout}
+
+Benché lo spazio di indirizzi virtuali copra un intervallo molto ampio, solo
+una parte di essi è effettivamente allocato ed utilizzabile dal processo; il
+tentativo di accedere ad un indirizzo non allocato è un tipico errore che si
+commette quando si è manipolato male un puntatore e genera quella che viene
+chiamata una \itindex{segment~violation} \textit{segment violation}. Se si
+tenta cioè di leggere o scrivere con un indirizzo per il quale non esiste
+un'associazione nella memoria virtuale, il kernel risponde al relativo
+\textit{page fault} mandando un segnale \signal{SIGSEGV} al processo, che
+normalmente ne causa la terminazione immediata.
+
+È pertanto importante capire come viene strutturata la memoria virtuale di un
+processo. Essa viene divisa in \textsl{segmenti}, cioè un insieme contiguo di
+indirizzi virtuali ai quali il processo può accedere. Solitamente un
+programma C viene suddiviso nei seguenti segmenti:
+\begin{enumerate*}
+\item Il \index{segmento!testo} segmento di testo o \textit{text segment}.
+ Contiene il codice del programma, delle funzioni di librerie da esso
+ utilizzate, e le costanti. Normalmente viene condiviso fra tutti i processi
+ che eseguono lo stesso programma e nel caso delle librerie anche da processi
+ che eseguono altri programmi.
+
+ Quando l'architettura hardware lo supporta viene marcato in sola lettura per
+ evitare sovrascritture accidentali (o maliziose) che ne modifichino le
+ istruzioni. Viene allocato da \func{execve} all'avvio del programma e resta
+ invariato per tutto il tempo dell'esecuzione.
+
+\item Il \index{segmento!dati} segmento dei dati o \textit{data
+ segment}. Contiene tutti i dati del programma, come le
+ \index{variabili!globali} variabili globali, cioè quelle definite al di
+ fuori di tutte le funzioni che compongono il programma, e le
+ \index{variabili!statiche} variabili statiche, cioè quelle dichiarate con
+ l'attributo \direct{static},\footnote{la direttiva \direct{static} indica al
+ compilatore C che una variabile così dichiarata all'interno di una
+ funzione deve essere mantenuta staticamente in memoria (nel
+ \index{segmento!dati} segmento dati appunto); questo significa che la
+ variabile verrà inizializzata una sola volta alla prima invocazione della
+ funzione e che il suo valore sarà mantenuto fra diverse esecuzioni della
+ funzione stessa, la differenza con una \index{variabili!globali} variabile
+ globale è che essa può essere vista solo all'interno della funzione in cui
+ è dichiarata.} e la memoria allocata dinamicamente. Di norma è diviso in
+ tre parti:
+
+ \begin{itemize*}
+ \item Il segmento dei dati inizializzati, che contiene le variabili il cui
+ valore è stato assegnato esplicitamente. Ad esempio se si definisce:
+ \includecodesnip{listati/pi.c}
+ questo valore sarà immagazzinato in questo segmento. La memoria di questo
+ segmento viene preallocata all'avvio del programma e inizializzata ai valori
+ specificati.
+ \item Il segmento dei dati non inizializzati, che contiene le variabili il
+ cui valore non è stato assegnato esplicitamente. Ad esempio se si
+ definisce:
+ \includecodesnip{listati/vect.c}
+ questo vettore sarà immagazzinato in questo segmento. Anch'esso viene
+ allocato all'avvio, e tutte le variabili vengono inizializzate a zero (ed
+ i puntatori a \val{NULL}).\footnote{si ricordi che questo vale solo per le
+ variabili che vanno nel \index{segmento!dati} segmento dati, e non è
+ affatto vero in generale.} Storicamente questa seconda parte del
+ \index{segmento!dati} segmento dati viene chiamata BSS (da \textit{Block
+ Started by Symbol}). La sua dimensione è fissa.
+ \item Lo \itindex{heap} \textit{heap}, detto anche \textit{free
+ store}. Tecnicamente lo si può considerare l'estensione del segmento dei
+ dati non inizializzati, a cui di solito è posto giusto di seguito. Questo
+ è il segmento che viene utilizzato per l'allocazione dinamica della
+ memoria. Lo \textit{heap} può essere ridimensionato allargandolo e
+ restringendolo per allocare e disallocare la memoria dinamica con le
+ apposite funzioni (vedi sez.~\ref{sec:proc_mem_alloc}), ma il suo limite
+ inferiore, quello adiacente al segmento dei dati non inizializzati, ha una
+ posizione fissa.
+ \end{itemize*}
+
+\item Il segmento di \itindex{stack} \textit{stack}, che contiene quello che
+ viene chiamato \textit{stack} del programma. Tutte le volte che si effettua
+ una chiamata ad una funzione è qui che viene salvato l'indirizzo di ritorno
+ e le informazioni dello stato del chiamante (come il contenuto di alcuni
+ registri della CPU), poi la funzione chiamata alloca qui lo spazio per le
+ sue variabili locali. Tutti questi dati vengono \textit{impilati} (da questo
+ viene il nome \itindex{stack} \textit{stack}) in sequenza uno sull'altro; in
+ questo modo le funzioni possono essere chiamate ricorsivamente. Al ritorno
+ della funzione lo spazio è automaticamente rilasciato e
+ ``\textsl{ripulito}''.\footnote{il compilatore si incarica di generare
+ automaticamente il codice necessario, seguendo quella che viene chiamata
+ una \textit{calling convention}; quella standard usata con il C ed il C++
+ è detta \textit{cdecl} e prevede che gli argomenti siano caricati nello
+ \textit{stack} dal chiamante da destra a sinistra, e che sia il chiamante
+ stesso ad eseguire la ripulitura dello \textit{stack} al ritorno della
+ funzione, se ne possono però utilizzare di alternative (ad esempio nel
+ Pascal gli argomenti sono inseriti da sinistra a destra ed è compito del
+ chiamato ripulire lo \textit{stack}), in genere non ci si deve preoccupare
+ di questo fintanto che non si mescolano funzioni scritte con linguaggi
+ diversi.}
+
+ La dimensione di questo segmento aumenta seguendo la crescita dello
+ \itindex{stack} \textit{stack} del programma, ma non viene ridotta quando
+ quest'ultimo si restringe.
+\end{enumerate*}
+
+\begin{figure}[htb]
+ \centering
+% \includegraphics[height=12cm]{img/memory_layout}
+ \begin{tikzpicture}
+ \draw (0,0) rectangle (4,1);
+ \draw (2,0.5) node {\textit{text}};
+ \draw (0,1) rectangle (4,2.5);
+ \draw (2,1.75) node {dati inizializzati};
+ \draw (0,2.5) rectangle (4,5);
+ \draw (2,3.75) node {dati non inizializzati};
+ \draw (0,5) rectangle (4,9);
+ \draw[dashed] (0,6) -- (4,6);
+ \draw[dashed] (0,8) -- (4,8);
+ \draw (2,5.5) node {\textit{heap}};
+ \draw (2,8.5) node {\textit{stack}};
+ \draw [->] (2,6) -- (2,6.5);
+ \draw [->] (2,8) -- (2,7.5);
+ \draw (0,9) rectangle (4,10);
+ \draw (2,9.5) node {\textit{environment}};
+ \draw (4,0) node [anchor=west] {\texttt{0x08000000}};
+ \draw (4,5) node [anchor=west] {\texttt{0x08xxxxxx}};
+ \draw (4,9) node [anchor=west] {\texttt{0xC0000000}};
+ \end{tikzpicture}
+ \caption{Disposizione tipica dei segmenti di memoria di un processo.}
+ \label{fig:proc_mem_layout}
+\end{figure}
+
+Una disposizione tipica dei vari segmenti (testo, dati inizializzati e non
+inizializzati, \itindex{heap} \textit{heap}, \itindex{stack} \textit{stack},
+ecc.) è riportata in fig.~\ref{fig:proc_mem_layout}. Si noti come in figura
+sia indicata una ulteriore regione, marcata \textit{environment}, che è quella
+che contiene i dati relativi alle variabili di ambiente passate al programma
+al suo avvio (torneremo su questo argomento in sez.~\ref{sec:proc_environ}).
+
+Usando il comando \cmd{size} su un programma se ne può stampare le dimensioni
+dei \index{segmento!testo} segmenti di testo e \index{segmento!dati} di dati
+(solo però per i dati inizializzati ed il BSS, dato che lo \itindex{heap}
+\textit{heap} ha una dimensione dinamica). Si tenga presente comunque che il
+BSS, contrariamente al segmento dei dati inizializzati, non è mai salvato sul
+file che contiene l'eseguibile, dato che viene sempre inizializzato a zero al
+caricamento del programma.
+
+
+\subsection{Allocazione della memoria per i programmi C}
+\label{sec:proc_mem_alloc}
+
+Il C supporta direttamente, come linguaggio di programmazione, soltanto due
+modalità di allocazione della memoria: l'\textsl{allocazione statica} e
+l'\textsl{allocazione automatica}.
+
+L'\textsl{allocazione statica} è quella con cui sono memorizzate le
+\index{variabili!globali} variabili globali e le \index{variabili!statiche}
+variabili statiche, cioè le variabili il cui valore deve essere mantenuto per
+tutta la durata del programma. Come accennato queste variabili vengono
+allocate nel \index{segmento!dati} segmento dei dati all'avvio del programma
+come parte delle operazioni svolte da \func{exec}, e lo spazio da loro
+occupato non viene liberato fino alla sua conclusione.
+
+L'\textsl{allocazione automatica} è quella che avviene per gli argomenti di
+una funzione e per le sue variabili locali, quelle che vengono definite
+all'interno della funzione che esistono solo per la durata della sua esecuzione
+e che per questo vengono anche dette \index{variabili!automatiche}
+\textsl{variabili automatiche}. Lo spazio per queste variabili viene allocato
+nello \itindex{stack} \textit{stack} quando viene eseguita la funzione e
+liberato quando si esce dalla medesima.
+
+Esiste però un terzo tipo di allocazione, l'\textsl{allocazione dinamica}
+della memoria, che non è prevista direttamente all'interno del linguaggio C,
+ma che è necessaria quando il quantitativo di memoria che serve è
+determinabile solo durante il corso dell'esecuzione del programma. Il C non
+consente di usare variabili allocate dinamicamente, non è possibile cioè
+definire in fase di programmazione una variabile le cui dimensioni possano
+essere modificate durante l'esecuzione del programma. Per questo la libreria
+standard del C fornisce una opportuna serie di funzioni per eseguire
+l'allocazione dinamica di memoria, che come accennato avviene nello
+\itindex{heap} \textit{heap}.
+
+Le variabili il cui contenuto è allocato in questo modo non potranno essere
+usate direttamente come le altre (quelle nello \itindex{stack}
+\textit{stack}), ma l'accesso sarà possibile solo in maniera indiretta,
+attraverso i puntatori alla memoria loro riservata che si sono ottenuti dalle
+funzioni di allocazione.
+
+Le funzioni previste dallo standard ANSI C per la gestione della memoria sono
+quattro: \func{malloc}, \func{calloc}, \func{realloc} e \func{free}. Le prime
+due, \funcd{malloc} e \funcd{calloc} allocano nuovo spazio di memoria; i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{void *calloc(size\_t nmemb, size\_t size)}
+\fdesc{Alloca un'area di memoria inizializzata a 0.}
+\fdecl{void *malloc(size\_t size)}
+\fdesc{Alloca un'area di memoria non inizializzata.}
+}
+{Entrambe le funzioni restituiscono il puntatore alla zona di memoria allocata
+in caso di successo e \val{NULL} in caso di fallimento, nel qual caso
+ \var{errno} assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+In genere si usano \func{malloc} e \func{calloc} per allocare dinamicamente
+un'area di memoria.\footnote{queste funzioni presentano un comportamento
+ diverso fra le \acr{glibc} e le \acr{uClib} quando il valore di \param{size}
+ è nullo. Nel primo caso viene comunque restituito un puntatore valido,
+ anche se non è chiaro a cosa esso possa fare riferimento, nel secondo caso
+ viene restituito \val{NULL}. Il comportamento è analogo con
+ \code{realloc(NULL, 0)}.} Dato che i puntatori ritornati sono di tipo
+generico non è necessario effettuare un cast per assegnarli a puntatori al
+tipo di variabile per la quale si effettua l'allocazione, inoltre le funzioni
+garantiscono che i puntatori siano allineati correttamente per tutti i tipi di
+dati; ad esempio sulle macchine a 32 bit in genere sono allineati a multipli
+di 4 byte e sulle macchine a 64 bit a multipli di 8 byte.
+
+Nel caso di \func{calloc} l'area di memoria viene allocata nello \textit{heap}
+come un vettore di \param{nmemb} membri di \param{size} byte di dimensione, e
+preventivamente inizializzata a zero, nel caso di \func{malloc} invece vengono
+semplicemente allocati \param{size} byte e l'area di memoria non viene
+inizializzata.
+
+Una volta che non sia più necessaria la memoria allocata dinamicamente deve
+essere esplicitamente rilasciata usando la funzione \funcd{free},\footnote{le
+ glibc provvedono anche una funzione \funcm{cfree} definita per compatibilità
+ con SunOS, che è deprecata.} il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{void free(void *ptr)}
+\fdesc{Disalloca un'area di memoria precedentemente allocata.}
+}
+{La funzione non ritorna nulla e non riporta errori.}
+\end{funcproto}
+
+Questa funzione vuole come argomento \var{ptr} il puntatore restituito da una
+precedente chiamata ad una qualunque delle funzioni di allocazione che non sia
+già stato liberato da un'altra chiamata a \func{free}. Se il valore
+di \param{ptr} è \val{NULL} la funzione non fa niente, mentre se l'area di
+memoria era già stata liberata da un precedente chiamata il comportamento
+della funzione è dichiarato indefinito, ma in genere comporta la corruzione
+dei dati di gestione dell'allocazione, che può dar luogo a problemi gravi, ad
+esempio un \textit{segmentation fault} in una successiva chiamata di una di
+queste funzioni.
+
+Dato che questo errore, chiamato in gergo \itindex{double~free} \textit{double
+ free}, è abbastanza frequente, specie quando si manipolano vettori di
+puntatori, e dato che le conseguenze possono essere pesanti ed inaspettate, si
+suggerisce come soluzione precauzionale di assegnare sempre a \val{NULL} ogni
+puntatore su cui sia stata eseguita \func{free} immediatamente dopo
+l'esecuzione della funzione. In questo modo, dato che con un puntatore nullo
+\func{free} non esegue nessuna operazione, si evitano i problemi del
+\itindex{double~free} \textit{double free}.
+
+Infine la funzione \funcd{realloc} consente di modificare, in genere di
+aumentare, la dimensione di un'area di memoria precedentemente allocata; il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{void *realloc(void *ptr, size\_t size)}
+\fdesc{Cambia la dimensione di un'area di memoria precedentemente allocata.}
+} {La funzione ritorna il puntatore alla zona di memoria allocata in caso
+ di successo e \val{NULL} per un errore, nel qual caso \var{errno}
+ assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+La funzione vuole come primo argomento il puntatore restituito da una
+precedente chiamata a \func{malloc} o \func{calloc} e come secondo argomento
+la nuova dimensione (in byte) che si intende ottenere. Se si passa
+per \param{ptr} il valore \val{NULL} allora la funzione si comporta come
+\func{malloc}.\footnote{questo è vero per Linux e l'implementazione secondo lo
+ standard ANSI C, ma non è vero per alcune vecchie implementazioni, inoltre
+ alcune versioni delle librerie del C consentivano di usare \func{realloc}
+ anche per un puntatore liberato con \func{free} purché non ci fossero state
+ nel frattempo altre chiamate a funzioni di allocazione, questa funzionalità
+ è totalmente deprecata e non è consentita sotto Linux.}
+
+La funzione si usa ad esempio quando si deve far crescere la dimensione di un
+vettore. In questo caso se è disponibile dello spazio adiacente al precedente
+la funzione lo utilizza, altrimenti rialloca altrove un blocco della
+dimensione voluta, copiandoci automaticamente il contenuto; lo spazio aggiunto
+non viene inizializzato. Se la funzione fallisce l'area di memoria originale
+non viene assolutamente toccata.
+
+Si deve sempre avere ben presente il fatto che il blocco di memoria restituito
+da \func{realloc} può non essere un'estensione di quello che gli si è passato
+in ingresso; per questo si dovrà \emph{sempre} eseguire la riassegnazione di
+\param{ptr} al valore di ritorno della funzione, e reinizializzare o provvedere
+ad un adeguato aggiornamento di tutti gli altri puntatori all'interno del
+blocco di dati ridimensionato.
+
+La \acr{glibc} ha un'implementazione delle funzioni di allocazione che è
+controllabile dall'utente attraverso alcune variabili di ambiente (vedi
+sez.~\ref{sec:proc_environ}), in particolare diventa possibile tracciare
+questo tipo di errori usando la variabile di ambiente \envvar{MALLOC\_CHECK\_}
+che quando viene definita mette in uso una versione meno efficiente delle
+funzioni suddette, che però è più tollerante nei confronti di piccoli errori
+come quello dei \itindex{double~free} \textit{double~free} o i \textit{buffer
+ overrun} di un byte.\footnote{uno degli errori più comuni, causato ad
+ esempio dalla scrittura di una stringa di dimensione pari a quella del
+ buffer, in cui ci si dimentica dello zero di terminazione finale.} In
+particolare:
+\begin{itemize*}
+\item se la variabile è posta a $0$ gli errori vengono ignorati;
+\item se la variabile è posta a $1$ viene stampato un avviso sullo
+ \textit{standard error} (vedi sez.~\ref{sec:file_fd});
+\item se la variabile è posta a $2$ viene chiamata la funzione \func{abort}
+ (vedi sez.~\ref{sec:sig_alarm_abort}), che in genere causa l'immediata
+ terminazione del programma;
+\item se la variabile è posta a $3$ viene stampato l'avviso e chiamata
+ \func{abort}.
+\end{itemize*}
+
+L'errore di programmazione più comune e più difficile da risolvere che si
+incontra con le funzioni di allocazione è quando non viene opportunamente
+liberata la memoria non più utilizzata, quello che in inglese viene chiamato
+\itindex{memory~leak} \textit{memory leak}, cioè una \textsl{perdita di
+ memoria}.
+
+Un caso tipico che illustra il problema è quello in cui in una propria
+funzione 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 funzione continueranno ad effettuare altre
+allocazioni, che si accumuleranno causando a lungo andare un esaurimento della
+memoria disponibile e la probabile impossibilità di proseguire l'esecuzione
+del 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 funzione
+che contiene l'errore. Per questo motivo è sempre molto difficile trovare un
+\itindex{memory~leak} \textit{memory leak}.
+
+In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
+programmazione ad oggetti, il problema dei \itindex{memory~leak}
+\textit{memory leak} si può notevolmente ridimensionare attraverso l'uso
+accurato di appositi oggetti come gli \textit{smartpointers}. Questo però in
+genere va a scapito delle prestazioni dell'applicazione in esecuzione.
+
+% TODO decidere cosa fare di questo che segue
+% In altri linguaggi come il java e recentemente il C\# il problema non si pone
+% nemmeno perché la gestione della memoria viene fatta totalmente in maniera
+% automatica, ovvero il programmatore non deve minimamente preoccuparsi di
+% liberare la memoria allocata precedentemente quando non serve più, poiché
+% l'infrastruttura del linguaggio gestisce automaticamente la cosiddetta
+% \index{\textit{garbage~collection}} \textit{garbage collection}. In tal caso,
+% attraverso meccanismi simili a quelli del \textit{reference counting}, quando
+% una zona di memoria precedentemente allocata non è più riferita da nessuna
+% parte del codice in esecuzione, può essere deallocata automaticamente in
+% qualunque momento dall'infrastruttura.
+
+% Anche questo va a scapito delle prestazioni dell'applicazione in esecuzione
+% (inoltre le applicazioni sviluppate con tali linguaggi di solito non sono
+% eseguibili compilati, come avviene invece per il C ed il C++, ed è necessaria
+% la presenza di una infrastruttura per la loro interpretazione e pertanto hanno
+% di per sé delle prestazioni più scadenti rispetto alle stesse applicazioni
+% compilate direttamente). Questo comporta però il problema della non
+% predicibilità del momento in cui viene deallocata la memoria precedentemente
+% allocata da un oggetto.
+
+Per limitare l'impatto di questi problemi, e semplificare la ricerca di
+eventuali errori, l'implementazione delle funzioni di allocazione nella
+\acr{glibc} mette a disposizione una serie di funzionalità che permettono di
+tracciare le allocazioni e le disallocazioni, e definisce anche una serie di
+possibili \textit{hook} (\textsl{ganci}) che permettono di sostituire alle
+funzioni di libreria una propria versione (che può essere più o meno
+specializzata per il debugging). Esistono varie librerie che forniscono dei
+sostituti opportuni delle funzioni di allocazione in grado, senza neanche
+ricompilare il programma,\footnote{esempi sono \textit{Dmalloc}
+ \url{http://dmalloc.com/} di Gray Watson ed \textit{Electric Fence} di Bruce
+ Perens.} di eseguire diagnostiche anche molto complesse riguardo
+l'allocazione della memoria. Vedremo alcune delle funzionalità di ausilio
+presenti nella \acr{glibc} in sez.~\ref{sec:proc_memory_adv_management}.
+
+Una possibile alternativa all'uso di \func{malloc}, per evitare di soffrire
+dei problemi di \itindex{memory~leak} \textit{memory leak} descritti in
+precedenza, è di allocare la memoria nel segmento di \itindex{stack}
+\textit{stack} della funzione corrente invece che nello \itindex{heap}
+\textit{heap}. Per farlo si può usare la funzione \funcd{alloca}, la cui
+sintassi è identica a quella di \func{malloc}; il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{void *alloca(size\_t size)}
+\fdesc{Alloca un'area di memoria nello \textit{stack}.}
+}
+{La funzione ritorna il puntatore alla zona di memoria allocata, in caso
+ di errore il comportamento è indefinito.}
+\end{funcproto}
+
+La funzione alloca la quantità di memoria (non inizializzata) richiesta
+dall'argomento \param{size} nel segmento di \itindex{stack} \textit{stack}
+della funzione chiamante. Con questa funzione non è più necessario liberare
+la memoria allocata, e quindi non esiste un analogo della \func{free}, in
+quanto essa viene rilasciata automaticamente al ritorno della funzione.
+
+Come è evidente questa funzione ha alcuni vantaggi interessanti, anzitutto
+permette di evitare alla radice i problemi di \itindex{memory~leak}
+\textit{memory leak}, dato che non serve più la deallocazione esplicita;
+inoltre la deallocazione automatica funziona anche quando si usa
+\func{longjmp} per uscire da una subroutine con un salto non locale da una
+funzione (vedi sez.~\ref{sec:proc_longjmp}). Un altro vantaggio è che in
+Linux la funzione è molto più veloce di \func{malloc} e non viene sprecato
+spazio, infatti non è necessario gestire un pool di memoria da riservare e si
+evitano così anche i problemi di frammentazione di quest'ultimo, che
+comportano inefficienze sia nell'allocazione della memoria che nell'esecuzione
+dell'allocazione.
+
+Gli svantaggi sono che questa funzione non è disponibile su tutti gli Unix, e
+non è inserita né nello standard POSIX né in SUSv3 (ma è presente in BSD), il
+suo utilizzo quindi limita la portabilità dei programmi. Inoltre la funzione
+non può essere usata nella lista degli argomenti di una funzione, perché lo
+spazio verrebbe allocato nel mezzo degli stessi. Inoltre non è chiaramente
+possibile usare \func{alloca} per allocare memoria che deve poi essere usata
+anche al di fuori della funzione in cui essa viene chiamata, dato che
+all'uscita dalla funzione lo spazio allocato diventerebbe libero, e potrebbe
+essere sovrascritto all'invocazione di nuove funzioni. Questo è lo stesso
+problema che si può avere con le \index{variabili!automatiche} variabili
+automatiche, su cui torneremo in sez.~\ref{sec:proc_var_passing}.
+
+Infine non esiste un modo di sapere se l'allocazione ha avuto successo, la
+funzione infatti viene realizzata inserendo del codice \textit{inline} nel
+programma\footnote{questo comporta anche il fatto che non è possibile
+ sostituirla con una propria versione o modificarne il comportamento
+ collegando il proprio programma con un'altra libreria.} che si limita a
+modificare il puntatore nello \itindex{stack} \textit{stack} e non c'è modo di
+sapere se se ne sono superate le dimensioni, per cui in caso di fallimento
+nell'allocazione il comportamento del programma può risultare indefinito,
+dando luogo ad una \itindex{segment~violation} \textit{segment violation} la
+prima volta che cercherà di accedere alla memoria non effettivamente
+disponibile.
+
+
+\index{segmento!dati|(}
+
+Le due funzioni seguenti\footnote{le due funzioni sono state definite con BSD
+ 4.3, sono marcate obsolete in SUSv2 e non fanno parte delle librerie
+ standard del C e mentre sono state esplicitamente rimosse dallo standard
+ POSIX.1-2001.} vengono utilizzate soltanto quando è necessario effettuare
+direttamente la gestione della memoria associata allo spazio dati di un
+processo, per poterle utilizzare è necessario definire una della macro di
+funzionalità (vedi sez.~\ref{sec:intro_gcc_glibc_std}) fra
+\macro{\_BSD\_SOURCE}, \macro{\_SVID\_SOURCE} e \macro{\_XOPEN\_SOURCE} (ad un
+valore maggiore o uguale di 500). La prima funzione è \funcd{brk}, ed il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{int brk(void *addr)}
+\fdesc{Sposta la fine del segmento dati del processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore,
+ nel qual caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+La funzione è un'interfaccia all'omonima \textit{system call} ed imposta
+l'indirizzo finale del segmento dati di un processo (più precisamente dello
+\itindex{heap} \textit{heap}) all'indirizzo specificato
+da \param{addr}. Quest'ultimo deve essere un valore ragionevole, e la
+dimensione totale non deve comunque eccedere un eventuale limite (vedi
+sez.~\ref{sec:sys_resource_limit}) imposto sulle dimensioni massime del
+segmento dati del processo.
+
+Il valore di ritorno della funzione fa riferimento alla versione fornita dalla
+\acr{glibc}, in realtà in Linux la \textit{system call} corrispondente
+restituisce come valore di ritorno il nuovo valore della fine del segmento
+dati in caso di successo e quello corrente in caso di fallimento, è la
+funzione di interfaccia usata dalla \acr{glibc} che fornisce i valori di
+ritorno appena descritti; se si usano librerie diverse questo potrebbe non
+accadere.
+
+Una seconda funzione per la manipolazione diretta delle dimensioni del
+segmento dati\footnote{in questo caso si tratta soltanto di una funzione di
+ libreria, anche se basata sulla stessa \textit{system call}.} è
+\funcd{sbrk}, ed il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fdecl{void *sbrk(intptr\_t increment)}
+\fdesc{Incrementa la dimensione del segmento dati del processo.}
+}
+{La funzione ritorna il puntatore all'inizio della nuova zona di memoria
+ allocata in caso di successo e \val{NULL} per un errore, nel qual
+ caso \var{errno} assumerà il valore \errcode{ENOMEM}.}
+\end{funcproto}
+
+La funzione incrementa la dimensione dello \itindex{heap} \textit{heap} di un
+programma del valore indicato dall'argomento \param{increment}, restituendo il
+nuovo indirizzo finale dello stesso. L'argomento è definito come di tipo
+\type{intptr\_t}, ma a seconda della versione delle librerie e del sistema può
+essere indicato con una serie di tipi equivalenti come \type{ptrdiff\_t},
+\type{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzione
+permette di ottenere l'attuale posizione della fine del segmento dati.
+
+Queste due funzioni sono state deliberatamente escluse dallo standard POSIX.1
+dato che per i normali programmi è sempre opportuno usare le funzioni di
+allocazione standard descritte in precedenza, a meno di non voler realizzare
+per proprio conto un diverso meccanismo di gestione della memoria del segmento
+dati.
+
+\index{segmento!dati|)}
+
+
+\subsection{Il controllo della memoria virtuale}
+\label{sec:proc_mem_lock}
+
+\index{memoria~virtuale|(}
+
+Come spiegato in sez.~\ref{sec:proc_mem_gen} il kernel gestisce la memoria
+virtuale in maniera trasparente ai processi, decidendo quando rimuovere pagine
+dalla memoria per metterle nell'area di \textit{swap}, sulla base
+dell'utilizzo corrente da parte dei vari processi.
+
+Nell'uso comune un processo non deve preoccuparsi di tutto ciò, in quanto il
+meccanismo della paginazione riporta in RAM, ed in maniera trasparente, tutte
+le pagine che gli occorrono; esistono però esigenze particolari in cui non si
+vuole che questo meccanismo si attivi. In generale i motivi per cui si possono
+avere di queste necessità sono due:
+\begin{itemize*}
+\item \textsl{La velocità}. Il processo della paginazione è trasparente solo
+ se il programma in esecuzione non è sensibile al tempo che occorre a
+ riportare la pagina in memoria; per questo motivo processi critici che hanno
+ esigenze di tempo reale o tolleranze critiche nelle risposte (ad esempio
+ processi che trattano campionamenti sonori) possono non essere in grado di
+ sopportare le variazioni della velocità di accesso dovuta alla paginazione.
+
+ In certi casi poi un programmatore può conoscere meglio dell'algoritmo di
+ allocazione delle pagine le esigenze specifiche del suo programma e decidere
+ quali pagine di memoria è opportuno che restino in memoria per un aumento
+ delle prestazioni. In genere queste sono esigenze particolari e richiedono
+ anche un aumento delle priorità in esecuzione del processo (vedi
+ sez.~\ref{sec:proc_real_time}).
+
+\item \textsl{La sicurezza}. Se si hanno password o chiavi segrete in chiaro
+ in memoria queste possono essere portate su disco dal meccanismo della
+ paginazione. Questo rende più lungo il periodo di tempo in cui detti segreti
+ sono presenti in chiaro e più complessa la loro cancellazione: un processo
+ infatti può cancellare la memoria su cui scrive le sue variabili, ma non può
+ toccare lo spazio disco su cui una pagina di memoria può essere stata
+ salvata. Per questo motivo di solito i programmi di crittografia richiedono
+ il blocco di alcune pagine di memoria.
+\end{itemize*}
+
+Per ottenere informazioni sulle modalità in cui un programma sta usando la
+memoria virtuale è disponibile una apposita funzione di sistema,
+\funcd{mincore}, che però non è standardizzata da POSIX e pertanto non è
+disponibile su tutte le versioni di kernel unix-like;\footnote{nel caso di
+ Linux devono essere comunque definite le macro \macro{\_BSD\_SOURCE} e
+ \macro{\_SVID\_SOURCE}.} il suo prototipo è:
+
+\begin{funcproto}{
+\fhead{unistd.h}
+\fhead{sys/mman.h}
+\fdecl{int mincore(void *addr, size\_t length, unsigned char *vec)}
+\fdesc{Ritorna lo stato delle pagine di memoria occupate da un processo.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errore, nel qual
+caso \var{errno} assumerà uno dei valori:
+\begin{errlist}
+ \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire
+ una risposta.
+ \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido.
+ \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di
+ una pagina.
+ \item[\errcode{ENOMEM}] o \param{addr}$+$\param{length} eccede la dimensione
+ della memoria usata dal processo o l'intervallo di indirizzi specificato
+ non è mappato.
+\end{errlist}}
+\end{funcproto}
+
+La funzione permette di ottenere le informazioni sullo stato della mappatura
+della memoria per il processo chiamante, specificando l'intervallo da
+esaminare con l'indirizzo iniziale, indicato con l'argomento \param{addr}, e
+la lunghezza, indicata con l'argomento \param{length}. L'indirizzo iniziale
+deve essere un multiplo delle dimensioni di una pagina, mentre la lunghezza
+può essere qualunque, fintanto che si resta nello spazio di indirizzi del
+processo,\footnote{in caso contrario si avrà un errore di \errcode{ENOMEM};
+ fino al kernel 2.6.11 in questo caso veniva invece restituito
+ \errcode{EINVAL}, in considerazione che il caso più comune in cui si
+ verifica questo errore è quando si usa per sbaglio un valore negativo
+ di \param{length}, che nel caso verrebbe interpretato come un intero
+ positivo di grandi dimensioni.} ma il risultato verrà comunque fornito per
+l'intervallo compreso fino al multiplo successivo.
+
+I risultati della funzione vengono forniti nel vettore puntato da \param{vec},
+che deve essere allocato preventivamente e deve essere di dimensione
+sufficiente a contenere tanti byte quante sono le pagine contenute
+nell'intervallo di indirizzi specificato, la dimensione cioè deve essere
+almeno pari a \code{(length+PAGE\_SIZE-1)/PAGE\_SIZE}. Al ritorno della
+funzione il bit meno significativo di ciascun byte del vettore sarà acceso se
+la pagina di memoria corrispondente è al momento residente in memoria, o
+cancellato altrimenti. Il comportamento sugli altri bit è indefinito, essendo
+questi al momento riservati per usi futuri. Per questo motivo in genere è
+comunque opportuno inizializzare a zero il contenuto del vettore, così che le
+pagine attualmente residenti in memoria saranno indicata da un valore non
+nullo del byte corrispondente.
+
+Dato che lo stato della memoria di un processo può cambiare continuamente, il
+risultato di \func{mincore} è assolutamente provvisorio e lo stato delle
+pagine potrebbe essere già cambiato al ritorno stesso della funzione, a meno
+che, come vedremo ora, non si sia attivato il meccanismo che forza il
+mantenimento di una pagina sulla memoria.
+
+\itindbeg{memory~locking}
+
+Il meccanismo che previene la paginazione di parte della memoria virtuale di
+un processo è chiamato \textit{memory locking} (o \textsl{blocco della
+ memoria}). Il blocco è sempre associato alle pagine della memoria virtuale
+del processo, e non al segmento reale di RAM su cui essa viene mantenuta. La
+regola è che se un segmento di RAM fa da supporto ad almeno una pagina
+bloccata allora esso viene escluso dal meccanismo della paginazione. I blocchi
+non si accumulano, se si blocca due volte la stessa pagina non è necessario
+sbloccarla due volte, una pagina o è bloccata oppure no.
+
+Il \textit{memory lock} persiste fintanto che il processo che detiene la
+memoria bloccata non la sblocca. Chiaramente la terminazione del processo
+comporta anche la fine dell'uso della sua memoria virtuale, e quindi anche di
+tutti i suoi \textit{memory lock}. Inoltre i \textit{memory lock} non sono
+ereditati dai processi figli, ma siccome Linux usa il \itindex{copy~on~write}
+\textit{copy on write} (vedi sez.~\ref{sec:proc_fork}) gli indirizzi virtuali
+del figlio sono mantenuti sullo stesso segmento di RAM del padre, e quindi
+fintanto che un figlio non scrive su un segmento bloccato, può usufruire del
+\textit{memory lock} del padre. Infine i \textit{memory lock} vengono
+automaticamente rimossi se si pone in esecuzione un altro programma con
+\func{exec} (vedi sez.~\ref{sec:proc_exec}).
+
+Il sistema pone dei limiti all'ammontare di memoria di un processo che può
+essere bloccata e al totale di memoria fisica che si può dedicare a questo, lo
+standard POSIX.1 richiede che sia definita in \headfile{unistd.h} la macro
+\macro{\_POSIX\_MEMLOCK\_RANGE} per indicare la capacità di eseguire il
+\textit{memory locking}.
+
+Siccome la richiesta di un \textit{memory lock} da parte di un processo riduce
+la memoria fisica disponibile nel sistema per gli altri processi, questo ha un
+evidente impatto su tutti gli altri processi, per cui fino al kernel 2.6.9
+solo un processo dotato di privilegi amministrativi (la \textit{capability}
+\const{CAP\_IPC\_LOCK}, vedi sez.~\ref{sec:proc_capabilities}) aveva la
+capacità di bloccare una pagina di memoria.
+
+A partire dal kernel 2.6.9 anche un processo normale può bloccare la propria
+memoria\footnote{la funzionalità è stata introdotta per non essere costretti a
+ dare privilegi eccessivi a programmi di crittografia, che necessitano di
+ questa funzionalità, ma che devono essere usati da utenti normali.} ma
+mentre un processo privilegiato non ha limiti sulla quantità di memoria che
+può bloccare, un processo normale è soggetto al limite della risorsa
+\const{RLIMIT\_MEMLOCK} (vedi sez.~\ref{sec:sys_resource_limit}). In generale
+poi ogni processo può sbloccare le pagine relative alla propria memoria, se
+però diversi processi bloccano la stessa pagina questa resterà bloccata
+fintanto che ci sarà almeno un processo che la blocca.
+
+Le funzioni di sistema per bloccare e sbloccare la paginazione di singole
+sezioni di memoria sono rispettivamente \funcd{mlock} e \funcd{munlock}; i
+loro prototipi sono:
+
+\begin{funcproto}{
+ \fhead{sys/mman.h}
+ \fdecl{int mlock(const void *addr, size\_t len)}
+ \fdesc{Blocca la paginazione su un intervallo di memoria.}
+
+ \fdecl{int munlock(const void *addr, size\_t len)}
+ \fdesc{Rimuove il blocco della paginazione su un intervallo di memoria.}
+ }
+{Entrambe le funzioni ritornano $0$ in caso di successo e $-1$ in caso di
+ errore, nel qual caso \var{errno} assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{len} non è un valore positivo.
+ \item[\errcode{ENOMEM}] alcuni indirizzi dell’intervallo specificato non
+ corrispondono allo spazio di indirizzi del processo o si è superato il
+ limite di \const{RLIMIT\_MEMLOCK} per un processo non privilegiato (solo
+ per kernel a partire dal 2.6.9).
+ \item[\errcode{EPERM}] il processo non è privilegiato (per kernel precedenti
+ il 2.6.9) o si ha un limite nullo per \const{RLIMIT\_MEMLOCK} e
+ il processo non è privilegiato (per kernel a partire dal 2.6.9).
+ \end{errlist}}
+\end{funcproto}
+
+Le due funzioni permettono rispettivamente di bloccare e sbloccare la
+\index{paginazione} paginazione per l'intervallo di memoria iniziante
+all'indirizzo \param{addr} e lungo \param{len} byte. Tutte le pagine che
+contengono una parte dell'intervallo bloccato sono mantenute in RAM per tutta
+la durata del blocco. Con kernel diversi da Linux si può ottenere un errore di
+\errcode{EINVAL} se \param{addr} non è un multiplo della dimensione delle
+pagine di memoria, pertanto se si ha a cuore la portabilità si deve avere cura
+di allinearne correttamente il valore.
+
+Altre due funzioni di sistema, \funcd{mlockall} e \funcd{munlockall},
+consentono di bloccare genericamente la \index{paginazione} paginazione per
+l'intero spazio di indirizzi di un processo. I prototipi di queste funzioni
+sono:
+
+\begin{funcproto}{
+\fhead{sys/mman.h}
+\fdecl{int mlockall(int flags)}
+\fdesc{Blocca la paginazione per lo spazio di indirizzi del processo corrente.}
+\fdecl{int munlockall(void)}
+\fdesc{Sblocca la paginazione per lo spazio di indirizzi del processo corrente.}
+}
+{Codici di ritorno ed errori sono gli stessi di \func{mlock} e \func{munlock},
+ tranne per \errcode{EINVAL} che viene restituito solo se si è specificato
+ con \func{mlockall} un valore sconosciuto per \param{flags}.}
+\end{funcproto}
+
+L'argomento \param{flags} di \func{mlockall} permette di controllarne il
+comportamento; esso deve essere specificato come maschera binaria dei valori
+espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
+
+\begin{table}[htb]
+ \footnotesize
+ \centering
+ \begin{tabular}[c]{|l|p{8cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{MCL\_CURRENT}& blocca tutte le pagine correntemente mappate nello
+ spazio di indirizzi del processo.\\
+ \const{MCL\_FUTURE} & blocca tutte le pagine che verranno mappate nello
+ spazio di indirizzi del processo.\\
+ \hline
+ \end{tabular}
+ \caption{Valori e significato dell'argomento \param{flags} della funzione
+ \func{mlockall}.}
+ \label{tab:mlockall_flags}
+\end{table}
+
+Con \func{mlockall} si possono bloccare tutte le pagine mappate nello spazio
+di indirizzi del processo, sia che comprendano il \index{segmento!dati}
+\index{segmento!testo} segmento di testo, di dati, lo \itindex{stack}
+\textit{stack}, lo \itindex{heap} \textit{heap} e pure le funzioni di libreria
+chiamate, i file mappati in memoria, i dati del kernel mappati in user space,
+la memoria condivisa. L'uso dell'argomento \param{flags} permette di
+selezionare con maggior finezza le pagine da bloccare, ad esempio usando
+\const{MCL\_FUTURE} ci si può limitare a tutte le pagine allocate a partire
+dalla chiamata della funzione.
+
+In ogni caso un processo \textit{real-time} che deve entrare in una
+\index{sezione~critica} sezione critica deve provvedere a riservare memoria
+sufficiente prima dell'ingresso, per scongiurare l'occorrenza di un eventuale
+\textit{page fault} causato dal meccanismo di \itindex{copy~on~write}
+\textit{copy on write}. Infatti se nella \index{sezione~critica} sezione
+critica si va ad utilizzare memoria che non è ancora stata riportata in RAM si
+potrebbe avere un \textit{page fault} durante l'esecuzione della stessa, con
+conseguente rallentamento (probabilmente inaccettabile) dei tempi di
+esecuzione.
+
+In genere si ovvia a questa problematica chiamando una funzione che ha
+allocato una quantità sufficientemente ampia di \index{variabili!automatiche}
+variabili automatiche, in modo che esse vengano mappate in RAM dallo
+\itindex{stack} \textit{stack}, dopo di che, per essere sicuri che esse siano
+state effettivamente portate in memoria, ci si scrive sopra.
+
+\itindend{memory~locking}
+
+\index{memoria~virtuale|)}
+
+
+\subsection{Gestione avanzata dell'allocazione della memoria}
+\label{sec:proc_memory_adv_management}
+
+La trattazione delle funzioni di allocazione di sez.~\ref{sec:proc_mem_alloc}
+si è limitata a coprire le esigenze generiche di un programma, in cui non si
+hanno dei requisiti specifici e si lascia il controllo delle modalità di
+allocazione alle funzioni di libreria. Tuttavia esistono una serie di casi in
+cui può essere necessario avere un controllo più dettagliato delle modalità
+con cui la memoria viene allocata; nel qual caso potranno venire in aiuto le
+funzioni trattate in questa sezione.
+
+Le prime funzioni che tratteremo sono quelle che consentono di richiedere di
+allocare un blocco di memoria ``\textsl{allineato}'' ad un multiplo una certa
+dimensione. Questo tipo di esigenza emerge usualmente quando si devono
+allocare dei buffer da utilizzare per eseguire dell'I/O diretto su dispositivi
+a blocchi. In questo caso infatti il trasferimento di dati viene eseguito per
+blocchi di dimensione fissa, ed è richiesto che l'indirizzo di partenza del
+buffer sia un multiplo intero di questa dimensione, usualmente 512 byte. In
+tal caso l'uso di \func{malloc} non è sufficiente, ed occorre utilizzare una
+funzione specifica.
+
+Tradizionalmente per rispondere a questa esigenza sono state create due
+funzioni diverse, \funcd{memalign} e \funcd{valloc}, oggi obsolete; i
+rispettivi prototipi sono:
+
+\begin{funcproto}{
+\fhead{malloc.h}
+\fdecl{void *valloc(size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato alla dimensione di una pagina di
+ memoria.}
+\fdecl{void *memalign(size\_t boundary, size\_t size)}
+\fdesc{Alloca un blocco di memoria allineato ad un multiplo
+ di \param{boundary}.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{boundary} non è una potenza di due.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+Le funzioni restituiscono il puntatore al buffer di memoria allocata di
+dimensioni pari a \param{size}, che per \func{memalign} sarà un multiplo
+di \param{boundary} mentre per \func{valloc} un multiplo della dimensione di
+una pagina di memoria. Nel caso della versione fornita dalla \acr{glibc} la
+memoria allocata con queste funzioni deve essere liberata con \func{free},
+cosa che non è detto accada con altre implementazioni.
+
+Nessuna delle due funzioni ha una chiara standardizzazione e nessuna delle due
+compare in POSIX.1, inoltre ci sono indicazioni discordi sui file che ne
+contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
+ \headfile{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4}
+ e \acr{libc5} la dichiarano in \headfile{malloc.h}, lo stesso vale per
+ \func{memalign} che in alcuni sistemi è dichiarata in \headfile{stdlib.h}.}
+per questo motivo il loro uso è sconsigliato, essendo state sostituite dalla
+nuova \funcd{posix\_memalign}, che è stata standardizzata in POSIX.1d; il suo
+prototipo è:
+
+\begin{funcproto}{
+\fhead{stdlib.h}
+\fdecl{posix\_memalign(void **memptr, size\_t alignment, size\_t size)}
+\fdesc{Alloca un buffer di memoria allineato ad un multiplo
+ di \param{alignment}.}
+}
+{Entrambe le funzioni ritornano un puntatore al blocco di memoria allocato in
+ caso di successo e \val{NULL} in caso di errore, nel qual caso \var{errno}
+ assumerà uno dei valori:
+ \begin{errlist}
+ \item[\errcode{EINVAL}] \param{alignment} non è potenza di due e multiplo
+ di \code{sizeof(void *)}.
+ \item[\errcode{ENOMEM}] non c'è memoria sufficiente per l'allocazione.
+ \end{errlist}}
+\end{funcproto}
+
+La funzione restituisce il puntatore al buffer allocato di dimensioni pari
+a \param{size} nella variabile (di tipo \texttt{void *}) posta all'indirizzo
+indicato da \param{memptr}. La funzione fallisce nelle stesse condizioni delle
+due funzioni precedenti, ma a loro differenza restituisce direttamente come
+valore di ritorno il codice di errore. Come per le precedenti la memoria
+allocata con \func{posix\_memalign} deve essere disallocata con \func{free},
+che in questo caso però è quanto richiesto dallo standard. Si tenga presente
+infine che nessuna di queste funzioni inizializza il buffer di memoria
+allocato, il loro comportamento cioè è analogo, allineamento a parte, a quello
+di \func{malloc}.
+
+Un secondo caso in cui risulta estremamente utile poter avere un maggior
+controllo delle modalità di allocazione della memoria è quello in cui cercano
+errori di programmazione. Esempi di questi errori sono i \itindex{double~free}
+\textit{double free}, o i cosiddetti \itindex{buffer~overrun} \textit{buffer
+ overrun}, cioè le scritture su un buffer oltre le dimensioni della sua
+allocazione,\footnote{entrambe queste operazioni causano in genere la
+ corruzione dei dati di controllo delle funzioni di allocazione, che vengono
+ anch'essi mantenuti nello \itindex{heap} \textit{heap} per tenere traccia
+ delle zone di memoria allocata.} o i classici \textit{memory leak}.
+
+Abbiamo visto in sez.~\ref{sec:proc_mem_lock} come una prima funzionalità di
+ausilio nella ricerca di questi errori sia l'uso della variabile di ambiente
+\envvar{MALLOC\_CHECK\_}. Una modalità alternativa per effettuare dei
+controlli di consistenza sullo stato delle allocazioni di memoria eseguite con
+\func{malloc}, anche questa fornita come estensione specifica (e non standard)
+della \acr{glibc}, è quella di utilizzare la funzione \funcd{mcheck}, che deve
+essere chiamata prima di eseguire qualunque allocazione con \func{malloc}; il
+suo prototipo è:
+
+\begin{funcproto}{
+\fhead{mcheck.h}
+\fdecl{int mcheck(void (*abortfn) (enum mcheck\_status status))}
+\fdesc{Attiva i controlli di consistenza delle allocazioni di memoria.}
+}
+{La funzione ritorna $0$ in caso di successo e $-1$ per un errorre;
+ \var{errno} non viene impostata.}
+\end{funcproto}
+
+La funzione consente di registrare una funzione di emergenza che verrà
+eseguita tutte le volte che, in una successiva esecuzione di \func{malloc},
+venissero trovate delle inconsistenze, come delle operazioni di scrittura
+oltre i limiti dei buffer allocati. Per questo motivo la funzione deve essere
+chiamata prima di qualunque allocazione di memoria, altrimenti fallirà.
+
+Se come primo argomento di \func{mcheck} si passa \val{NULL} verrà utilizzata
+una funzione predefinita che stampa un messaggio di errore ed invoca la
+funzione \func{abort} (vedi sez.~\ref{sec:sig_alarm_abort}), altrimenti si
+dovrà creare una funzione personalizzata in grado di ricevere il tipo di
+errore ed agire di conseguenza.
+
+Nonostante la scarsa leggibilità del prototipo si tratta semplicemente di
+definire una funzione di tipo \code{void abortfn(enum mcheck\_status status)},
+che non deve restituire nulla e che deve avere un unico argomento di tipo
+\code{mcheck\_status}. In caso di errore la funzione verrà eseguita ricevendo
+un opportuno valore di \param{status} che è un tipo enumerato che può assumere
+soltanto i valori di tab.~\ref{tab:mcheck_status_value} che indicano la
+tipologia di errore riscontrata.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{7cm}|}
+ \hline
+ \textbf{Valore} & \textbf{Significato} \\
+ \hline
+ \hline
+ \const{MCHECK\_OK} & Riportato a \func{mprobe} se nessuna
+ inconsistenza è presente.\\
+ \const{MCHECK\_DISABLED}& Riportato a \func{mprobe} se si è chiamata
+ \func{mcheck} dopo aver già usato
+ \func{malloc}.\\
+ \const{MCHECK\_HEAD} & I dati immediatamente precedenti il buffer sono
+ stati modificati, avviene in genere quando si
+ decrementa eccessivamente il valore di un
+ puntatore scrivendo poi prima dell'inizio del
+ buffer.\\
+ \const{MCHECK\_TAIL} & I dati immediatamente seguenti il buffer sono
+ stati modificati, succede quando si va scrivere
+ oltre la dimensione corretta del buffer.\\
+ \const{MCHECK\_FREE} & Il buffer è già stato disallocato.\\
+ \hline
+ \end{tabular}
+ \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
+ funzione di terminazione installata con \func{mcheck}.}
+ \label{tab:mcheck_status_value}
+\end{table}
+
+Una volta che si sia chiamata \func{mcheck} con successo si può anche
+controllare esplicitamente lo stato delle allocazioni senza aspettare un
+errore nelle relative funzioni utilizzando la funzione \funcd{mprobe}, il cui
+prototipo è:
+
+\begin{funcproto}{
+\fhead{mcheck.h}
+\fdecl{enum mcheck\_status mprobe(ptr)}
+\fdesc{Esegue un controllo di consistenza delle allocazioni.}
+}
+{La funzione ritorna un codice fra quelli riportati in
+ tab.~\ref{tab:mcheck_status_value} e non ha errori.}
+\end{funcproto}
+
+La funzione richiede che si passi come argomento un puntatore ad un blocco di
+memoria precedentemente allocato con \func{malloc} o \func{realloc}, e
+restituisce lo stesso codice di errore che si avrebbe per la funzione di
+emergenza ad una successiva chiamata di una funzione di allocazione, e poi i
+primi due codici che indicano rispettivamente quando tutto è a posto o il
+controllo non è possibile per non aver chiamato \func{mcheck} in tempo.
+
+% TODO: trattare le altre funzionalità avanzate di \func{malloc}, mallopt,
+% mtrace, muntrace, mallinfo e gli hook con le glibc 2.10 c'è pure malloc_info
+% a sostituire mallinfo, vedi http://udrepper.livejournal.com/20948.html
+
+
+\section{Argomenti, ambiente ed altre proprietà di un processo}
+\label{sec:proc_options}
+
+In questa sezione esamineremo le funzioni che permettono di gestire gli
+argomenti e le opzioni, e quelle che consentono di manipolare ed utilizzare le
+variabili di ambiente. Accenneremo infine alle modalità con cui si può gestire
+la localizzazione di un programma modificandone il comportamento a seconda
+della lingua o del paese a cui si vuole faccia riferimento nelle sue
+operazioni.
+
+\subsection{Il formato degli argomenti}