Ancora reindicizzazioni, più CLONE_VFORK, CLONE_VM, CLONE_PTRACED
[gapil.git] / process.tex
index be725cdfa077dceb0143a4e0b48c180415233a1d..b25c6582a1db27571ba476e832190f6f73807e1c 100644 (file)
@@ -248,8 +248,7 @@ di quelli installati con il sistema,\footnote{in un sistema GNU/Linux che
   segue le specifiche del \textit{Filesystem Hierarchy Standard} (per maggiori
   informazioni si consulti sez.~1.2.3 di \cite{AGL}) si trovano sotto
   \texttt{/usr/include}.}  o fra virgolette, nel qual caso si fa riferimento
-ad una versione locale, da indicare con un \itindsub{pathname}{relativo}
-\textit{pathname} relativo:
+ad una versione locale, da indicare con un \textit{pathname} relativo:
 \includecodesnip{listati/main_include.c}
 
 Si tenga presente che oltre ai nomi riservati a livello generale di cui si è
@@ -427,10 +426,10 @@ usare un multiplo di 256, di avere uno stato di uscita uguale a zero, che
 verrebbe interpretato come un successo.
 
 Per questo motivo in \headfile{stdlib.h} sono definite, seguendo lo standard
-POSIX, le due costanti \const{EXIT\_SUCCESS} e \const{EXIT\_FAILURE}, da usare
-sempre per specificare lo stato di uscita di un processo. Su Linux, ed in
-generale in qualunque sistema POSIX, ad esse sono assegnati rispettivamente i
-valori 0 e 1.
+POSIX, le due costanti \constd{EXIT\_SUCCESS} e \constd{EXIT\_FAILURE}, da
+usare sempre per specificare lo stato di uscita di un processo. Su Linux, ed
+in generale in qualunque sistema POSIX, ad esse sono assegnati rispettivamente
+valori 0 e 1.
 
 \itindend{exit~status}
 
@@ -482,7 +481,7 @@ chiamata ad una funzione che effettui tali operazioni all'uscita dal
 programma. A questo scopo lo standard ANSI C prevede la possibilità di
 registrare un certo numero di funzioni che verranno eseguite all'uscita dal
 programma,\footnote{nel caso di \func{atexit} lo standard POSIX.1-2001
-  richiede che siano registrabili almeno \const{ATEXIT\_MAX} funzioni (il
+  richiede che siano registrabili almeno \constd{ATEXIT\_MAX} funzioni (il
   valore può essere ottenuto con \func{sysconf}, vedi
   sez.~\ref{sec:sys_limits}).} sia per la chiamata ad \func{exit} che per il
 ritorno di \code{main}. La prima funzione che si può utilizzare a tal fine è
@@ -663,7 +662,7 @@ bit e di 8kb sulle alpha. Con le versioni più recenti del kernel è possibile
 anche utilizzare pagine di dimensioni maggiori (di 4Mb, dette \textit{huge
   page}), per sistemi con grandi quantitativi di memoria in cui l'uso di
 pagine troppo piccole comporta una perdita di prestazioni. In alcuni sistemi
-la costante \const{PAGE\_SIZE}, definita in \headfile{limits.h}, indica la
+la costante \constd{PAGE\_SIZE}, definita in \headfile{limits.h}, indica la
 dimensione di una pagina in byte, con Linux questo non avviene e per ottenere
 questa dimensione si deve ricorrere alla funzione \func{getpagesize} (vedi
 sez.~\ref{sec:sys_memory_res}).
@@ -754,10 +753,10 @@ 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:
 \index{segmento!testo|(}
-\index{segmento!dati(}
+\index{segmento!dati|(}
 \itindbeg{heap} 
 \itindbeg{stack}
-\begin{enumerate*}
+\begin{enumerate}
 \item Il \textsl{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
@@ -783,7 +782,7 @@ programma C viene suddiviso nei seguenti segmenti:
     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*}
+  \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}
@@ -810,7 +809,7 @@ programma C viene suddiviso nei seguenti segmenti:
     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*}
+  \end{itemize}
 \item Il segmento di \textit{stack}, che contiene quello che viene chiamato lo
   ``\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
@@ -834,7 +833,7 @@ programma C viene suddiviso nei seguenti segmenti:
   La dimensione di questo segmento aumenta seguendo la crescita dello
   \textit{stack} del programma, ma non viene ridotta quando quest'ultimo si
   restringe.
-\end{enumerate*}
+\end{enumerate}
 
 \begin{figure}[htb]
   \centering
@@ -878,7 +877,7 @@ mai salvato sul file che contiene l'eseguibile, dato che viene sempre
 inizializzato a zero al caricamento del programma.
 
 \index{segmento!testo|)}
-\index{segmento!dati)}
+\index{segmento!dati|)}
 \itindend{heap} 
 \itindend{stack}
 
@@ -1074,25 +1073,23 @@ 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
-\textit{memory leak}.
-
-In C e C++ il problema è particolarmente sentito. In C++, per mezzo della
-programmazione ad oggetti, il problema dei \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.
+\textit{memory leak}.  In C e C++ il problema è particolarmente sentito. In
+C++, per mezzo della programmazione ad oggetti, il problema dei \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
+% \itindex{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
@@ -1155,7 +1152,7 @@ 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
+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
@@ -1174,7 +1171,6 @@ comportamento del programma può risultare indefinito, dando luogo ad una
 \textit{segment violation} la prima volta che cercherà di accedere alla
 memoria non effettivamente disponibile.
 
-
 \index{segmento!dati|(}
 \itindbeg{heap} 
 
@@ -1200,9 +1196,9 @@ uguale di 500). La prima funzione è \funcd{brk}, ed il suo prototipo è:
 La funzione è un'interfaccia all'omonima \textit{system call} ed imposta
 l'indirizzo finale del segmento dati di un processo (più precisamente dello
 \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.
+essere un valore ragionevole e la dimensione totale non deve comunque eccedere
+un eventuale limite (vedi sez.~\ref{sec:sys_resource_limit}) 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
@@ -1370,7 +1366,7 @@ 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
+\macrod{\_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
@@ -1454,10 +1450,10 @@ espressi dalle costanti riportate in tab.~\ref{tab:mlockall_flags}.
     \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.\\
+    \constd{MCL\_CURRENT}& blocca tutte le pagine correntemente mappate nello
+                           spazio di indirizzi del processo.\\
+    \constd{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
@@ -1636,20 +1632,20 @@ tipologia di errore riscontrata.
     \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.\\
+    \constd{MCHECK\_OK}      & Riportato a \func{mprobe} se nessuna
+                               inconsistenza è presente.\\
+    \constd{MCHECK\_DISABLED}& Riportato a \func{mprobe} se si è chiamata
+                               \func{mcheck} dopo aver già usato
+                               \func{malloc}.\\
+    \constd{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.\\
+    \constd{MCHECK\_TAIL}    & I dati immediatamente seguenti il buffer sono
+                               stati modificati, succede quando si va scrivere
+                               oltre la dimensione corretta del buffer.\\
+    \constd{MCHECK\_FREE}    & Il buffer è già stato disallocato.\\
     \hline
   \end{tabular}
   \caption{Valori dello stato dell'allocazione di memoria ottenibili dalla
@@ -1860,7 +1856,7 @@ Normalmente \func{getopt} compie una permutazione degli elementi di
 opzioni sono spostati in coda al vettore. Oltre a questa esistono altre due
 modalità di gestire gli elementi di \param{argv}; se \param{optstring} inizia
 con il carattere ``\texttt{+}'' (o è impostata la variabile di ambiente
-\macro{POSIXLY\_CORRECT}) la scansione viene fermata non appena si incontra un
+\cmd{POSIXLY\_CORRECT}) la scansione viene fermata non appena si incontra un
 elemento che non è un'opzione.
 
 L'ultima modalità, usata quando un programma può gestire la mescolanza fra
@@ -2319,7 +2315,7 @@ relativo puntatore fra le funzioni.
 \subsection{Il passaggio di un numero variabile di argomenti}
 \label{sec:proc_variadic}
 
-\index{funzioni!variadic|(}
+\index{funzioni!\textit{variadic}|(}
 
 Come vedremo nei capitoli successivi, non sempre è possibile specificare un
 numero fisso di argomenti per una funzione.  Lo standard ISO C prevede nella
@@ -2377,6 +2373,8 @@ quelli variabili vengono indicati in maniera generica dalla
 pertanto quella sequenziale, in cui vengono estratti dallo \textit{stack}
 secondo l'ordine in cui sono stati scritti nel prototipo della funzione.
 
+\macrobeg{va\_start}
+
 Per fare questo in \headfile{stdarg.h} sono definite delle macro specifiche,
 previste dallo standard ISO C89, che consentono di eseguire questa operazione.
 La prima di queste macro è \macro{va\_start}, che inizializza opportunamente
@@ -2396,6 +2394,8 @@ deve essere una apposita variabile di tipo \type{va\_list}; il
 parametro \param{last} deve indicare il nome dell'ultimo degli argomenti fissi
 dichiarati nel prototipo della funzione \textit{variadic}. 
 
+\macrobeg{va\_arg}
+
 La seconda macro di gestione delle liste di argomenti di una funzione
 \textit{variadic} è \macro{va\_arg}, che restituisce in successione un
 argomento della lista; la sua definizione è:
@@ -2423,8 +2423,10 @@ effettivamente forniti si otterranno dei valori indefiniti. Si avranno
 risultati indefiniti anche quando si chiama \macro{va\_arg} specificando un
 tipo che non corrisponde a quello usato per il corrispondente argomento.
 
+\macrobeg{va\_end}
+
 Infine una volta completata l'estrazione occorre indicare che si sono concluse
-le operazioni con la macro \macro{va\_end}, la cui definizione è:
+le operazioni con la macro \macrod{va\_end}, la cui definizione è:
 
 {\centering
 \begin{funcbox}{ 
@@ -2467,6 +2469,10 @@ caso però al ritorno della funzione \macro{va\_arg} non può più essere usata
 (anche se non si era completata l'estrazione) dato che il valore di \param{ap}
 risulterebbe indefinito.
 
+\macroend{va\_start}
+\macroend{va\_arg}
+\macroend{va\_end}
+
 Esistono dei casi in cui è necessario eseguire più volte la scansione degli
 argomenti e poter memorizzare una posizione durante la stessa. In questo caso
 sembrerebbe naturale copiarsi la lista degli argomenti \param{ap} con una
@@ -2489,7 +2495,7 @@ utilizzare solo attraverso dalle opportune funzioni di gestione.
 Per questo motivo una variabile di tipo \type{va\_list} non può essere
 assegnata direttamente ad un'altra variabile dello stesso tipo, ma 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
+  posto \macrod{\_\_va\_copy} che era il nome proposto in una bozza dello
   standard.}  ha previsto una macro ulteriore che permette di eseguire la
 copia di una lista degli argomenti:
 
@@ -2503,7 +2509,7 @@ copia di una lista degli argomenti:
 
 La macro copia l'attuale della lista degli argomenti \param{src} su una nuova
 lista \param{dest}. Anche in questo caso è buona norma chiudere ogni
-esecuzione di una \macro{va\_copy} con una corrispondente \macro{va\_end} sul
+esecuzione di una \macrod{va\_copy} con una corrispondente \macro{va\_end} sul
 nuovo puntatore alla lista degli argomenti.
 
 La chiamata di una funzione con un numero variabile di argomenti, posto che la
@@ -2535,7 +2541,7 @@ valore speciale per l'ultimo argomento, come fa ad esempio \func{execl} che
 usa un puntatore \val{NULL} per indicare la fine della lista degli argomenti
 (vedi sez.~\ref{sec:proc_exec}).
 
-\index{funzioni!variadic|)}
+\index{funzioni!\textit{variadic}|)}
 
 \subsection{Il controllo di flusso non locale}
 \label{sec:proc_longjmp}
@@ -2625,10 +2631,10 @@ dell'argomento \param{val} deve essere sempre diverso da zero, se si è
 specificato 0 sarà comunque restituito 1 al suo posto.
 
 In sostanza l'esecuzione di \func{longjmp} è analoga a quella di una
-istruzione \instruction{return}, solo che invece di ritornare alla riga
+istruzione \instr{return}, solo che invece di ritornare alla riga
 successiva della funzione chiamante, il programma in questo caso ritorna alla
 posizione della relativa \func{setjmp}. L'altra differenza fondamentale con
-\instruction{return} è che il ritorno può essere effettuato anche attraverso
+\instr{return} è che il ritorno può essere effettuato anche attraverso
 diversi livelli di funzioni annidate.
 
 L'implementazione di queste funzioni comporta alcune restrizioni dato che esse
@@ -2652,13 +2658,13 @@ dei seguenti casi:
 In generale, dato che l'unica differenza fra la chiamata diretta e quella
 ottenuta nell'uscita con un \func{longjmp} è costituita dal valore di ritorno
 di \func{setjmp}, pertanto quest'ultima viene usualmente chiamata all'interno
-di un una istruzione \instruction{if} che permetta di distinguere i due casi.
+di un una istruzione \instr{if} che permetta di distinguere i due casi.
 
 Uno dei punti critici dei salti non-locali è quello del valore delle
 variabili, ed in particolare quello delle variabili automatiche della funzione
 a cui si ritorna. In generale le variabili globali e statiche mantengono i
 valori che avevano al momento della chiamata di \func{longjmp}, ma quelli
-delle variabili automatiche (o di quelle dichiarate \direct{register}) sono in
+delle variabili automatiche (o di quelle dichiarate \dirct{register}) sono in
 genere indeterminati.
 
 Quello che succede infatti è che i valori delle variabili che sono tenute in