X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=process.tex;h=92cb08eb38b2fa8612cd13d66ec17bce1536512a;hp=29ca369c201f0b8576df7336b1ed5c7dcb590ab2;hb=4367a0c9bfa422d8667a79b1875a9f815019c3c8;hpb=8247284097011dd78d9207d05efab85da02b7833 diff --git a/process.tex b/process.tex index 29ca369..92cb08e 100644 --- a/process.tex +++ b/process.tex @@ -41,7 +41,7 @@ tutti gli altri.\footnote{questo non \subsection{La funzione \func{main}} \label{sec:proc_main} -Quando un programma viene lanciato il kernel esegue un'opportuna routine di +Quando un programma viene lanciato il kernel esegue un opportuno codice di avvio, usando il programma \cmd{ld-linux.so}. Questo programma prima carica 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 @@ -77,7 +77,7 @@ modalit direttamente la funzione \func{exit} (che viene comunque chiamata automaticamente quando \func{main} ritorna). Una forma alternativa è quella di chiamare direttamente la system call \func{\_exit}, che restituisce il -controllo direttamente alla routine di conclusione dei processi del kernel. +controllo direttamente alla funzione di conclusione dei processi del kernel. Oltre alla conclusione ``\textsl{normale}'' esiste anche la possibilità di una conclusione ``\textsl{anomala}'' del programma a causa della ricezione di un @@ -283,7 +283,7 @@ dimensione fissa,\footnote{inizialmente questi erano di 4kb sulle macchine a comporta una perdita di prestazioni.} e ciascuna pagina nello spazio di indirizzi virtuale è associata ad un supporto che può essere una pagina di memoria reale o ad un dispositivo di stoccaggio secondario (come lo spazio -disco riservato alla swap, o i file che contengono il codice). Per ciasun +disco riservato alla swap, o i file che contengono il codice). Per ciascun processo il kernel si cura di mantenere un mappa di queste corrispondenze nella cosiddetta \itindex{page~table}\textit{page table}.\footnote{questa è una semplificazione brutale, il meccanismo è molto più complesso; una buona @@ -415,7 +415,7 @@ seguenti segmenti: \begin{figure}[htb] \centering - \includegraphics[height=11cm]{img/memory_layout} + \includegraphics[height=12cm]{img/memory_layout} \caption{Disposizione tipica dei segmenti di memoria di un processo.} \label{fig:proc_mem_layout} \end{figure} @@ -476,8 +476,9 @@ quattro: \funcd{malloc}, \funcd{calloc}, \funcd{realloc} e \funcd{free}, i loro prototipi sono i seguenti: \begin{functions} \headdecl{stdlib.h} -\funcdecl{void *calloc(size\_t size)} - Alloca \param{size} byte nello heap. La memoria viene inizializzata a 0. +\funcdecl{void *calloc(size\_t nmemb, size\_t size)} + Alloca nello heap un'area di memoria per un vettore di \param{nmemb} membri + di \param{size} byte di dimensione. La memoria viene inizializzata a 0. La funzione restituisce il puntatore alla zona di memoria allocata in caso di successo e \val{NULL} in caso di fallimento, nel qual caso @@ -554,7 +555,7 @@ assegnare sempre a \val{NULL} ogni puntatore liberato con \func{free}, dato che, quando l'argomento è un puntatore nullo, \func{free} non esegue nessuna operazione. -Le \acr{glibc} hanno un'implementazione delle routine di allocazione che è +Le \acr{glibc} hanno un'implementazione delle funzioni di allocazione che è controllabile dall'utente attraverso alcune variabili di ambiente, in particolare diventa possibile tracciare questo tipo di errori usando la variabile di ambiente \val{MALLOC\_CHECK\_} che quando viene definita mette in @@ -570,7 +571,7 @@ tollerante nei confronti di piccoli errori come quello di chiamate doppie a \end{itemize} Il problema più comune e più difficile da risolvere che si incontra con le -routine di allocazione è quando non viene opportunamente liberata la memoria +funzioni di allocazione è quando non viene opportunamente liberata la memoria non più utilizzata, quello che in inglese viene chiamato \textit{memory leak}\itindex{memory~leak}, cioè una \textsl{perdita di memoria}. @@ -615,13 +616,13 @@ genere va a scapito delle prestazioni dell'applicazione in esecuzione. % allocata da un oggetto. Per limitare l'impatto di questi problemi, e semplificare la ricerca di -eventuali errori, l'implementazione delle routine di allocazione delle +eventuali errori, l'implementazione delle funzioni di allocazione delle \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 routine di allocazione in grado, senza neanche +sostituti opportuni delle funzioni di allocazione in grado, senza neanche ricompilare il programma,\footnote{esempi sono \textit{Dmalloc} \href{http://dmalloc.com/}{\textsf{http://dmalloc.com/}} di Gray Watson ed \textit{Electric Fence} di Bruce Perens.} di eseguire diagnostiche anche @@ -677,6 +678,8 @@ spazio verrebbe allocato nel mezzo degli stessi. %cerca di allocare troppa memoria non si ottiene un messaggio di errore, ma un %segnale di \textit{segment violation} analogo a quello che si avrebbe da una %ricorsione infinita. +% TODO inserire più informazioni su alloca come da man page + 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 @@ -686,12 +689,14 @@ Questo cui torneremo in sez.~\ref{sec:proc_auto_var}. -Le due funzioni seguenti 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 routine di allocazione della memoria viste in -sez.~\ref{sec:proc_mem_malloc}. La prima funzione è \funcd{brk}, ed il suo -prototipo è: +Le due funzioni seguenti\footnote{le due funzioni sono state definite con BSD + 4.3, non fanno parte delle librerie standard del C e mentre sono state + esplicitamente escluse dallo standard POSIX.} 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 funzioni di allocazione della memoria +viste in sez.~\ref{sec:proc_mem_malloc}. La prima funzione è \funcd{brk}, ed +il suo prototipo è: \begin{prototype}{unistd.h}{int brk(void *end\_data\_segment)} Sposta la fine del segmento dei dati. @@ -707,7 +712,7 @@ deve comunque eccedere un eventuale limite (si veda sez.~\ref{sec:sys_resource_limit}) imposto sulle dimensioni massime dello spazio dati del processo. -La seconda funzione per la manipolazione delle dimensioni +Una seconda funzione per la manipolazione delle dimensioni \index{segmento!dati} del segmento dati\footnote{in questo caso si tratta soltanto di una funzione di libreria, e non di una system call.} è \funcd{sbrk}, ed il suo prototipo è: @@ -876,7 +881,7 @@ di indirizzi di un processo. I prototipi di queste funzioni sono: \bodydesc{Codici di ritorno ed errori sono gli stessi di \func{mlock} e \func{munlock}, con un kernel successivo al 2.6.9 l'uso di - func{munlockall} senza la \itindex{capabilities}\textit{capability} + \func{munlockall} senza la \itindex{capabilities}\textit{capability} \const{CAP\_IPC\_LOCK} genera un errore di \errcode{EPERM}.} \end{functions} @@ -915,6 +920,9 @@ che esse vengano mappate in RAM dallo \itindex{stack} stack, dopo di che, per essere sicuri che esse siano state effettivamente portate in memoria, ci si scrive sopra. +% TODO: trattare \func{madvise} + + \index{memoria~virtuale|)} \itindend{memory~locking} @@ -1320,7 +1328,7 @@ del passaggio pu Il passaggio di una variabile \textit{by value} significa che in realtà quello che viene passato alla subroutine è una copia del valore attuale di quella variabile, copia che la subroutine potrà modificare a piacere, senza che il -valore originale nella routine chiamante venga toccato. In questo modo non +valore originale nella funzione chiamante venga toccato. In questo modo non occorre preoccuparsi di eventuali effetti delle operazioni della subroutine sulla variabile passata come argomento. @@ -1329,13 +1337,13 @@ vale per qualunque variabile, puntatori compresi; quando per subroutine si usano dei puntatori (ad esempio per scrivere in un buffer) in realtà si va a modificare la zona di memoria a cui essi puntano, per cui anche se i puntatori sono copie, i dati a cui essi puntano sono sempre gli stessi, e -le eventuali modifiche avranno effetto e saranno visibili anche nella routine +le eventuali modifiche avranno effetto e saranno visibili anche nella funzione chiamante. Nella maggior parte delle funzioni di libreria e delle system call i puntatori vengono usati per scambiare dati (attraverso buffer o strutture) e le variabili semplici vengono usate per specificare argomenti; in genere le -informazioni a riguardo dei risultati vengono passate alla routine chiamante +informazioni a riguardo dei risultati vengono passate alla funzione chiamante attraverso il valore di ritorno. È buona norma seguire questa pratica anche nella programmazione normale. @@ -1590,9 +1598,10 @@ Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore diverso da zero viene restituito solo quando il ritorno è dovuto ad una chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo \itindex{stack} stack effettuando il salto non-locale. Si tenga conto che il -contesto salvato in \param{env} viene invalidato se la routine che ha chiamato -\func{setjmp} ritorna, nel qual caso un successivo uso di \func{longjmp} può -comportare conseguenze imprevedibili (e di norma fatali) per il processo. +contesto salvato in \param{env} viene invalidato se la funzione che ha +chiamato \func{setjmp} ritorna, nel qual caso un successivo uso di +\func{longjmp} può comportare conseguenze imprevedibili (e di norma fatali) +per il processo. Come accennato per effettuare un salto non-locale ad un punto precedentemente stabilito con \func{setjmp} si usa la funzione @@ -1678,3 +1687,24 @@ dichiarandole tutte come \direct{volatile}\footnote{la direttiva %%% mode: latex %%% TeX-master: "gapil" %%% End: + +% LocalWords: like exec kernel thread main ld linux static linker char envp Gb +% LocalWords: sez POSIX exit system call cap abort shell diff errno stdlib int +% LocalWords: SUCCESS FAILURE void atexit stream fclose unistd descriptor init +% LocalWords: SIGCHLD wait function glibc SunOS arg argp execve fig high kb Mb +% LocalWords: memory alpha swap table printf Unit MMU paging fault SIGSEGV BSS +% LocalWords: multitasking segmentation text segment NULL Block Started Symbol +% LocalWords: heap stack calling convention size malloc calloc realloc nmemb +% LocalWords: ENOMEM ptr uClib cfree error leak smartpointers hook Dmalloc brk +% LocalWords: Gray Watson Electric Fence Bruce Perens sbrk longjmp SUSv BSD ap +% LocalWords: ptrdiff increment locking lock copy write capabilities IPC mlock +% LocalWords: capability MEMLOCK limits getpagesize RLIMIT munlock sys const +% LocalWords: addr len EINVAL EPERM mlockall munlockall flags l'OR CURRENT IFS +% LocalWords: argc argv parsing questofile txt getopt optstring switch optarg +% LocalWords: optind opterr optopt ForkTest POSIXLY CORRECT long options NdA +% LocalWords: option parameter list environ PATH HOME XPG tab LOGNAME LANG PWD +% LocalWords: TERM PAGER TMPDIR getenv name SVr setenv unsetenv putenv opz gcc +% LocalWords: clearenv libc value overwrite string reference result argument +% LocalWords: socket variadic ellipsis header stdarg execl self promoting last +% LocalWords: float double short register type dest src extern setjmp jmp buf +% LocalWords: env return if while