X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=f14150aa94728ffda3e09f31c8d270eda6ec0e28;hp=b25c6582a1db27571ba476e832190f6f73807e1c;hb=b0f9e84fb388f894bf26c87ffa304847bddfa3b0;hpb=04a547df13e4c672d95e1060e1ada9ae2e1fcb2f diff --git a/process.tex b/process.tex index b25c658..f14150a 100644 --- a/process.tex +++ b/process.tex @@ -1,6 +1,6 @@ %% process.tex %% -%% Copyright (C) 2000-2015 by Simone Piccardi. Permission is granted to +%% Copyright (C) 2000-2018 by Simone Piccardi. Permission is granted to %% copy, distribute and/or modify this document under the terms of the GNU Free %% Documentation License, Version 1.1 or any later version published by the %% Free Software Foundation; with the Invariant Sections being "Un preambolo", @@ -36,7 +36,7 @@ tutte le parti uguali siano condivise), avrà un suo spazio di indirizzi, variabili proprie e sarà eseguito in maniera completamente indipendente da tutti gli altri. Questo non è del tutto vero nel caso di un programma \textit{multi-thread}, ma la gestione dei \textit{thread} in Linux sarà -trattata a parte in cap.~\ref{cha:threads}. +trattata a parte\unavref{in cap.~\ref{cha:threads}}. \subsection{L'avvio e l'esecuzione di un programma} @@ -44,9 +44,9 @@ trattata a parte in cap.~\ref{cha:threads}. \itindbeg{link-loader} \itindbeg{shared~objects} -Quando un programma viene messo in esecuzione cosa che può essere fatta solo -con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}) il -kernel esegue un opportuno codice di avvio, il cosiddetto +Quando un programma viene messo in esecuzione, cosa che può essere fatta solo +con una funzione della famiglia \func{exec} (vedi sez.~\ref{sec:proc_exec}), +il kernel esegue un opportuno codice di avvio, il cosiddetto \textit{link-loader}, costituito dal programma \cmd{ld-linux.so}. Questo programma è una parte fondamentale del sistema il cui compito è quello della gestione delle cosiddette \textsl{librerie condivise}, quelle che nel mondo @@ -64,15 +64,15 @@ una sola volta per tutti i programmi che lo usano. Questo significa però che normalmente il codice di un programma è incompleto, contenendo solo i riferimenti alle funzioni di libreria che vuole utilizzare e non il relativo codice. Per questo motivo all'avvio del programma è necessario -l'intervento del \textit{link-loader} il cui compito è -caricare in memoria le librerie condivise eventualmente assenti, ed effettuare -poi il collegamento dinamico del codice del programma alle funzioni di -libreria da esso utilizzate prima di metterlo in esecuzione. +l'intervento del \textit{link-loader} il cui compito è caricare in memoria le +librerie condivise eventualmente assenti, ed effettuare poi il collegamento +dinamico del codice del programma alle funzioni di libreria da esso utilizzate +prima di metterlo in esecuzione. Il funzionamento di \cmd{ld-linux.so} è controllato da alcune variabili di -ambiente e dal contenuto del file \conffile{/etc/ld.so.conf}, che consentono -di elencare le directory un cui cercare le librerie e determinare quali -verranno utilizzate. In particolare con la variabile di ambiente +ambiente e dal contenuto del file \conffile{/etc/ld.so.conf} che consentono di +elencare le directory un cui cercare le librerie e determinare quali verranno +utilizzate. In particolare con la variabile di ambiente \envvar{LD\_LIBRARY\_PATH} si possono indicare ulteriori directory rispetto a quelle di sistema in cui inserire versioni personali delle librerie che hanno la precedenza su quelle di sistema, mentre con la variabile di ambiente @@ -213,27 +213,28 @@ definizioni. & ANSI C& POSIX& \\ \hline \hline - \headfile{assert.h}&$\bullet$& -- & Verifica le asserzioni fatte in un - programma.\\ - \headfile{ctype.h} &$\bullet$& -- & Tipi standard.\\ - \headfile{dirent.h}& -- &$\bullet$& Manipolazione delle directory.\\ - \headfile{errno.h} & -- &$\bullet$& Errori di sistema.\\ - \headfile{fcntl.h} & -- &$\bullet$& Controllo sulle opzioni dei file.\\ - \headfile{limits.h}& -- &$\bullet$& Limiti e parametri del sistema.\\ - \headfile{malloc.h}&$\bullet$& -- & Allocazione della memoria.\\ - \headfile{setjmp.h}&$\bullet$& -- & Salti non locali.\\ - \headfile{signal.h}& -- &$\bullet$& Gestione dei segnali.\\ - \headfile{stdarg.h}&$\bullet$& -- & Gestione di funzioni a argomenti + \headfiled{assert.h}&$\bullet$& -- & Verifica le asserzioni fatte in un + programma.\\ + \headfiled{ctype.h} &$\bullet$& -- & Tipi standard.\\ + \headfiled{dirent.h}& -- &$\bullet$& Manipolazione delle directory.\\ + \headfiled{errno.h} & -- &$\bullet$& Errori di sistema.\\ + \headfiled{fcntl.h} & -- &$\bullet$& Controllo sulle opzioni dei + file.\\ + \headfiled{limits.h}& -- &$\bullet$& Limiti e parametri del sistema.\\ + \headfiled{malloc.h}&$\bullet$& -- & Allocazione della memoria.\\ + \headfiled{setjmp.h}&$\bullet$& -- & Salti non locali.\\ + \headfiled{signal.h}& -- &$\bullet$& Gestione dei segnali.\\ + \headfiled{stdarg.h}&$\bullet$& -- & Gestione di funzioni a argomenti variabili.\\ - \headfile{stdio.h} &$\bullet$& -- & I/O bufferizzato in standard ANSI - C.\\ - \headfile{stdlib.h}&$\bullet$& -- & Definizioni della libreria - standard.\\ - \headfile{string.h}&$\bullet$& -- & Manipolazione delle stringhe.\\ - \headfile{time.h} & -- &$\bullet$& Gestione dei tempi.\\ - \headfile{times.h} &$\bullet$& -- & Gestione dei tempi.\\ - \headfile{unistd.h}& -- &$\bullet$& Unix standard library.\\ - \headfile{utmp.h} & -- &$\bullet$& Registro connessioni utenti.\\ + \headfiled{stdio.h} &$\bullet$& -- & I/O bufferizzato in standard ANSI + C.\\ + \headfiled{stdlib.h}&$\bullet$& -- & Definizioni della libreria + standard.\\ + \headfiled{string.h}&$\bullet$& -- & Manipolazione delle stringhe.\\ + \headfiled{time.h} & -- &$\bullet$& Gestione dei tempi.\\ + \headfiled{times.h} &$\bullet$& -- & Gestione dei tempi.\\ + \headfiled{unistd.h}& -- &$\bullet$& Unix standard library.\\ + \headfiled{utmp.h} & -- &$\bullet$& Registro connessioni utenti.\\ \hline \end{tabular} \caption{Elenco dei principali \textit{header file} definiti dagli standard @@ -273,7 +274,7 @@ esempio si avrà che: ``\texttt{TC}'' e con ``\texttt{B}'' seguito da un numero, \item in \headfile{grp.h} vengono riservati i nomi che iniziano con ``\texttt{gr\_}'', -\item in \headfile{pwd.h}vengono riservati i nomi che iniziano con +\item in \headfile{pwd.h} vengono riservati i nomi che iniziano con ``\texttt{pw\_}'', \end{itemize*} @@ -291,18 +292,28 @@ una qualunque funzione ordinaria, la situazione è totalmente diversa nell'esecuzione del programma. Una funzione ordinaria infatti viene eseguita, esattamente come il codice che si è scritto nel corpo del programma, in \textit{user space}. Quando invece si esegue una \textit{system call} -l'esecuzione ordinaria del programma viene interrotta, i dati forniti (come -argomenti della chiamata) vengono trasferiti al kernel che esegue il codice -della \textit{system call} (che è codice del kernel) in \textit{kernel space}. +l'esecuzione ordinaria del programma viene interrotta con quello che viene +usualmente chiamato un \itindex{context~switch} \textit{context + switch};\footnote{in realtà si parla più comunemente di \textit{context + switch} quando l'esecuzione di un processo viene interrotta dal kernel + (tramite lo \textit{scheduler}) per metterne in esecuzione un altro, ma il + concetto generale resta lo stesso: l'esecuzione del proprio codice in + \textit{user space} viene interrotta e lo stato del processo deve essere + salvato per poterne riprendere l'esecuzione in un secondo tempo.} il +contesto di esecuzione del processo viene salvato in modo da poterne +riprendere in seguito l'esecuzione ed i dati forniti (come argomenti della +chiamata) vengono trasferiti al kernel che esegue il codice della +\textit{system call} (che è codice del kernel) in \textit{kernel space}; al +completamento della \textit{system call} i dati salvati nel \textit{context + switch} saranno usati per riprendere l'esecuzione ordinaria del programma. Dato che il passaggio dei dati ed il salvataggio del contesto di esecuzione -del programma che consentirà di riprenderne l'esecuzione ordinaria al -completamento della \textit{system call} sono operazioni critiche per le -prestazioni del sistema, per rendere il più veloce possibile questa -operazione, usualmente chiamata \textit{context switch} sono state sviluppate -una serie di ottimizzazioni che richiedono alcune preparazioni abbastanza -complesse dei dati, che in genere dipendono dall'architettura del processore -sono scritte direttamente in \textit{assembler}. +sono operazioni critiche per le prestazioni del sistema, per rendere il più +veloce possibile questa operazione sono state sviluppate una serie di +ottimizzazioni che richiedono alcune preparazioni abbastanza complesse dei +dati, che in genere dipendono dall'architettura del processore e sono scritte +direttamente in \textit{assembler}. + % % TODO:trattare qui, quando sarà il momento vsyscall e vDSO, vedi: @@ -324,14 +335,19 @@ associazione, e lavorare a basso livello con una specifica versione, oppure si può voler utilizzare una \textit{system call} che non è stata ancora associata ad una funzione di libreria. In tal caso, per evitare di dover effettuare esplicitamente le operazioni di preparazione citate, all'interno della -\textsl{glibc} è fornita una specifica funzione, \funcd{syscall}, che consente -eseguire direttamente una \textit{system call}; il suo prototipo, accessibile -se si è definita la macro \macro{\_GNU\_SOURCE}, è: +\textsl{glibc} è fornita una specifica funzione, +\funcd{syscall},\footnote{fino a prima del kernel 2.6.18 per l'esecuzione + diretta delle \textit{system call} erano disponibili anche una serie di + macro \texttt{\_syscall\textsl{N}} (con $N$ pari al numero di argomenti + della \textit{system call}); queste sono deprecate e pertanto non ne + parleremo ulteriormente.} che consente eseguire direttamente una +\textit{system call}; il suo prototipo, accessibile se si è definita la macro +\macro{\_GNU\_SOURCE}, è: \begin{funcproto}{ \fhead{unistd.h} \fhead{sys/syscall.h} - \fdecl{int syscall(int number, ...)} + \fdecl{long syscall(int number, ...)} \fdesc{Esegue la \textit{system call} indicata da \param{number}.} } {La funzione ritorna un intero dipendente dalla \textit{system call} invocata, @@ -352,7 +368,7 @@ dall'architettura,\footnote{in genere le vecchie \textit{system call} non ciascuna \textit{system call} viene in genere identificata da una costante nella forma \texttt{SYS\_*} dove al prefisso viene aggiunto il nome che spesso corrisponde anche alla omonima funzione di libreria. Queste costanti sono -definite nel file \headfile{sys/syscall.h}, ma si possono anche usare +definite nel file \headfiled{sys/syscall.h}, ma si possono anche usare direttamente valori numerici. @@ -365,7 +381,7 @@ linguaggio C all'interno della stessa, o se si richiede esplicitamente la chiusura invocando direttamente la funzione \func{exit}. Queste due modalità sono assolutamente equivalenti, dato che \func{exit} viene chiamata in maniera trasparente anche quando \code{main} ritorna, passandogli come argomento il -valore di ritorno (che essendo . +valore di ritorno. La funzione \funcd{exit}, che è completamente generale, essendo definita dallo standard ANSI C, è quella che deve essere invocata per una terminazione @@ -436,8 +452,12 @@ i valori 0 e 1. Una forma alternativa per effettuare una terminazione esplicita di un programma è quella di chiamare direttamente la \textit{system call} \funcd{\_exit},\footnote{la stessa è definita anche come \funcd{\_Exit} in - \headfile{stdlib.h}.} che restituisce il controllo direttamente al kernel, -concludendo immediatamente il processo, il suo prototipo è: + \headfile{stdlib.h}, inoltre a partire dalle \acr{glibc} 2.3 usando questa + funzione viene invocata \func{exit\_group} che termina tutti i + \textit{thread} del processo e non solo quello corrente (fintanto che non si + usano i \textit{thread}\unavref{, vedi sez.~\ref{cha:threads},} questo non + fa nessuna differenza).} che restituisce il controllo direttamente al +kernel, concludendo immediatamente il processo, il suo prototipo è: \begin{funcproto}{ \fhead{unistd.h} \fdecl{void \_exit(int status)} \fdesc{Causa la conclusione immediata del programma.} } {La funzione non @@ -1223,12 +1243,12 @@ segmento dati\footnote{in questo caso si tratta soltanto di una funzione di caso \var{errno} assumerà il valore \errcode{ENOMEM}.} \end{funcproto} -La funzione incrementa la dimensione dello \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 \ctyp{ptrdiff\_t}, -\ctyp{ssize\_t}, \ctyp{int}. Se invocata con un valore nullo la funzione +La funzione incrementa la dimensione dello \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 +\typed{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 @@ -1422,6 +1442,9 @@ blocco. Con kernel diversi da Linux si può ottenere un errore di pagine di memoria, pertanto se si ha a cuore la portabilità si deve avere cura di allinearne correttamente il valore. +% TODO trattare mlock2, introdotta con il kernel 4.4 (vedi +% http://lwn.net/Articles/650538/) + Altre due funzioni di sistema, \funcd{mlockall} e \funcd{munlockall}, consentono di bloccare genericamente la paginazione per l'intero spazio di indirizzi di un processo. I prototipi di queste funzioni sono: @@ -2389,10 +2412,10 @@ una lista degli argomenti, la sua definizione è: } \end{funcbox}} -La macro inizializza il puntatore alla lista di argomenti \param{ap} che -deve essere una apposita variabile di tipo \type{va\_list}; il +La macro inizializza il puntatore alla lista di argomenti \param{ap} che 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}. +dichiarati nel prototipo della funzione \textit{variadic}. \macrobeg{va\_arg} @@ -2484,15 +2507,15 @@ assolutamente normale pensare di poter effettuare questa operazione. \index{tipo!opaco|(} In generale però possono esistere anche realizzazioni diverse, ed è per questo -motivo che invece che di un semplice puntatore viene \type{va\_list} è quello -che viene chiamato un \textsl{tipo opaco}. Si chiamano così quei tipi di dati, -in genere usati da una libreria, la cui struttura interna non deve essere -vista dal programma chiamante (da cui deriva il nome opaco) che li devono -utilizzare solo attraverso dalle opportune funzioni di gestione. +motivo che invece che un semplice puntatore, \typed{va\_list} è quello che +viene chiamato un \textsl{tipo opaco}. Si chiamano così quei tipi di dati, in +genere usati da una libreria, la cui struttura interna non deve essere vista +dal programma chiamante (da cui deriva il nome opaco) che li devono utilizzare +solo attraverso dalle opportune funzioni di gestione. \index{tipo!opaco|)} -Per questo motivo una variabile di tipo \type{va\_list} non può essere +Per questo motivo una variabile di tipo \typed{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 \macrod{\_\_va\_copy} che era il nome proposto in una bozza dello @@ -2597,7 +2620,7 @@ di salvare il contesto dello \textit{stack} è \funcd{setjmp}, il cui prototipo Quando si esegue la funzione il contesto corrente dello \textit{stack} viene salvato nell'argomento \param{env}, una variabile di tipo -\type{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di +\typed{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di \textsl{tipo opaco}.} che deve essere stata definita in precedenza. In genere le variabili di tipo \type{jmp\_buf} vengono definite come variabili globali in modo da poter essere viste in tutte le funzioni del programma. @@ -2686,6 +2709,10 @@ dichiarandole tutte come \direct{volatile}.\footnote{la direttiva \index{salto~non-locale|)} +% TODO trattare qui le restartable sequences (vedi +% https://lwn.net/Articles/664645/ e https://lwn.net/Articles/650333/) se e +% quando saranno introdotte + \subsection{La \textit{endianness}} \label{sec:endianness}