054ff4428f4412159db68783f2b07c5ee6a9a794
[gapil.git] / signal.tex
1 \chapter{I segnali}
2 \label{sec:signals}
3
4 I segnali sono il primo e più semplice meccanismo di comunicazione nei
5 confronti dei processi. Non portano con se nessuna informazione che non sia il
6 loro tipo, si tratta in sostanza di un'interruzione software portata ad un
7 processo.
8
9 In genere i segnali vengono usati dal kernel per riportare situazioni
10 eccezionali (come errori di accesso, eccezioni aritmetiche, etc.) ma possono
11 anche essere usati come forma elementare di comunicazione fra processi (ad
12 esempio vengono usati per il controllo di sessione), per notificare eventi
13 (come la terminazione di un processo figlio), etc.
14
15 \section{I concetti base}
16 \label{sec:sig_base}
17
18 Come il nome stesso indica i segnali sono usati per notificare ad un processo
19 l'occorrenza di un evento eccezionale. Gli eventi che possono generare un
20 segnale sono vari; un breve elenco di possibile cause è il seguente:
21
22 \begin{itemize}
23 \item un errore del programma, come una divisione per zero o un tentativo di
24   accesso alla memoria fuori dai limiti validi.
25 \item la terminazione di un processo figlio.
26 \item la scadenza di un timer o di un allarme.
27 \item il tentativo di effettuare un'operazione di input/output che non può
28   essere eseguita.
29 \item una richiesta dell'utente di terminare o fermare il programma. In genere
30   si realizza attraverso un segnale mandato dalla shell in corrispondenza
31   della pressione di tasti come 'ctrl-c' o 'ctrl-z'.
32 \item l'esecuzione di una \texttt{kill} o di una \texttt{raise} da parte del
33   processo stesso o di un'altro (solo nel caso della \texttt{kill}).
34 \end{itemize}
35
36 Ciascuno di questi eventi (tranne gli ultimi due che sono controllati
37 dall'utente) comporta da parte del kernel la generazione un particolare tipo
38 di segnale.
39
40
41 \subsection{Le modalità di funzionamento}
42 \label{sec:sig_semantics}
43
44 Quando un processo riceve un segnale il kernel esegue una apposita routine di
45 gestione (il cosiddetto \textit{signal handler}) che può essere specificata
46 dall'utente.  Negli anni il comportamento del sistema in risposta ai segnali è
47 stato modificato in vari modi nelle differenti implementazioni di unix.
48 Attualmente si possono individuare due tipologie fondamentali di comportamento
49 dei segnali (dette semantiche) che vengono chiamate rispettivamente
50 \textit{reliable} e \textit{unreliable}.
51
52 Nella semantica \textit{unreliable} la routine di gestione del segnale
53 specificata dall'utente non resta installata una volta chiamata; è perciò a
54 carico dell'utente stesso ripetere l'installazione all'interno della routine
55 stessa in tutti i casi in cui si vuole che il signal handler esterno resti
56 attivo.
57
58 Per questo motivo è possibile una race-condition in cui il segnale arriva
59 prima che il suo manipolatore sia installato, nel qual caso il segnale può
60 essere perso o causare il comportamento originale (in genere la terminazione
61 del processo). Questa è la ragione per cui detti segnali sono chiamati
62 \textit{inaffidabili}, in quanto la ricezione del segnale e la reinstallazione
63 del suo manipolatore non sono operazioni atomiche.
64
65 In caso di implementazione inaffidabile le chiamate di sistema non sono fatte
66 ripartire automaticamente quando sono interrotte da un segnale, per questo il
67 programma deve controllare lo stato di uscita della chiamata al sistema e
68 riperterla nel caso l'errore riportato da \texttt{errno} sia \texttt{EINTR}.
69
70 Inoltre in questo caso non esiste una modalità semplice per ottenere una
71 operazione di pausa atomica (cioè mandare in sleep un processo fino all'arrivo
72 di un segnale), dato che ci sono casi in cui un segnale può arrivare quando il
73 programma non è in grado di accorgersene.
74
75 In caso di segnali \textit{reliable} invece il signal handler resta installato
76 quando viene chiamato e i problemi precedenti sono evitati. Inoltre alcune
77 chiamate di sistema possono essere fatte ripartire automaticamente e si può
78 ottenere un'operazione di pausa atomica (usando la funzione POSIX
79 \texttt{sigsuspend}).
80
81
82 \subsubsection{Tipi di segnali}
83 \label{sec:sig_types}
84
85
86 In generale gli eventi che generano i segnali si possono dividere in tre
87 categorie principali: errori, eventi e richieste esplicite. 
88
89 Un errore significa che un programma ha fatto qualcosa di sbagliato e non può
90 continuare ad essere eseguito. Non tutti gli errori causano dei segnali, in
91 genere la condizione di errore più comune comporta la restituzione di un
92 codice di errore da parte di una funzione di libreria, sono gli errori che
93 possono avvenire ovunque in un programma che causano l'emissione di un
94 segnale, come le divisioni per zero o l'uso di indirizzi di memoria non validi.
95
96 Un evento esterno ha in genere a che fare con l'I/O o con altri processi;
97 esempi di segnali di questo tipo sono quelli legati all'arrivo di dati di
98 input, scadenze di un timer, terminazione di processi figli.
99
100 Una richiesta esplicita significa l'uso di una chiamata di sistema (come
101 \texttt{kill} o \texttt{raise}) per la generazione di un segnale, cosa che
102 viene fatta usualmente dalla shell quando l'utente invoca la sequenza di tasti
103 di stop o di suspend, ma può essere pure inserita all'interno di un programma.
104
105 Si dice poi che i segnali possono essere \textit{asincroni} o
106 \textit{sincroni}. Un segnale sincrono è legato ad una azione specifica di un
107 programma ed è inviato (a meno che non sia bloccato) durante tale azione;
108 molti errori generano segnali sincroni, così come la richiesta esplicita da
109 parte del processo tramite le chiamate al sistema. Alcuni errori come la
110 divisione per zero non sono completamente sincroni e possono arrivare dopo
111 qualche istruzione.
112
113 I segnali asincroni sono generati da eventi fuori dal controllo del processo
114 che li riceve e arrivano in tempi impredicibili nel corso dell'esecuzione del
115 programma. Eventi esterni come la terminazione di un processo figlio generano
116 segnali asincroni, così come le richieste di generazione di un segnale
117 effettuate da altri processi.
118
119 In generale un tipo di segnale o è sincrono o è asincrono, salvo il caso in
120 cui esso sia generato attraverso una richiesta esplicita tramite chiamata al
121 sistema, nel qual caso qualunque tipo di segnale (quello scelto nella
122 chiamata) può diventare sincrono o asincrono a seconda che sia generato
123 internamente o esternamente al processo.
124
125 \section{La notifica dei segnali}
126 \label{sec:sig_notification}
127
128 Quando un segnale viene generato il kernel prende nota del fatto; si dice così
129 che diventa \textit{pending} (sospeso), e rimarrà tale fino al momento in cui
130 verrà notificato al processo a cui deve essere inviato.
131
132 Normalmente l'invio al processo che deve ricevere il segnale è immediato, a
133 meno che il segnale in questione non sia stato bloccato (\textit{blocked}) nel
134 qual caso l'invio non avviene ed il segnale resta sospeso indefinitamente. Una
135 volta però che esso venga sbloccato il segnale sarà subito notificato.
136
137 Una volta che il segnale viene notificato (che questo avvenga subito o dopo
138 una attesa più o meno lunga) viene eseguita l'azione specificata per detto
139 segnale. Per alcuni segnali (\texttt{SIGKILL} e \texttt{SIGSTOP}) questa azione
140 è fissa e non può essere cambiata, ma per tutti gli altri il programma può
141 specificare una scelta fra le tre seguenti:
142
143 \begin{itemize}
144 \item ignorare il segnale
145 \item utilizzare il manipolatore (\textit{signal handler}) specificato
146 \item accettare l'azione di default per quel segnale.
147 \end{itemize}
148
149 Il programma può specificare queste scelte usano le due routine
150 \texttt{signal} e \texttt{sigaction}; se si è installato un manipolatore sarà
151 quest'ultimo a intercettare il segnale ed ad essere eseguito, e mentre viene
152 eseguito (onde evitare race conditions) il segnale viene bloccato.
153
154 Se l'azione specificata per un certo tipo di segnale è quella di ignorarlo
155 questo sarà scartato immediatamente ogni volta che verrà generato, e questo
156 avverrà anche se in quel momento il segnale è bloccato. Per questo un segnale
157 ignorato non sarà mai notificato, anche se in seguito si sarà specificata una
158 diversa azione per lo stesso segnale.
159
160 Se arriva un segnale per il quale non è stato specificata un'azione viene
161 utilizzata l'azione standard. Questa è diversa da segnale a segnale (come
162 vedremo in \ref{sec:sig_standard}) ma per la maggior parte essa comporta la
163 terminazione del processo, per alcuni che invece rappresentano eventi innocui
164 l'azione standard è di non fare nulla.
165
166 Quando un segnale termina un processo, il padre può determinare la causa della
167 terminazione esaminando il codice di stato riportato delle funzioni
168 \texttt{wait} e \texttt{waitpid} in cui è riportato anche se la causa è un
169 segnale e nel caso quale; questo è il modo in cui la shell determina i motivi
170 della terminazione di un programma e scrive un eventuale messaggio di errore.
171
172 I segnali che rappresentano errori del programma (divisione per zero o
173 violazioni di accesso) hanno anche la caratteristica di scrivere un file
174 \textit{core dump} che registra lo stato del processo prima della terminazione
175 e può essere esaminato da un debugger per investigare sulla causa dell'errore.
176 Lo stesso avviene se i suddetti segnale vengono generati artificialmente con
177 una \texttt{kill}.
178
179
180
181 \subsection{I segnali standard}
182 \label{sec:sig_standard}
183
184 Esaminiamo ora i vari segnali disponibili e le loro caratteristiche. 
185 Ciascun segnale è identificato rispetto al sistema da un numero, ma l'uso
186 diretto di questo numero da parte dei programmi è da evitare, in quanto esso
187 può variare a seconda dell'implementazione del sistema.
188
189 Per questo ad ogni tipo di segnale viene associato un nome, che corrisponde
190 tramite una macro di preprocessore, al suddetto numero, e sono questi nomi,
191 che sono standardizzati e uniformi rispetto alle varie implementazioni, che si
192 devono usare nei programmi. Tutti i nomi e le funzioni che concernono i
193 segnali sono definiti nell'header di sistema \texttt{signal.h}.
194
195 Il numero totale di segnali presenti è dato dalla macro \texttt{NSIG}, e dato
196 che i numeri dei segnali sono allocati progressivamente, essa corrisponde
197 anche al successivo del valore numerico assegnato all'ultimo segnale definito.
198
199
200 \subsubsection{Segnali di errore di programma}
201
202 Questi segnali sono generati quando il sistema, o in certi casi direttamente
203 l'hardware (come per i page fault non valildi) rileva un qualche errore
204 insanabile nel programma in esecuzione. In generale la generazione di questi
205 segnali significa che il programma ha dei gravi problemi (ad esempio ha
206 dereferenziato un puntatore non valido o ha eseguito una operazione aritmetica
207 proibita) e l'esecuzione non può essere proseguita.
208
209 In genere si intercettano questi segnali per permettere al programma di
210 terminare in maniera pulita, ad esempio per ripristinare i settaggi della
211 console o eliminare i file di lock prima dell'uscita.  In questo caso il
212 manipolatore deve concludersi ripristinando l'azione di default e rialzando il
213 segnale, in questo modo il programma si concluderà senza effetti spiacevoli,
214 ma riportando lo stesso stato di uscita che avrebbe avuto se il manipolatore
215 non ci fosse stato.
216
217 L'azione di default per tutti questi segnali è causare la terminazione del
218 processo che li ha causati. In genere oltre a questo il segnale provoca pure
219 la registrazione su disco di un \textit{core dump file} che viene scritto in
220 un file \texttt{core} nella directory corrente del processo al momento
221 dell'errore.
222
223 Questi segnali sono:
224
225 \begin{itemize}
226 \item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome
227   derivi da \textit{floating point exception} si applica a tutti gli errori
228   aritmetici compresa la divisione per zero e l'overflow.
229
230 %   Per questo segnale le cose sono complicate dal fatto che possono esserci
231 %   molte diverse eccezioni che \texttt{SIGFPE} non distingue, mentre lo
232 %   standard IEEE per le operazioni in virgola mobile definisce vaire eccezioni
233 %   aritmetiche e richiede che esse siano notificate.  
234 \item \texttt{SIGILL} Il nome deriva da \textit{illegal instruction},
235   significa che il programma sta cercando di eseguire una istruzione
236   privilegiata od inesistente, in generale del codice illegale. Poiché il
237   compilatore del C genera del codice valido si ottiene questo segnale se il
238   file eseguibile è corrotto o si stanno cercando di eseguire dei
239   dati. Quest'ultimo caso può accadere quando si passa un puntatore sbagliato
240   al posto di un puntatore a funzione, o si eccede la scrittura di un array di
241   una variabile locale, andando a corrompere lo stack. Lo stesso segnale viene
242   generato in caso di overflow dello stack o di problemi nell'esecuzione di
243   di un signal handler.
244
245 \item \texttt{SIGSEGV} Il nome deriva da \textit{segment violation}, e
246   significa che il programma sta cercando di leggere o scrivere in una zona di
247   memoria protetta al di fuori di quella che gli è stata riservata dal
248   sistema. In genere è il meccanismo della protezione della memoria che si
249   accorge dell'errore ed il kernel genera il segnale.
250
251   È tipico ottenere questo segnale dereferenziando un puntatore nullo o non
252   inizializzatoo leggendo al di la della fine di un vettore. 
253
254 \item \texttt{SIGBUS} 
255 \item \texttt{SIGABRT} 
256 \item \texttt{SIGTRAP} 
257 \item \texttt{SIGSYS} 
258
259 \end{itemize}
260