Materiale scritto a nizza
[gapil.git] / process.tex
index 15dea095766b37b273fb868dc0683e40feed4412..7c104bc36ffa6df64c51f1e217b14b773de7e3b5 100644 (file)
@@ -844,6 +844,67 @@ motivi per cui si possono avere di queste necessit
   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, \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{functions}
+  \headdecl{unistd.h} 
+  \headdecl{sys/mman.h} 
+
+  \funcdecl{int mincore(void *addr, size\_t length, unsigned char *vec)}
+  Ritorna lo stato delle pagine di memoria occupate da un processo.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori seguenti:
+  \begin{errlist}
+  \item[\errcode{ENOMEM}] o \param{addr} + \param{lenght} eccede la dimensione
+    della memoria usata dal processo o l'intervallo di indirizzi specificato
+    non è mappato.
+  \item[\errcode{EINVAL}] \param{addr} non è un multiplo delle dimensioni di
+    una pagina.
+  \item[\errcode{EFAULT}] \param{vec} punta ad un indirizzo non valido.
+  \item[\errcode{EAGAIN}] il kernel è temporaneamente non in grado di fornire
+    una risposta.
+  \end{errlist}
+}
+\end{functions}
+
+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.\footnote{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 \index{paginazione} paginazione di parte della
@@ -884,7 +945,6 @@ standard POSIX.1 richiede che sia definita in \file{unistd.h} la macro
 in byte.\footnote{con Linux questo non avviene e si deve ricorrere alla
   funzione \func{getpagesize}, vedi sez.~\ref{sec:sys_memory_res}.} 
 
-
 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
@@ -986,7 +1046,6 @@ ci si scrive sopra.
 
 \itindend{memory~locking}
 
-
 \index{memoria~virtuale|)} 
 
 
@@ -1041,7 +1100,7 @@ liberata con \func{free}, cosa che non 
 implementazioni.
 
 Nessuna delle due funzioni ha una chiara standardizzazione (nessuna delle due
-compare in POSIX.1), ed inoltre ci sono indicazione discordi sui file che ne
+compare in POSIX.1), ed inoltre ci sono indicazioni discordi sui file che ne
 contengono la definizione;\footnote{secondo SUSv2 \func{valloc} è definita in
   \texttt{stdlib.h}, mentre sia le \acr{glibc} che le precedenti \acr{libc4} e
   \acr{lic5} la dichiarano in \texttt{malloc.h}, lo stesso vale per
@@ -1064,8 +1123,7 @@ funzioni precedenti, ma a differenza di \func{memalign} restituisce un codice
 di errore \errcode{EINVAL} anche se \param{alignment} non è un multiplo della
 la dimensione di \code{sizeof(void *)}. Come per le precedenti la memoria
 allocata con \func{posix\_memalign} può essere disallocata con
-\func{free}.\footnote{che in caso questo caso è quanto richiesto dallo
-  standard.}
+\func{free}.\footnote{che in questo caso è quanto richiesto dallo standard.}
 
 Un secondo caso in cui risulta estremamente utile poter avere un maggior
 controllo delle modalità di allocazione della memoria è quello in cui cercano
@@ -1099,14 +1157,85 @@ sia stampato il messaggio d'errore che abortito il programma. In genere 
 opportuno definire la variabile ad un valore diverso da zero che consente di
 rilevare un errore nel momento in cui avviene.
 
+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) delle \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{prototype}{mcheck.h}{mcheck(void (*abortfn) (enum mcheck\_status
+    status))} 
+  Attiva i controlli di consistenza delle allocazioni eseguite da \func{malloc}.
+  
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    fallimento; \var{errno} non viene impostata.}
+\end{prototype}
 
+La funzione consente di registrare una funzione di emergenza, da passare come
+argomento, 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à con un valore di ritorno pari a $-1$.
+
+Se come argomento di \func{mcheck} si passa \var{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à create
+una funzione personalizzata che verrà eseguita ricevendo un unico argomento di
+tipo \type{mcheck\_status},\footnote{trattasi in sostanza di un codice di
+  errore che la funzione di emergenza potrà utilizzare per prendere le
+  opportune azioni.} un tipo enumerato che può assumere soltanto i valori di
+tab.~\ref{tab:mcheck_status_value}.
 
-% TODO: trattare le funzionalità avanzate di \func{malloc}
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{7cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \macro{MCHECK\_OK}      & riportato (a \func{mprobe}) se nessuna
+                              inconsistenza è presente.\\
+    \macro{MCHECK\_DISABLED}& riportato (a \func{mprobe}) se si è chiamata
+                              \func{mcheck} dopo aver già usato
+                              \func{malloc}.\\
+    \macro{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.\\
+    \macro{MCHECK\_TAIL}    & i dati immediatamente seguenti il buffer sono
+                              stati modificati, succede quando si va scrivere
+                              oltre la dimensione correttta del buffer.\\
+    \macro{MCHECK\_FREE}    & il buffer è già stato disallocato.\\
+    \hline
+  \end{tabular}
+  \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
+    funzione di teminazione installata con \func{mcheck}.} 
+  \label{tab:mcheck_status_value}
+\end{table}
 
-% TODO documentare \func{madvise}
-% TODO documentare \func{mincore}
+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{prototype}{mcheck.h}{enum mcheck\_status mprobe(ptr)} 
+  Esegue un controllo di consistenza delle allocazioni.
+  
+  \bodydesc{La funzione restituisce un codice fra quelli riportati in
+    tab.\ref{tab:mcheck_status_value}.}
+\end{prototype}
 
+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, opzioni ed ambiente di un processo}
 \label{sec:proc_options}
@@ -1129,13 +1258,13 @@ manipolare ed utilizzare le variabili di ambiente.
 \subsection{Il formato degli argomenti}
 \label{sec:proc_par_format}
 
-In genere il passaggio degli argomenti al programma viene effettuato dalla
+In genere il passaggio degli argomenti ad un programma viene effettuato dalla
 shell, che si incarica di leggere la linea di comando e di effettuarne la
 scansione (il cosiddetto \textit{parsing}) per individuare le parole che la
 compongono, ciascuna delle quali viene considerata un argomento. Di norma per
-individuare le parole viene usato come carattere di separazione lo spazio o il
-tabulatore, ma il comportamento è modificabile attraverso l'impostazione della
-variabile di ambiente \cmd{IFS}.
+individuare le parole che andranno a costituire la lista degli argomenti viene
+usato come carattere di separazione lo spazio o il tabulatore, ma la cosa
+dipende ovviamente dalle modalità con cui si effettua il lancio.
 
 \begin{figure}[htb]
   \centering
@@ -1145,11 +1274,13 @@ variabile di ambiente \cmd{IFS}.
   \label{fig:proc_argv_argc}
 \end{figure}
 
-Nella scansione viene costruito il vettore di puntatori \param{argv} inserendo
-in successione il puntatore alla stringa costituente l'$n$-simo argomento; la
-variabile \param{argc} viene inizializzata al numero di argomenti trovati, in
-questo modo il primo argomento è sempre il nome del programma; un esempio di
-questo meccanismo è mostrato in fig.~\ref{fig:proc_argv_argc}.
+Indipendentemente da come viene eseguita, il risultato della scansione deve
+essere la costruzione del vettore di puntatori \param{argv} in cui si devono
+inserire in successione i puntatori alle stringhe costituenti i vari
+argomenti, e della variabile \param{argc} che deve essere inizializzata al
+numero di argomenti trovati. Nel caso della shell questo comporta che il primo
+argomento sia sempre il nome del programma; un esempio di questo meccanismo è
+mostrato in fig.~\ref{fig:proc_argv_argc}.
 
 
 \subsection{La gestione delle opzioni}
@@ -1474,20 +1605,18 @@ alla cancellazione di tutto l'ambiente per costruirne una versione
 ``\textsl{sicura}'' da zero.
 
 
-\subsection{Opzioni in formato esteso}
-\label{sec:proc_opt_extended}
-
-Oltre alla modalità ordinaria di gestione delle opzioni trattata in
-sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità
-alternativa costituita dalle cosiddette \textit{long-options}, che consente di
-esprimere le opzioni in una forma più descrittiva che nel caso più generale è
-qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''.
-
-(NdA: questa parte verrà inserita in seguito).
+%\subsection{Opzioni in formato esteso}
+%\label{sec:proc_opt_extended}
 
-% TODO opzioni in formato esteso 
+%Oltre alla modalità ordinaria di gestione delle opzioni trattata in
+%sez.~\ref{sec:proc_opt_handling} le \acr{glibc} forniscono una modalità
+%alternativa costituita dalle cosiddette \textit{long-options}, che consente di
+%esprimere le opzioni in una forma più descrittiva che nel caso più generale è
+%qualcosa del tipo di ``\texttt{-{}-option-name=parameter}''.
 
+%(NdA: questa parte verrà inserita in seguito).
 
+% TODO opzioni in formato esteso
 
 \section{Problematiche di programmazione generica}
 \label{sec:proc_gen_prog}