X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=signal.tex;h=f7e8bc5f34d91b6d5d6cff6885365b9452137778;hp=d3d05b828fd542eee5a7efce47628df941ddca16;hb=6e74264a76f38d92c33420801d6df62dae4fa64f;hpb=f385263eb52ef0963c1a2f422d194167de83dc3f diff --git a/signal.tex b/signal.tex index d3d05b8..f7e8bc5 100644 --- a/signal.tex +++ b/signal.tex @@ -59,8 +59,8 @@ in cui si vuole che il signal handler esterno resti attivo. In questo caso è possibile una situazione in cui i segnali possono essere perduti; si consideri il seguente segmento di codice in cui la prima operazione del manipolatore è quella di reinstallare se stesso: -\begin{lstlisting}{showlines=false} - +\footnotesize +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} int sig_handler(); /* handler function */ ... signal(SIGINT, sig_handler); /* establish handler */ @@ -72,6 +72,7 @@ int sig_handler() ... /* process signal */ } \end{lstlisting} +\normalsize se un secondo segnale arriva prima che il manipolatore invocato dal primo abbia eseguito la re-installazione di se stesso il segnale può essere perso o causare il comportamento originale assegnato al segnale (in genere la @@ -92,7 +93,8 @@ quello in cui si usa il manipolatore per settare un flag che riporta al processo l'occorrenza del segnale. Si consideri il seguente segmento di codice il cui scopo sarebbe quello di fermare il processo fino all'occorrenza di un opportuno segnale: -\begin{lstlisting}{} +\footnotesize +\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{} int signal_flag = 0; main () { @@ -111,6 +113,7 @@ int sig_handler() signal_flag = 1; /* set flag */ } \end{lstlisting} +\normalsize l'idea è che quando il processo trova il flag a zero viene messo in sleep e verrà risvegliato solo dalla ricezione di un segnale. Il manipolatore si limita in questo caso a settare il flag a uno; all'uscita dal manipolatore la @@ -160,8 +163,7 @@ usare la funzione \func{sigpending} (vedi \secref{sec:sig_sigpending}) per determinare quali segnali sono bloccati e quali sono pendenti. - -\subsubsection{Tipi di segnali} +\subsection{Tipi di segnali} \label{sec:sig_types} In generale gli eventi che generano i segnali si possono dividere in tre @@ -222,8 +224,9 @@ segnale. Per alcuni segnali (\texttt{SIGKILL} e \texttt{SIGSTOP}) questa azione specificare una scelta fra le tre seguenti: \begin{itemize} -\item ignorare il segnale -\item utilizzare il manipolatore (\textit{signal handler}) specificato +\item ignorare il segnale. +\item catturare il segnale, ed utilizzare il manipolatore (\textit{signal + handler}) specificato. \item accettare l'azione di default per quel segnale. \end{itemize} @@ -273,20 +276,21 @@ sono standardizzati e uniformi rispetto alle varie implementazioni, che si devono usare nei programmi. Tutti i nomi e le funzioni che concernono i segnali sono definiti nell'header di sistema \texttt{signal.h}. -Il numero totale di segnali presenti è dato dalla macro \texttt{NSIG}, e dato +Il numero totale di segnali presenti è dato dalla macro \macro{NSIG}, e dato che i numeri dei segnali sono allocati progressivamente, essa corrisponde anche al successivo del valore numerico assegnato all'ultimo segnale definito. In \ntab\ si è riportato l'elenco completo dei segnali definiti in Linux (estratto dalle man page), comparati con quelli definiti in vari standard. \begin{table}[htb] + \footnotesize \centering - \begin{tabular}[c]{|l|c|c|c||c|p{8cm}|} + \begin{tabular}[c]{|l|c|c|c||c|p{6cm}|} \hline Segnale & POSIX.1 & SUSv2 & Linux &Azione & Descrizione \\ \hline \hline - SIGHUP &$\bullet$&&$\bullet$& A & Hangup sul terminale o - morte del processo di controllo \\ + SIGHUP &$\bullet$&&$\bullet$& A & Hangup o + fine del processo di controllo \\ SIGINT &$\bullet$&&$\bullet$& A & Interrupt da tastiera (\cmd{C-c})\\ SIGQUIT &$\bullet$&&$\bullet$& C & Quit da tastiera (\cmd{C-y}) \\ SIGILL &$\bullet$&&$\bullet$& C & Istruzione illegale\\ @@ -305,8 +309,8 @@ In \ntab\ si SIGTSTP &$\bullet$&&$\bullet$& D & Stop typed at tty \\ SIGTTIN &$\bullet$&&$\bullet$& D & tty input for background process \\ SIGTTOU &$\bullet$&&$\bullet$& D & tty output for background process \\ - SIGBUS &&$\bullet$&$\bullet$& C & Bus error (bad memory access) \\ - SIGPOLL &&$\bullet$&$\bullet$& A & Pollable event (Sys V). Synonym of SIGIO\\ + SIGBUS &&$\bullet$&$\bullet$& C & Bus error (bad memory access) \\ + SIGPOLL &&$\bullet$&$\bullet$& A & Pollable event (Sys V). Synonym of SIGIO\\ SIGPROF &&$\bullet$&$\bullet$& A & Profiling timer expired \\ SIGSYS &&$\bullet$&$\bullet$& C & Bad argument to routine (SVID)\\ SIGTRAP &&$\bullet$&$\bullet$& C & Trace/breakpoint trap \\ @@ -342,7 +346,11 @@ stato dello stack e delle variabili al momento della ricezione del segnale. \begin{table}[htb] \centering - \begin{tabular}[c]{c p{10cm}} + \begin{tabular}[c]{|c|p{8cm}|} + \hline + Sigla & Significato \\ + \hline + \hline A & L'azione di default è terminare il processo. \\ B & L'azione di default è ignorare il segnale. \\ C & L'azione di default è terminare il processo e scrivere un \textit{core @@ -350,15 +358,18 @@ stato dello stack e delle variabili al momento della ricezione del segnale. D & L'azione di default è fermare il processo. \\ E & Il segnale non può essere intercettato. \\ F & Il segnale non può essere ignorato.\\ + \hline \end{tabular} \caption{Legenda delle caratteristiche dei segnali riportate in \tabref{tab:sig_signal_list}. } \label{tab:sig_action_leg} \end{table} -la descrizione dettagliata del significato dei vari segnali, raggruppati per -tipologia, è a seguire. -\subsubsection{Segnali di errore di programma} +La descrizione dettagliata del significato dei vari segnali, raggruppati per +tipologia, verrà affrontate nel seguito. + + +\subsection{Segnali di errore di programma} \label{sec:sig_prog_error} Questi segnali sono generati quando il sistema, o in certi casi direttamente @@ -379,13 +390,13 @@ non ci fosse stato. L'azione di default per tutti questi segnali è causare la terminazione del processo che li ha causati. In genere oltre a questo il segnale provoca pure la registrazione su disco di un file di \textit{core dump} che viene scritto -in un file \texttt{core} nella directory corrente del processo al momento +in un file \file{core} nella directory corrente del processo al momento dell'errore, che il debugger può usare per ricostruire lo stato del programma al momento della terminazione. Questi segnali sono: \begin{description} -\item \texttt{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome +\item \macro{SIGFPE} Riporta un errore aritmetico fatale. Benché il nome derivi da \textit{floating point exception} si applica a tutti gli errori aritmetici compresa la divisione per zero e l'overflow. @@ -394,7 +405,7 @@ Questi segnali sono: % standard IEEE per le operazioni in virgola mobile definisce vaire eccezioni % aritmetiche e richiede che esse siano notificate. -\item \texttt{SIGILL} Il nome deriva da \textit{illegal instruction}, +\item \macro{SIGILL} Il nome deriva da \textit{illegal instruction}, significa che il programma sta cercando di eseguire una istruzione privilegiata o inesistente, in generale del codice illegale. Poiché il compilatore del C genera del codice valido si ottiene questo segnale se il @@ -404,7 +415,7 @@ Questi segnali sono: una variabile locale, andando a corrompere lo stack. Lo stesso segnale viene generato in caso di overflow dello stack o di problemi nell'esecuzione di di un signal handler. -\item \texttt{SIGSEGV} Il nome deriva da \textit{segment violation}, e +\item \macro{SIGSEGV} Il nome deriva da \textit{segment violation}, e significa che il programma sta cercando di leggere o scrivere in una zona di memoria protetta al di fuori di quella che gli è stata riservata dal sistema. In genere è il meccanismo della protezione della memoria che si @@ -412,20 +423,20 @@ Questi segnali sono: È tipico ottenere questo segnale dereferenziando un puntatore nullo o non inizializzato leggendo al di la della fine di un vettore. -\item \texttt{SIGBUS} Il nome deriva da \textit{bus error}. Come - \texttt{SIGSEGV} questo è un segnale che viene generato di solito quando si - dereferenzia un puntatore non inzializzato, la differenza è - che\texttt{SIGSEGV} indica un accesso non permesso su un indirizzo esistente - (tipo fuori dallo heap o dallo stack), mentre \texttt{SIGBUS} indica +\item \macro{SIGBUS} Il nome deriva da \textit{bus error}. Come + \macro{SIGSEGV} questo è un segnale che viene generato di solito quando si + dereferenzia un puntatore non inzializzato, la differenza è che + \macro{SIGSEGV} indica un accesso non permesso su un indirizzo esistente + (tipo fuori dallo heap o dallo stack), mentre \macro{SIGBUS} indica l'accesso ad un indirizzo non valido, come nel caso di un puntatore non allineato. -\item \texttt{SIGABRT} Il nome deriva da \textit{abort}. Il segnale indica che +\item \macro{SIGABRT} Il nome deriva da \textit{abort}. Il segnale indica che il programma stesso ha rilevato un errore che viene riportato chiamando la - funzione \texttt{abort} che genera questo segnale. -\item \texttt{SIGTRAP} È il segnale generato da un'istruzione di breakpoint o + funzione \func{abort} che genera questo segnale. +\item \macro{SIGTRAP} È il segnale generato da un'istruzione di breakpoint o dall'attivazione del tracciamento per il processo. È usato dai programmi per il debugging e se un programma normale non dovrebbe ricevere questo segnale. -\item \texttt{SIGSYS} Sta ad indicare che si è eseguita una istruzione che +\item \macro{SIGSYS} Sta ad indicare che si è eseguita una istruzione che richiede l'esecuzione di una system call, ma si è fornito un codice sbagliato per quest'ultima. \end{description} @@ -501,13 +512,13 @@ di default segnali la scelta di default è irrilevante, in quanto il loro uso presuppone sempre la necessità di un manipolatore. Questi segnali sono: \begin{description} -\item \texttt{SIGALRM} Il nome sta per \textit{alarm}. Segnale la scadenza di +\item \macro{SIGALRM} Il nome sta per \textit{alarm}. Segnale la scadenza di un timer misurato sul tempo reale o sull'orologio di sistema. È normalmente usato dalla funzione \func{alarm}. -\item \texttt{SIGVTALRM} Il nome sta per \textit{virtual alarm}. È analogo al +\item \macro{SIGVTALRM} Il nome sta per \textit{virtual alarm}. È analogo al precedente ma segnala la scadenza di un timer sul tempo di CPU usato dal processo. -\item \texttt{SIGPROF} Il nome sta per \textit{profiling}. Indica la scadenza +\item \macro{SIGPROF} Il nome sta per \textit{profiling}. Indica la scadenza di un timer che misura sia il tempo di CPU speso direttamente dal processo che quello che il sistema ha speso per conto di quest'ultimo. In genere viene usato dai tool che servono a fare il profilo d'uso della CPU da parte @@ -524,14 +535,14 @@ generare questi segnali. L'azione di default è di essere ignorati. Questi segnali sono: \begin{description} -\item \texttt{SIGIO} Questo segnale viene inviato quando un file descriptor è +\item \macro{SIGIO} Questo segnale viene inviato quando un file descriptor è pronto per eseguire dell'input/output. In molti sistemi solo i socket e i terminali possono generare questo segnale, in Linux questo può essere usato anche per i file, posto che la \func{fcntl} abbia avuto successo. -\item \texttt{SIGURG} Questo segnale è inviato quando arrivano dei dati +\item \macro{SIGURG} Questo segnale è inviato quando arrivano dei dati urgenti o \textit{out of band} su di un socket; per maggiori dettagli al proposito si veda \secref{sec:xxx_urgent_data}. -\item \texttt{SIGPOLL} Questo segnale è equivalente a \macro{SIGIO}, è +\item \macro{SIGPOLL} Questo segnale è equivalente a \macro{SIGIO}, è definito solo per compatibilità con i sistemi System V. \end{description} @@ -544,7 +555,7 @@ cui si trattano gli argomenti relativi. Questi segnali sono: \begin{description} \item \macro{SIGCHLD} Questo è il segnale mandato al processo padre quando un figlio termina o viene fermato. L'azione di default è di ignorare il - segnale, la sua gestione è trattata in \secref{sec:prochand_wait}. + segnale, la sua gestione è trattata in \secref{sec:proc_wait}. \item \macro{SIGCLD} Per Linux questo è solo un segnale identico al precedente, il nome è obsoleto e andrebbe evitato. \item \macro{SIGCONT} Il nome sta per \textit{continue}. Il segnale viene @@ -586,16 +597,16 @@ resto del sistema. L'azione di default di questi segnali è di terminare il processo, questi segnali sono: \begin{description} -\item \texttt{SIGPIPE} Sta per \textit{Broken pipe}. Se si usano delle pipes o +\item \macro{SIGPIPE} Sta per \textit{Broken pipe}. Se si usano delle pipe o delle FIFO è necessario che, prima che un processo inizi a scrivere su di essa, un'altro abbia aperto la pipe in lettura (si veda \secref{sec:ipc_pipes}). Se il processo in lettura non è partito o è terminato inavvertitamente alla scrittura sulla pipe il kernel genera questo segnale. Se il segnale è bloccato, intercettato o ignorato la chiamata che lo ha causato fallisce restituendo l'errore \macro{EPIPE} -\item \texttt{SIGLOST} Sta per \textit{Resource lost}. -\item \texttt{SIGXCPU} Sta per \textit{CPU time limit exceeded}. -\item \texttt{SIGXFSZ} Sta per \textit{File size limit exceeded}. +\item \macro{SIGLOST} Sta per \textit{Resource lost}. +\item \macro{SIGXCPU} Sta per \textit{CPU time limit exceeded}. +\item \macro{SIGXFSZ} Sta per \textit{File size limit exceeded}. \end{description} @@ -605,23 +616,45 @@ segnali sono: Raccogliamo qui infine usa serie di segnali che hanno scopi differenti non classificabili in maniera omogenea. Questi segnali sono: \begin{description} -\item \texttt{SIGUSR1} e \texttt{SIGUSR2} Sono due segnali a disposizione +\item \macro{SIGUSR1} e \macro{SIGUSR2} Sono due segnali a disposizione dell'utente che li può usare per quello che vuole. Possono essere utili per implementare una comunicazione elementare fra processi diversi, o per eseguire a richiesta una operazione utilizzando un manipolatore. L'azione di - default è terminare il processo. -\item \texttt{SIGWINCH} Il nome sta per \textit{window (size) change} ed è + default è terminare il processo. +\item \macro{SIGWINCH} Il nome sta per \textit{window (size) change} ed è generato da molti sistemi (GNU/Linux compreso) quando le dimensioni (in righe e colonne) di un terminale vengono cambiate. Viene usato da alcuni programmi testuali per riformattare l'uscita su schermo quando si cambia dimensione a quest'ultimo. L'azione di default è di essere ignorato. -\item \texttt{SIGINFO} Il segnale indica una richiesta di informazioni. È +\item \macro{SIGINFO} Il segnale indica una richiesta di informazioni. È usato con il controllo di sessione, causa la stampa di informazioni da parte del processo leader del gruppo associato al terminale di controllo, gli altri processi lo ignorano. \end{description} +\subsection{Le funzioni \func{strsignal} e \func{psignal}} +\label{sec:sig_strsignal} + +Per la descrizione dei segnali il sistema mette a disposizione due funzioni +che stampano un messaggio di descrizione dato il numero. In genere si usano +quando si vuole notificare all'utente il segnale avvenuto (nel caso di +terminazione di un processo figlio o di un manipolatore che gestisce più +segnali); la prima funzione è una estensione GNU ed è analoga alla funzione +\func{strerr} per gli errori: +\begin{prototype}{string.h}{char * strsignal (int signum)} + Ritorna il puntatore ad una stringa allocata staticamente che contiene la + descrizione del segnale \var{signum}. +\end{prototype} + +Dato che la stringa è allocata staticamente non se ne deve modificare il +contenuto, che resta valido solo fino alla successiva chiamata di +\func{strsignal}; nel caso si debba mantenere traccia del messaggio sarà +necessario copiarlo. + +La seconda funzione deriva da BSD ed è analoga alla funzione \func{perror} +descritta in \secref{sec:intro_strerror}. + \section{La gestione dei segnali} \label{sec:sig_handlers}