X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=e67ae82e4e1acc25228e2846493e383b3a0d7610;hp=1127247800e688da58249ada4414f047c635718c;hb=388493a5b44babce8434148b87562aea0f046db7;hpb=43863d64be274fa4adfa5db745120aedb5f421c9 diff --git a/process.tex b/process.tex index 1127247..e67ae82 100644 --- a/process.tex +++ b/process.tex @@ -43,29 +43,30 @@ tutti gli altri.\footnote{questo non Quando un programma viene lanciato il kernel esegue un'opportuna routine di avvio, usando il programma \cmd{ld-linux.so}. Questo programma prima carica -le librerie condivise che servono al programma, poi effettua il link dinamico -del codice e alla fine lo esegue. Infatti, a meno di non aver specificato il -flag \texttt{-static} durante la compilazione, tutti i programmi in Linux sono -incompleti e necessitano di essere \textit{linkati} alle librerie condivise -quando vengono avviati. La procedura è controllata da alcune variabili di -ambiente e dal contenuto di \file{/etc/ld.so.conf}. I dettagli sono riportati -nella man page di \cmd{ld.so}. +le librerie condivise che servono al programma, poi effettua il collegamento +dinamico del codice e alla fine lo esegue. Infatti, a meno di non aver +specificato il flag \texttt{-static} durante la compilazione, tutti i +programmi in Linux sono incompleti e necessitano di essere \textsl{collegati} +alle librerie condivise quando vengono avviati. La procedura è controllata da +alcune variabili di ambiente e dal contenuto di \file{/etc/ld.so.conf}. I +dettagli sono riportati nella man page di \cmd{ld.so}. Il sistema fa partire qualunque programma chiamando la funzione \func{main}; sta al programmatore chiamare così la funzione principale del programma da cui si suppone iniziare l'esecuzione; in ogni caso senza questa funzione lo stesso -\textit{linker} darebbe luogo ad errori. - -Lo standard ISO C specifica che la funzione \func{main} può non avere -argomenti o prendere due argomenti che rappresentano gli argomenti passati da -linea di comando, in sostanza un prototipo che va sempre bene è il seguente: +\textit{linker} (ci chiama così il programma che effettua i collegamenti di +cui sopra) darebbe luogo ad errori. Lo standard ISO C specifica che la +funzione \func{main} può non avere argomenti o prendere due argomenti che +rappresentano gli argomenti passati da linea di comando, in sostanza un +prototipo che va sempre bene è il seguente: \includecodesnip{listati/main_def.c} In realtà nei sistemi Unix esiste un'altro modo per definire la funzione \func{main}, che prevede la presenza di un terzo argomento, \code{char - *envp[]}, che fornisce l'\textsl{ambiente} (vedi sez.~\ref{sec:proc_environ}) -del programma; questa forma però non è prevista dallo standard POSIX.1 per cui -se si vogliono scrivere programmi portabili è meglio evitarla. + *envp[]}, che fornisce (vedi sez.~\ref{sec:proc_environ}) +l'\textsl{ambiente} del programma; questa forma però non è prevista dallo +standard POSIX.1 per cui se si vogliono scrivere programmi portabili è meglio +evitarla. \subsection{Come chiudere un programma} @@ -151,7 +152,7 @@ non vengono salvati e le eventuali funzioni registrate con \func{atexit} e La funzione chiude tutti i file descriptor appartenenti al processo (si tenga presente che questo non comporta il salvataggio dei dati bufferizzati degli -stream), fa sì che ogni figlio del processo sia ereditato da \cmd{init} (vedi +stream), fa sì che ogni figlio del processo sia adottato da \cmd{init} (vedi cap.~\ref{cha:process_handling}), manda un segnale \const{SIGCHLD} al processo padre (vedi sez.~\ref{sec:sig_job_control}) ed infine ritorna lo stato di uscita specificato in \param{status} che può essere raccolto usando la @@ -265,7 +266,7 @@ nell'assegnare ad ogni processo uno spazio virtuale di indirizzamento lineare, in cui gli indirizzi vanno da zero ad un qualche valore massimo.\footnote{nel caso di Linux fino al kernel 2.2 detto massimo era, per macchine a 32bit, di 2Gb. Con il kernel 2.4 ed il supporto per la \textit{high-memory} il limite - è stato esteso.} + è stato esteso anche per macchine a 32 bit.} Come accennato in cap.~\ref{cha:intro_unix} questo spazio di indirizzi è virtuale e non corrisponde all'effettiva posizione dei dati nella RAM del @@ -374,8 +375,8 @@ seguenti segmenti: puntatori a \val{NULL}).\footnote{si ricordi che questo vale solo per le variabili che vanno nel segmento dati, e non è affatto vero in generale.} - Storicamente questo segmento viene chiamato BSS (da \textit{block started by - symbol}). La sua dimensione è fissa. + Storicamente questa seconda parte del segmento dati viene chiamata BSS (da + \textit{Block Started by Symbol}). La sua dimensione è fissa. \item Lo \textit{heap}. Tecnicamente lo si può considerare l'estensione del segmento dati, a cui di solito è posto giusto di seguito. È qui che avviene @@ -401,7 +402,7 @@ seguenti segmenti: \begin{figure}[htb] \centering - \includegraphics[height=12cm]{img/memory_layout} + \includegraphics[height=11cm]{img/memory_layout} \caption{Disposizione tipica dei segmenti di memoria di un processo.} \label{fig:proc_mem_layout} \end{figure} @@ -434,10 +435,10 @@ una funzione e per le sue variabili locali (le cosiddette \textsl{variabili per queste variabili viene allocato nello 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. +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 @@ -603,14 +604,13 @@ funzioni di libreria una propria versione (che pu specializzata per il debugging). Esistono varie librerie che forniscono dei sostituti opportuni delle routine di allocazione in grado, senza neanche ricompilare il programma,\footnote{esempi sono \textit{Dmalloc} - \href{http://dmalloc.com/}{http://dmalloc.com/} di Gray Watson ed + \href{http://dmalloc.com/}{\textsf{http://dmalloc.com/}} di Gray Watson ed \textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche molto complesse riguardo l'allocazione della memoria. - -\subsection{La funzione \func{alloca}} -\label{sec:proc_mem_alloca} +\subsection{Le funzioni \func{alloca}, \func{brk} e \func{sbrk}} +\label{sec:proc_mem_sbrk_alloca} Una possibile alternativa all'uso di \func{malloc}, che non soffre dei problemi di \textit{memory leak}\index{\textit{memory~leak}} descritti in @@ -666,9 +666,6 @@ Questo cui torneremo in sez.~\ref{sec:proc_auto_var}. -\subsection{Le funzioni \func{brk} e \func{sbrk}} -\label{sec:proc_mem_sbrk} - Queste due funzioni vengono utilizzate soltanto quando è necessario effettuare direttamente la gestione della memoria associata allo spazio dati di un processo, ad esempio qualora si debba implementare la propria versione delle @@ -902,7 +899,7 @@ di ambiente \cmd{IFS}. \begin{figure}[htb] \centering - \includegraphics[width=11cm]{img/argv_argc} + \includegraphics[width=13cm]{img/argv_argc} \caption{Esempio dei valori di \param{argv} e \param{argc} generati nella scansione di una riga di comando.} \label{fig:proc_argv_argc} @@ -921,7 +918,7 @@ questo meccanismo In generale un programma Unix riceve da linea di comando sia gli argomenti che le opzioni, queste ultime sono standardizzate per essere riconosciute come tali: un elemento di \param{argv} che inizia con il carattere \texttt{'-'} e -che non sia un singolo \texttt{'-'} o un \texttt{'--'} viene considerato +che non sia un singolo \texttt{'-'} o un \texttt{'-{}-'} viene considerato un'opzione. In genere le opzioni sono costituite da una lettera singola (preceduta dal carattere \cmd{'-'}) e possono avere o no un parametro associato; un comando tipico può essere quello mostrato in @@ -960,7 +957,7 @@ che indica che non ci sono pi dichiarata in \param{optstring} viene ritornato il carattere \texttt{'?'} mentre se un opzione che lo richiede non è seguita da un parametro viene ritornato il carattere \texttt{':'}, infine se viene incontrato il valore -\texttt{'--'} la scansione viene considerata conclusa, anche se vi sono altri +\texttt{'-{}-'} la scansione viene considerata conclusa, anche se vi sono altri elementi di \param{argv} che cominciano con il carattere \texttt{'-'}. \begin{figure}[htb] @@ -1050,7 +1047,7 @@ pi fig.~\ref{fig:proc_envirno_list}. \begin{figure}[htb] \centering - \includegraphics[width=11cm]{img/environ_var} + \includegraphics[width=13cm]{img/environ_var} \caption{Esempio di lista delle variabili di ambiente.} \label{fig:proc_envirno_list} \end{figure} @@ -1074,7 +1071,7 @@ delle relative chiamate (si veda sez.~\ref{sec:proc_exec}). La shell ad esempio ne usa molte per il suo funzionamento (come \texttt{PATH} per la ricerca dei comandi, o \texttt{IFS} per la scansione degli argomenti), -e alcune di esse (come \texttt{HOME}, \texttt{USER}, etc.) sono definite al +e alcune di esse (come \texttt{HOME}, \texttt{USER}, ecc.) sono definite al login (per i dettagli si veda sez.~\ref{sec:sess_login}). In genere è cura dell'amministratore definire le opportune variabili di ambiente in uno script di avvio. Alcune servono poi come riferimento generico per molti programmi @@ -1308,21 +1305,23 @@ Come vedremo nei capitoli successivi, non sempre numero fisso di argomenti per una funzione. Lo standard ISO C prevede nella sua sintassi la possibilità di definire delle \textit{variadic function}\index{variadic} che abbiano un numero variabile di argomenti, -attraverso l'uso della \textit{ellipsis} \code{...} nella dichiarazione della -funzione; ma non provvede a livello di linguaggio alcun meccanismo con cui -dette funzioni possono accedere ai loro argomenti. - -L'accesso viene invece realizzato dalle librerie standard che provvedono gli -strumenti adeguati. L'uso delle \textit{variadic function} prevede tre punti: -\begin{itemize*} +attraverso l'uso nella dichiarazione della funzione dello speciale costrutto +``\texttt{...}'', che viene chiamato \textit{ellipsis}. + +Lo standard però non provvede a livello di linguaggio alcun meccanismo con cui +dette funzioni possono accedere ai loro argomenti. L'accesso viene pertanto +realizzato a livello delle librerie standard del C che provvedono gli +strumenti adeguati. L'uso di una \textit{variadic function} prevede quindi +tre punti: +\begin{itemize} \item \textsl{Dichiarare} la funzione come \textit{variadic} usando un prototipo che contenga una \textit{ellipsis}. -\item \textsl{Definire} la funzione come \textit{variadic} usando lo stesso +\item \textsl{Definire} la funzione come \textit{variadic} usando la stessa \textit{ellipsis}, ed utilizzare le apposite macro che consentono la gestione di un numero variabile di argomenti. -\item \textsl{Chiamare} la funzione specificando prima gli argomenti fissi, e - a seguire gli addizionali. -\end{itemize*} +\item \textsl{Invocare} la funzione specificando prima gli argomenti fissi, ed + a seguire quelli addizionali. +\end{itemize} Lo standard ISO C prevede che una \textit{variadic function}\index{variadic} abbia sempre almeno un argomento fisso; prima di effettuare la dichiarazione @@ -1352,7 +1351,7 @@ L'unica modalit sequenziale; essi verranno estratti dallo stack secondo l'ordine in cui sono stati scritti. Per fare questo in \file{stdarg.h} sono definite delle apposite macro; la procedura da seguire è la seguente: -\begin{enumerate*} +\begin{enumerate} \item Inizializzare un puntatore alla lista degli argomenti di tipo \macro{va\_list} attraverso la macro \macro{va\_start}. \item Accedere ai vari argomenti opzionali con chiamate successive alla macro @@ -1360,7 +1359,7 @@ macro; la procedura da seguire il secondo e così via. \item Dichiarare la conclusione dell'estrazione degli argomenti invocando la macro \macro{va\_end}. -\end{enumerate*} +\end{enumerate} in generale è perfettamente legittimo richiedere meno argomenti di quelli che potrebbero essere stati effettivamente forniti, e nella esecuzione delle \macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti @@ -1486,15 +1485,15 @@ programma: quello dell'uscita in caso di errore. \index{salto~non-locale|(} -Il C però non consente di effettuare un salto ad -una etichetta definita in un'altra funzione, per cui se l'errore avviene in -una funzione, e la sua gestione ordinaria è in un'altra, occorre usare quello -che viene chiamato un \textsl{salto non-locale}. Il caso classico in cui si -ha questa necessità, citato sia da \cite{APUE} che da \cite{glibc}, è quello -di un programma nel cui corpo principale vengono letti dei dati in ingresso -sui quali viene eseguita, tramite una serie di funzioni di analisi, una -scansione dei contenuti da si ottengono le indicazioni per l'esecuzione delle -opportune operazioni. +Il C però non consente di effettuare un salto ad una etichetta definita in +un'altra funzione, per cui se l'errore avviene in una funzione, e la sua +gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un +\textsl{salto non-locale}. Il caso classico in cui si ha questa necessità, +citato sia in \cite{APUE} che in \cite{glibc}, è quello di un programma nel +cui corpo principale vengono letti dei dati in ingresso sui quali viene +eseguita, tramite una serie di funzioni di analisi, una scansione dei +contenuti, da cui si ottengono le indicazioni per l'esecuzione di opportune +operazioni. Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa in fasi diverse, la rilevazione di un errore nei dati in ingresso può accadere @@ -1575,10 +1574,10 @@ pertanto non si pu chiamate a questa funzione sono sicure solo in uno dei seguenti casi: \begin{itemize} \item come espressione di controllo in un comando condizionale, di selezione - o di iterazione (come \code{if}, \code{switch} o \code{while}). + o di iterazione (come \code{if}, \code{switch} o \code{while}); \item come operando per un operatore di uguaglianza o confronto in una espressione di controllo di un comando condizionale, di selezione o di - iterazione. + iterazione; \item come operando per l'operatore di negazione (\code{!}) in una espressione di controllo di un comando condizionale, di selezione o di iterazione. \item come espressione a sé stante.