SIGNAL(7) | Linux Programmer's Manual | SIGNAL(7) |
signal - panoramica sui segnali
Linux supporta sia i segnali POSIX affidabili (d'ora in avanti "segnali standard") che i segnali real-time POSIX.
Ciascun segnale ha una disposizione attuale, che determina come si comporta il processo quando il segnale viene recapitato.
Le voci nella colonna "Azione" della tabella qui sotto specificano la disposizione predefinita di ogni segnale, come segue:
Un processo può cambiare la disposizione di un segnale usando sigaction(2) o signal(2) (l'ultimo è meno portabile quando si crea un gestore di segnale; si veda signal(2) per i dettagli). Usando queste chiamate di sistema, un processo può assumere uno dei seguenti comportamenti al recapito del segnale: eseguire l'azione predefinita; ignorare il segnale; intercettare il segnale con un gestore di segnale, una funzione definita dal programmatore che è automaticamente invocata quando il segnale è recapitato (il gestore di segnale viene chiamato, in modo predefinito, nel normale stack del processo. È possibile fare in modo che il gestore di segnale usi uno stack alternativo: vedere sigaltstack(2) per una discussione su come farlo e quando può essere utile).
La disposizione del segnale è un attributo per processo: in un'applicazione multithread, la disposizione di un particolare segnale è la stessa per tutti i thread.
Un processo figlio creato tramite fork(2) eredita una copia della disposizione dei segnali del genitore. Durante un execve(2), la disposizione dei segnali gestiti viene inizializzata ai valori predefiniti; la disposizione dei segnali ignorati viene lasciata com'è.
Le seguenti chiamate di sistema e funzioni di libreria permettono al chiamante di inviare un segnale:
Le seguenti chiamate di sistema sospendono l'esecuzione del processo chiamante o del thread finché non viene intercettato un segnale (o finché un segnale non gestito fa terminare il processo):
Anziché intercettare un segnale in modo asincrono tramite un gestore di segnale, è possibile accettare il segnale in modo sincrono, cioé bloccare l'esecuzione finché il segnale viene consegnato: a questo punto il kernel restituirà informazioni sul segnale al chiamante. Ci sono in generale due modi per farlo:
Un segnale può essere bloccato, cioé non verrà recapitato fino a quando non verrà sbloccato. Un segnale viene definito pendente nel periodo di tempo che passa tra quando è stato generato e quando è recapitato.
Ciascun thread in un processo ha una maschera segnale indipendente, che indica l'insieme di segnali che il thread attualmente sta bloccando. Un thread può manipolare la sua maschera segnale usando pthread_sigmask(3). In un'applicazione tradizionale a thread singolo, si può usare sigprocmask(2) per manipolare la maschera segnale.
Un processo figlio creato tramite fork(2) eredita una copia della maschera di segnale del processo genitore: la maschera di segnale viene preservata attraverso execve(2).
Un segnale può essere generato (e quindi pendente) per un processo nel suo insieme (per esempio quando è inviato usando kill(2)) o per uno specifico thread (per esempio certi segnali, come SIGSEGV e SIGFPE, generati come conseguenza dell'esecuzione di una istruzione specifica in linguaggio macchina sono diretti al thread, come lo sono i segnali indirizzati a uno specifico thread usando pthread_kill(3)). Un segnale diretto al processo può essere recapitato a uno qualunque dei thread che attualmente non hanno il segnale bloccato. Se più di uno dei thread ha il segnale sbloccato, allora il kernel sceglie un thread arbitrario a cui recapitare il segnale.
Un thread può ottenere l'insieme di segnali che attualmente ha pendenti usando sigpending(2). Questo insieme consisterà nell'unione dell'insieme dei segnali diretti ai processi pendenti e l'insieme di segnali pendenti per il thread chiamante.
L'insieme di segnali pendenti di un processo figlio creato tramite fork(2) inizialmente è vuoto: l'insieme di segnali pendenti è preservato attraverso execve(2).
Linux supporta i segnali standard elencati di seguito. Molti numeri di segnale dipendono dall'architettura, come indicato nella colonna "Valore" (dove sono indicati tre valori, il primo è normalmente valido per alpha e sparc, quello in mezzo per x86, arm e la maggior parte delle altre architetture, e l'ultimo per mips (i valori per parisc non vengono mostrati; si vedano i sorgenti del kernel Linux per la numerazione dei segnali su questa architettura). A - denota che un segnale è assente sulla corrispondente architettura).
Prima i segnali descritti nello standard POSIX.1-1990 originale.
Segnale | Valore | Azione | Commento |
SIGHUP | 1 | Term | La linea sul terminale che ha il controllo è stata |
agganciata o il processo che ha il controllo è morto | |||
SIGINT | 2 | Term | Interrupt da tastiera |
SIGQUIT | 3 | Core | Segnale d'uscita della tastiera |
SIGILL | 4 | Core | Istruzione illegale |
SIGABRT | 6 | Core | Segnale d'abbandono di abort(3) |
SIGFPE | 8 | Core | Eccezione in virgola mobile |
SIGKILL | 9 | Term | Termina il processo |
SIGSEGV | 11 | Core | Riferimento di memoria non valido |
SIGPIPE | 13 | Term | Pipe rotta: scrittura su una pipe priva di |
lettori | |||
SIGALRM | 14 | Term | Segnale del timer da alarm(2) |
SIGTERM | 15 | Term | Segnale di termine |
SIGUSR1 | 30,10,16 | Term | Segnale 1 definito dall'utente |
SIGUSR2 | 31,12,17 | Term | Segnale 2 definito dall'utente |
SIGCHLD | 20,17,18 | Ign | Figlio fermato o terminato |
SIGCONT | 19,18,25 | Cont | Continua se fermato |
SIGSTOP | 17,19,23 | Stop | Ferma il processo |
SIGTSTP | 18,20,24 | Stop | Stop digitato dal terminale |
SIGTTIN | 21,21,26 | Stop | Input da terminale per un processo sullo sfondo |
SIGTTOU | 22,22,27 | Stop | Output da terminale per un processo sullo sfondo |
I segnali SIGKILL e SIGSTOP non possono essere intercettati, bloccati o ignorati.
Seguono i segnali che non sono nello standard POSIX.1-1990 ma sono descritti in SUSv2 e POSIX.1-2001.
Segnale | Valore | Azione | Commento |
SIGBUS | 10,7,10 | Core | Errore sul bus (accesso errato alla memoria) |
SIGPOLL | Term | Evento suscettibile di polling (Sys V). | |
Sinonimo di SIGIO | |||
SIGPROF | 27,27,29 | Term | Timer del profiler scaduto |
SIGSYS | 12,31,12 | Core | Argomento errato alla routine (SVr4) |
SIGTRAP | 5 | Core | Trappola per trace/breakpoint |
SIGURG | 16,23,21 | Ign | Condizione urgente sul socket (4.2BSD) |
SIGVTALRM | 26,26,28 | Term | Allarme virtuale (4.2BSD) |
SIGXCPU | 24,24,30 | Core | Superato tempo limite di CPU (4.2BSD) |
SIGXFSZ | 25,25,31 | Core | Limite dimensione file superato (4.2BSD) |
Fino a Linux 2.2 incluso, il comportamento predefinito per SIGSYS, SIGXCPU, SIGXFSZ, e (su architetture diverse da SPARC e MIPS) SIGBUS era terminare il processo (senza eseguire un core dump). (In alcuni altri sistemi UNIX l'azione predefinita per SIGXCPU e SIGXFSZ è terminare il processo senza eseguire un core dump.) Linux 2.4 è conforme ai requisiti di POSIX.1-2001 per questi segnali, terminando il processo con un core dump.
E ora altri vari segnali.
Segnale | Valore | Azione | Commento |
SIGIOT | 6 | Core | Trappola IOT. Sinonimo di SIGABRT |
SIGEMT | 7,-,7 | Term | |
SIGSTKFLT | -,16,- | Term | Errore dello stack del coprocessore (inutilizzato) |
SIGIO | 23,29,22 | Term | I/O ora possibile (4.2 BSD) |
SIGCLD | -,-,18 | Ign | Sinonimo di SIGCHLD |
SIGPWR | 29,30,19 | Term | Mancanza di corrente (System V) |
SIGINFO | 29,-,- | Sinonimo di SIGPWR | |
SIGLOST | -,-,- | Term | Perso il lock del file (non usato) |
SIGWINCH | 28,28,20 | Ign | Dimensioni finestra cambiate (4.3BSD, Sun) |
SIGUNUSED | -,31,- | Core | Sinonimo di SIGSYS) |
(Il segnale 29 è SIGINFO / SIGPWR su alpha ma SIGLOST su sparc.)
SIGEMT non è specificato in POSIX.1-2001, tuttavia appare in molti altri sistemi UNIX, dove la sua azione predefinita è tipicamente di terminare il processo con un core dump.
SIGPWR (non specificato in POSIX.1-2001) è tipicamente ignorato in via predefinita in questi altri UNIX dove appare.
SIGIO (non specificato in POSIX.1-2001) è ignorato in via predefinita in molti altri sistemi UNIX.
Dove definito, SIGUNUSED è sinonimo di SIGSYS sulla maggior parte delle architetture.
Linux supporta i segnali real-time come originariamente definiti nelle estensioni real-time di POSIX.1b (e ora incluse in POSIX.1-2001). L'intervallo di segnali real-time supportati è definito dalle macro SIGRTMIN e SIGRTMAX. POSIX.1-2001 richiede che un'implementazione supporti almeno i segnali real-time _POSIX_RTSIG_MAX(8) .
Il kernel Linux supporta un intervallo di 32 diversi segnali real-time, numerati da 33 a 64. Comunque, l'implementazione di glibc POSIX dei thread usa internamente due (per NTPL) o tre (per LinuxThreads) segnali real-time (vedere pthreads(7)), e sistema il valore di SIGRTMIN in modo adatto (a 34 o 35). Dato che l'intervallo di segnali real-time disponibili varia a seconda dell'implementazione dei thread di glibc (e questa variazione può avvenire al run-time in accordo con kernel e glibc disponibili), e poiché l'intervallo dei segnali real-time varia tra i vari sistemi UNIX, i programmi non dovrebbero mai riferirsi ai segnali real-time usando numeri prefissati. Dovrebbero invece sempre fare riferimento ai segnali real-time usando la notazione SIGRTMIN+n, e includere controlli adatti (run-time) perché SIGRTMIN+n non ecceda SIGRTMAX.
Diversamente dai segnali standard, i segnali real-time non hanno significati predefiniti: l'intero insieme dei segnali real-time può essere usato per scopi definiti dall'applicazione.
L'azione predefinita per i segnali real-time non gestiti è di terminare il processo ricevente.
I segnali real-time si distinguono da quanto segue:
Se sia i segnali predefinit che quelli real-time sono in attesa di un processo, POSIX non specifica quale consegnare per primo. Linux, come molte altre implementazioni, in questo caso dà priorità ai segnali predefiniti.
Conformemente a POSIX, un'implementazione deve permettere che almeno (32) segnali real-time _POSIX_SIGQUEUE_MAX vengano accodati a un processo. Tuttavia Linux fa le cose diversamente. Nei kernel fino a e incluso il 2.6.7, Linux impone un limite globale al numero di segnali real-time accodati per tutti i processi. Questo limite può essere visto e cambiato (con privilegi) attraverso il file /proc/sys/kernel/rtsig-max. Un file correlato, /proc/sys/kernel/rtsig-nr, può essere usato per trovare quanti segnali real-time sono attualmente accodati. In Linux 2.6.8, queste interfacce /proc sono sostituite dal limite di risorsa RLIMIT_SIGPENDING che specifica un limite per utente per i segnali accodati. Vedere setrlimit(2) per ulteriori dettagli.
Una funzione di manipolazione dei segnali deve fare molta attenzione, poiché qualunque processo può essere interrotto in un punto arbitrario durante l'esecuzione del programma. POSIX ha il concetto di "funzione sicura". Se un segnale interrompe l'esecuzione di una funzione non sicura, e handler chiama una funzione non sicura, allora il comportamento del programma non è definito.
POSIX.1-2004 (già conosciuto come POSIX.1-2001 Technical Corrigendum 2) richiede all'implementazione di garantire che le seguenti funzioni possano essere chiamate in sicurezza in un gestore di segnali:
_Exit() _exit() abort() accept() access() aio_error() aio_return() aio_suspend() alarm() bind() cfgetispeed() cfgetospeed() cfsetispeed() cfsetospeed() chdir() chmod() chown() clock_gettime() close() connect() creat() dup() dup2() execle() execve() fchmod() fchown() fcntl() fdatasync() fork() fpathconf() fstat() fsync() ftruncate() getegid() geteuid() getgid() getgroups() getpeername() getpgrp() getpid() getppid() getsockname() getsockopt() getuid() kill() link() listen() lseek() lstat() mkdir() mkfifo() open() pathconf() pause() pipe() poll() posix_trace_event() pselect() raise() read() readlink() recv() recvfrom() recvmsg() rename() rmdir() select() sem_post() send() sendmsg() sendto() setgid() setpgid() setsid() setsockopt() setuid() shutdown() sigaction() sigaddset() sigdelset() sigemptyset() sigfillset() sigismember() signal() sigpause() sigpending() sigprocmask() sigqueue() sigset() sigsuspend() sleep() sockatmark() socket() socketpair() stat() symlink() sysconf() tcdrain() tcflow() tcflush() tcgetattr() tcgetpgrp() tcsendbreak() tcsetattr() tcsetpgrp() time() timer_getoverrun() timer_gettime() timer_settime() times() umask() uname() unlink() utime() wait() waitpid() write()
POSIX.1-2008 rimuove fpathconf(), pathconf(), e sysconf() dall'elenco precedente, e aggiunge le seguenti funzioni:
execl() execv() faccessat() fchmodat() fchownat() fexecve() fstatat() futimens() linkat() mkdirat() mkfifoat() mknod() mknodat() openat() readlinkat() renameat() symlinkat() unlinkat() utimensat() utimes()
Se viene chiamato un gestore di segnale mentre una chiamata di sistema o una funzione di libreria sono bloccate, può succedere:
Il verificarsi di uno di questi due comportamenti dipende dall'interfaccia e dall'uso o meno del flag SA_RESTART alla creazione del gestore di segnale (vedere sigaction(2)). I dettagli variano tra i sistemi UNIX: seguono quelli per Linux.
Se un gestore di segnale interrompe una chiamata bloccata verso una delle seguenti interfacce, la chiamata verrà automaticamente riavviata dopo il ritorno del gestore di segnale, se è stato usato il flag SA_RESTART, altrimenti la chiamata fallirà con l'errore EINTR: chiamate
Le seguenti interfacce non vengono mai riavviate dopo l'interruzione da parte di un gestore di segnale, senza curarsi dell'uso di SA_RESTART; falliscono sempre con l'errore EINTR quando vengono interrotte da un gestore di segnale:
La funzione sleep(3) non viene mai riavviata anche quando viene interrotta da un gestore, ma restituisce uno stato di successo: il numero di secondi rimanenti.
Su Linux, anche in assenza di gestori di segnale alcune interfacce di blocco possono fallire con l'errore EINTR dopo che il processo è stato fermato da un segnale di stop, e poi riavviato tramite SIGCONT. Questo comportamento non è sanzionato da POSIX.1, e non avviene su altri sistemi.
Le interfacce Linux che si comportano in questo modo sono:
POSIX.1, tranne dove indicato.
kill(1), getrlimit(2), kill(2), killpg(2), restart_syscall(2), rt_sigqueueinfo(2), setitimer(2), setrlimit(2), sgetmask(2), sigaction(2), sigaltstack(2), signal(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), sigwaitinfo(2), abort(3), bsd_signal(3), longjmp(3), raise(3), pthread_sigqueue(3), sigqueue(3), sigset(3), sigsetops(3), sigvec(3), sigwait(3), strsignal(3), sysv_signal(3), core(5), proc(5), pthreads(7), sigevent(7)
Questa pagina fa parte del rilascio 3.73 del progetto Linux man-pages. Una descrizione del progetto, le istruzioni per la segnalazione degli errori, e l'ultima versione di questa pagina si trova su http://www.kernel.org/doc/man-pages/.
La versione italiana fa parte del pacchetto man-pages-it v.
3.73, a cura di: ILDP "Italian Linux Documentation Project"
http://www.pluto.it/ildp
Per la traduzione in italiano si può fare riferimento a
http://www.pluto.it/ildp/collaborare/
Segnalare eventuali errori di traduzione a ildp@pluto.it
2014-06-13 | Linux |