Scroll to navigation

SIGNAL(7) Manuel du programmeur Linux SIGNAL(7)

NOM

signal – Panorama des signaux

DESCRIPTION

Linux prend en charge à la fois les signaux POSIX classiques (« ci-après signaux standard ») et les signaux POSIX temps réel.

Action des signaux

Chaque signal a une action en vigueur qui détermine le comportement du processus lorsqu'il reçoit ce signal.

Les éléments de la colonne « Action » des tables ci-dessous indiquent l'action par défaut pour chaque signal, avec la signification suivante :

Par défaut, terminer le processus.
Par défaut, ignorer le signal.
Par défaut, terminer le processus et créer un fichier d'image mémoire (consultez core(5)).
Par défaut, arrêter le processus.
Par défaut, continuer le processus s'il est actuellement arrêté.

Un processus peut changer l’action d'un signal avec sigaction(2) ou signal(2) (la deuxième option est moins portable quand on définit un gestionnaire de signal ; consultez signal(2) pour plus de détails). Avec ces appels système, un processus peut choisir de se comporter de l'une des façons suivantes lorsqu'il reçoit ce signal : effectuer l'action par défaut, ignorer le signal ou capturer le signal avec un gestionnaire de signal, c'est-à-dire une fonction définie par le programme qui est invoquée automatiquement lorsque le signal est distribué. (Par défaut, le gestionnaire de signal est appelé sur la pile normale des processus. Il est possible de s'arranger pour que le gestionnaire de signal utilise une autre pile ; consultez sigaltstack(2) pour une discussion sur comment faire cela et quand ça peut être utile.)

L’action d'un signal est un attribut du processus : dans une application multithreadée, l’action d'un signal particulier est la même pour tous les threads.

Un enfant créé par fork(2) hérite d'une copie des actions des signaux de son parent. Lors d'un execve(2), les actions des signaux pris en charge sont remises aux valeurs par défaut ; les actions des signaux ignorés ne sont pas modifiées.

Envoyer un signal

Les appels système et les fonctions de bibliothèque qui suivent permettent à l'appelant d'envoyer un signal :

raise(3)
Envoyer un signal au thread appelant.
kill(2)
Envoyer un signal au processus indiqué, à tous les membres du groupe de processus indiqué ou à tous les processus du système.
killpg(3)
Envoyer un signal à tous les membres du groupe de processus indiqué.
pthread_kill(3)
Envoyer un signal au thread POSIX indiqué dans le même processus que l'appelant.
tgkill(2)
Envoyer un signal au thread indiqué à l'intérieur d'un processus donné (c'est l'appel système utilisé pour implémenter pthread_kill(3)).
sigqueue(3)
Envoyer un signal temps réel, avec ses données jointes, au processus indiqué.

Attente de la capture d'un signal

Les appels système suivants suspendent l'exécution du processus ou du thread appelant jusqu'à ce qu'un signal soit capturé (ou qu'un signal non pris en charge termine le processus) :

pause(2)
Suspendre l'exécution jusqu'à ce que n'importe quel signal soit reçu.
sigsuspend(2)
Changer temporairement le masque de signaux (voir ci-dessous) et suspendre l'exécution jusqu'à ce qu'un des signaux non masqué soit reçu.

Accepter un signal de façon synchrone

Au lieu d’intercepter un signal de façon asynchrone avec un gestionnaire de signal, il est possible de l’accepter de façon synchrone, c'est-à-dire de bloquer l'exécution jusqu'à ce que le signal soit distribué. À ce moment, le noyau renvoie des informations concernant le signal à l'appelant. Il y a deux façons générales pour faire cela :

  • sigwaitinfo(2), sigtimedwait(2) et sigwait(3) suspendent l'exécution jusqu'à ce qu'un des signaux dans l'ensemble indiqué soit distribué. Chacun de ces appels renvoie des informations concernant le signal distribué.
  • signalfd(2) renvoie un descripteur de fichier qui peut être utilisé pour lire les informations concernant les signaux qui sont distribués à l'appelant. Chaque read(2) dans ce descripteur de fichier est bloquant jusqu'à ce que un des signaux de l'ensemble indiqué dans l’appel signalfd(2) soit distribué à l'appelant. Le tampon renvoyé par read(2) contient une structure qui décrit le signal.

Masque de signaux et signaux en attente

Un signal peut être bloqué, ce qui signifie qu'il ne sera pas envoyé avant d'être débloqué. Entre le moment de sa création et celui de son envoi, le signal est dit en attente.

Chaque thread d'un processus a un masque de signaux indépendant qui indique l'ensemble des signaux bloqués par le thread. Un thread peut modifier son masque de signaux avec pthread_sigmask(3). Dans une application traditionnelle à un seul thread, sigprocmask(2) peut être utilisée pour modifier le masque de signaux.

Un processus enfant créé avec fork(2) hérite d'une copie du masque de signaux de son parent. Le masque de signaux est conservé au travers d'un execve(2).

Un signal peut être généré (et par conséquent en attente) pour le processus dans son entier (par exemple, lorsqu’il est envoyé en utilisant kill(2)) ou pour un thread particulier (par exemple, certains signaux tels que SIGSEGV et SIGFPE, générés à la suite de l’exécution d’une instruction spécifique au langage machine, sont destinés aux threads, comme le sont les signaux ciblant un thread spécifique à l’aide de pthread_kill(3)). Un signal orienté processus peut être envoyé à n’importe quel thread qui n’a pas le signal présentement bloqué. Si plus d’un thread a le signal non bloqué, alors le noyau choisi un thread arbitraire auquel envoyer le signal.

Un thread peut obtenir l'ensemble des signaux actuellement en attente en utilisant sigpending(2). Cet ensemble est l'union de l’ensemble des signaux en attente orientés processus et l’ensemble des signaux en attente pour le thread appelant.

Un enfant créé avec fork(2) débute avec un ensemble de signaux en attente vide. L'ensemble de signaux en attente est conservé au travers d'un execve(2).

Signaux standard

Linux gère les signaux standard listés ci-dessous. Plusieurs numéros de signal dépendent de l’architecture, comme indiqué dans la colonne « Valeur » (où trois valeurs sont données, la première valable habituellement pour Alpha et SPARC, celle du milieu pour x86, ARM et la plupart des architectures, et la dernière pour MIPS — les valeurs pour PA-RISC ne sont pas affichées ici, consultez les sources du noyau Linux pour la numérotation des signaux pour cette architecture). Un tiret (-) indique que le signal est absent pour l’architecture correspondante.

D'abord les signaux décrits dans la norme originale POSIX.1-1990.

Signal Valeur Action Commentaire
SIGHUP  1 Term Déconnexion détectée sur le terminal de
contrôle ou mort du processus de contrôle
SIGINT  2 Term Interruption depuis le clavier
SIGQUIT  3 Core Quitter depuis le clavier
SIGILL  4 Core Instruction illégale
SIGABRT  6 Core Signal d'arrêt d’abort(3)
SIGFPE  8 Core Exception de virgule flottante
SIGKILL  9 Term Signal d’arrêt
SIGSEGV 11 Core Référence mémoire non valable
SIGPIPE 13 Term Tube brisé : écriture dans un tube sans
lecteur – voir pipe(7)
SIGALRM 14 Term Signal de temporisation d’alarm(2)
SIGTERM 15 Term Signal de fin
SIGUSR1 30,10,16 Term Signal utilisateur 1
SIGUSR2 31,12,17 Term Signal utilisateur 2
SIGCHLD 20,17,18 Ign Enfant arrêté ou terminé
SIGCONT 19,18,25 Cont Continuer si arrêté
SIGSTOP 17,19,23 Stop Processus d’arrêt
SIGTSTP 18,20,24 Stop Stop saisi sur le terminal
SIGTTIN 21,21,26 Stop Entrée du terminal pour processus en arrière-plan
SIGTTOU 22,22,27 Stop Sortie du terminal pour processus en arrière-plan

Les signaux SIGKILL et SIGSTOP ne peuvent être ni capturés, ni bloqués, ni ignorés.

Ensuite les signaux qui ne sont pas dans la norme POSIX.1-1990 mais qui sont décrits dans SUSv2 et POSIX.1-2001.

Signal Valeur Action Commentaire
SIGBUS 10,7,10 Core Erreur de bus (mauvais accès mémoire)
SIGPOLL Term Événement scrutable (System V).
Synonyme pour SIGIO
SIGPROF 27,27,29 Term Fin d'une temporisation de profilage
SIGSYS 12,31,12 Core Mauvais appel système (SVr4)
– voir aussi seccomp(2)
SIGTRAP 5 Core Interception pour trace ou pour point d’arrêt
SIGURG 16,23,21 Ign Condition urgente sur un socket (4.2BSD)
SIGVTALRM 26,26,28 Term Horloge virtuelle d’alarme (4.2BSD)
SIGXCPU 24,24,30 Core Limite de temps CPU dépassée (4.2BSD)
Consultez setrlimit(2)
SIGXFSZ 25,25,31 Core Taille de fichier excessive (4.2BSD)
Consultez setrlimit(2)

Jusqu'à Linux 2.2 inclus, l'action par défaut pour SIGSYS, SIGXCPU, SIGXFSZ et (sur les architectures autres que SPARC ou MIPS) SIGBUS était de terminer simplement le processus, sans fichier image mémoire. (Sur certains UNIX, l'action par défaut pour SIGXCPU et SIGXFSZ est de finir le processus sans fichier image mémoire.) Linux 2.4 se conforme à POSIX.1-2001 pour ces signaux et termine le processus avec un fichier image mémoire.

Enfin divers autres signaux.

Signal Valeur Action Commentaire
SIGIOT 6 Core Interception IOT – synonyme pour SIGABRT
SIGEMT 7,-,7 Term Interception (trap) d’émulateur
SIGSTKFLT -,16,- Term Erreur de pile sur coprocesseur (inutilisé)
SIGIO 23,29,22 Term E/S maintenant possible (4.2BSD)
SIGCLD -,-,18 Ign Synonyme pour SIGCHLD
SIGPWR 29,30,19 Term Panne d'alimentation (System V)
SIGINFO 29,-,- Synonyme pour SIGPWR
SIGLOST -,-,- Term Perte de verrou de fichier (inutilisé)
SIGWINCH 28,28,20 Ign Fenêtre redimensionnée (4.3BSD, Sun)
SIGUNUSED -,31,- Core Synonyme pour SIGSYS

(Le signal 29 est SIGINFO/SIGPWR sur Alpha mais SIGLOST sur SPARC).

SIGEMT n'est pas spécifié par POSIX.1-2001 mais apparaît néanmoins sur la plupart des UNIX, avec une action par défaut typique correspondant à une fin du processus avec fichier image mémoire.

SIGPWR (non spécifié dans POSIX.1-2001) est typiquement ignoré sur les autres UNIX où il apparaît.

SIGIO (non spécifié par POSIX.1-2001) est ignoré par défaut sur plusieurs autres systèmes UNIX.

Si défini, SIGUNUSED est synonyme de SIGSYS sur la plupart des architectures. Depuis la glibc 2.26, SIGUNUSED n’est plus défini sur aucune architecture.

Signaux temps réel

Depuis la version 2.2, Linux prend en charge les signaux temps réel tels qu'ils ont été définis à l'origine dans les extensions temps réel POSIX.1b (et inclus à présent dans POSIX.1-2001). L'éventail des signaux temps réel gérés est défini par les macros SIGRTMIN et SIGRTMAX. POSIX.1-2001 exige qu'une implémentation gère au moins _POSIX_RTSIG_MAX (8) signaux temps réel.

Le noyau Linux gère une gamme de 33 signaux temps réel différents, numérotés de 32 à 64. Cependant, l'implémentation des threads POSIX de la glibc utilise en interne deux (pour l'implémentation NPTL) ou trois (pour l'implémentation LinuxThreads) signaux temps réel (consultez pthreads(7)) et ajuste la valeur de SIGRTMIN en conséquence (à 34 ou 35). Comme la gamme de signaux temps réel varie en fonction de l'implémentation des threads par la glibc (et cette implémentation peut changer à l'exécution en fonction du noyau et de la glibc) et que la gamme de signaux temps réel varie bien sûr également suivant les systèmes UNIX, les programmes ne devraient jamais faire référence à des signaux temps réel en utilisant des numéros codés en dur, mais devraient toujours à la place utiliser des signaux temps réel avec la notation SIGRTMIN+n avec des vérifications adéquates (lors de l'exécution) que SIGRTMIN+n ne dépasse pas SIGRTMAX.

Contrairement aux signaux standard, les signaux temps réel n'ont pas de signification prédéfinie : l'ensemble complet de ces signaux peut être utilisé à des fins spécifiques à l'application.

L'action par défaut pour un signal temps réel non géré est de terminer le processus récepteur.

Les signaux temps réel se distinguent de la façon suivante :

1.
Plusieurs instances d'un signal temps réel peuvent être mises en file d’attente. Au contraire, si plusieurs instances d'un signal standard arrivent alors qu'il est présentement bloqué, une seule instance sera mise en file d’attente.
2.
Si le signal est envoyé en utilisant sigqueue(3), il peut être accompagné d'une valeur (un entier ou un pointeur). Si le processus récepteur positionne un gestionnaire pour ce signal en utilisant l'attribut SA_SIGINFO pour l'appel sigaction(2), alors il peut accéder à la valeur transmise dans le champ si_value de la structure siginfo_t passée en second argument au gestionnaire. De plus, les champs si_pid et si_uid de cette structure fournissent le PID et l'UID réel du processus émetteur du signal.
3.
Les signaux temps réel sont délivrés dans un ordre précis. Les divers signaux temps réel du même type sont délivrés dans l'ordre où ils ont été émis. Si différents signaux temps réel sont envoyés au processus, ils sont délivrés en commençant par le signal de numéro le moins élevé (c’est-à-dire le signal de plus fort numéro est celui de priorité la plus faible). Par contre, si plusieurs signaux standard sont en attente pour un processus, l'ordre dans lequel ils sont délivrés n'est pas défini.

Si des signaux standard et des signaux temps réel sont simultanément en attente pour un processus, POSIX ne précise pas l'ordre de délivrance. Linux, comme beaucoup d'autres implémentations, donne priorité aux signaux standard dans ce cas.

D'après POSIX, une implémentation doit permettre la mise en attente d'au moins _POSIX_SIGQUEUE_MAX (32) signaux temps réel pour un processus. Néanmoins, Linux fonctionne différemment. Jusqu'au noyau 2.6.7 inclus, Linux impose une limite pour l'ensemble des signaux temps réel en attente sur le système pour tous les processus. Cette limite peut être consultée et modifiée (avec les privilèges adéquats) grâce au fichier /proc/sys/kernel/rtsig-max. Un fichier associé, /proc/sys/kernel/rtsig-nr, indique combien de signaux temps réel sont actuellement en attente. Dans Linux 2.6.8, ces interfaces /proc ont été remplacées par la limite de ressources RLIMIT_SIGPENDING qui spécifie une limite par utilisateur pour les signaux en attente ; consultez setrlimit(2) pour plus de détails.

L’ajout de signaux temps réel nécessite l’agrandissement de la structure de l’ensemble des signaux (sigset_t) de 32 à 64 bits. Par conséquent, divers appels système ont été supplantés par de nouveaux appels système qui gèrent des ensembles de signaux plus grands. Les anciens et nouveaux appels système sont les suivants :

Linux 2.0 et antérieurs Linux 2.2 et postérieurs
sigaction(2) rt_sigaction(2)
sigpending(2) rt_sigpending(2)
sigprocmask(2) rt_sigprocmask(2)
sigreturn(2) rt_sigreturn(2)
sigsuspend(2) rt_sigsuspend(2)
sigtimedwait(2) rt_sigtimedwait(2)

Interruption d’appel et de fonction par un gestionnaire de signal

Si un gestionnaire de signal est invoqué pendant qu'un appel système ou une fonction de bibliothèque est bloqué, alors :

  • soit l'appel est automatiquement redémarré après le renvoi du gestionnaire de signal ;
  • soit l'appel échoue avec l'erreur EINTR.

Lequel de ces deux comportements se produira dépend de l'interface et de si le gestionnaire de signal a été mis en place avec l'attribut SA_RESTART (consultez sigaction(2)). Les détails varient selon les systèmes UNIX ; voici ceux pour Linux.

Si un appel en attente à l'une des interfaces suivantes est interrompu par un gestionnaire de signal, l'appel sera automatiquement redémarré après le renvoi du gestionnaire de signal si l'attribut SA_RESTART a été indiqué ; autrement, l'appel échouera avec l'erreur EINTR :

  • Appels read(2), readv(2), write(2), writev(2) et ioctl(2) sur des périphériques « lents ». Un périphérique « lent » est un périphérique où un appel d'E/S peut bloquer pendant un temps indéfini, par exemple un terminal, un tube ou un socket. Si un appel d'E/S sur un périphérique lent a déjà transféré des données au moment où il est interrompu par un gestionnaire de signal, l'appel renverra une indication de succès (normalement, le nombre d'octets transférés). Remarquez que selon cette définition, un disque (local) n'est pas un périphérique lent. Les opérations d’E/S sur les périphériques disque ne sont pas interrompues par des signaux.
  • open (2), s'il peut bloquer (par exemple, lors de l'ouverture d'une FIFO ; consultez fifo(7)).
  • wait(2), wait3(2), wait4(2), waitid(2), et waitpid(2).
  • Interfaces de socket : accept(2), connect(2), recv(2), recvfrom(2), recvmmsg(2), recvmsg(2), send(2), sendto(2) et sendmsg(2), à moins qu'une temporisation n'ait été placée sur le socket (voir ci-dessous).
  • Interfaces de blocage de fichier : flock(2) et les opérations F_SETLKW et F_OFD_SETLKW de fcntl(2)
  • Interfaces de files de messages POSIX : mq_receive(3), mq_timedreceive(3), mq_send(3) et mq_timedsend(3).
  • Opération FUTEX_WAIT de futex(2) (depuis Linux 2.6.22 ; auparavant, elle échouait toujours avec l'erreur EINTR).
  • getrandom(2).
  • pthread_mutex_lock(3), pthread_cond_wait(3) et autres API apparentées.
  • FUTEX_WAIT_BITSET de futex(2.
  • Interfaces de sémaphores POSIX : sem_wait(3) et sem_timedwait(3) (depuis Linux 2.6.22 ; auparavant, elles échouaient toujours avec l'erreur EINTR).
  • read(2) d’un descripteur de fichier d’inotify(7) (depuis Linux 3.8 ; auparavant, elle échouait toujours avec l'erreur EINTR).

Les interfaces suivantes ne sont jamais relancées après avoir été interrompues par un gestionnaire de signal, quelle que soit l'utilisation de SA_RESTART ; elles échouent toujours avec l'erreur EINTR lorsqu'elles sont interrompues par un gestionnaire de signal :

La fonction sleep(3) n'est également jamais relancée si elle est interrompue par un gestionnaire, mais elle renvoie une indication de succès : le nombre de secondes restantes pour le sommeil.

Interruption d’appel et de fonction par des signaux d'arrêt

Sous Linux, même en l'absence de gestionnaire de signal, certaines interfaces en mode bloquant peuvent échouer avec l'erreur EINTR après que le processus a été arrêté par l'un des signaux d'arrêt et relancé avec le signal SIGCONT. Ce comportement n'est pas ratifié par POSIX.1 et n'apparaît pas sur d'autres systèmes.

Les interfaces Linux qui affichent ce comportement sont :

CONFORMITÉ

POSIX.1, sauf indication contraire.

NOTES

Pour une discussion sur les fonctions sûres de signal asynchrone, consultez signal-safety(7).

VOIR AUSSI

kill(1), getrlimit(2), kill(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), sigreturn(2), sigsuspend(2), sigwaitinfo(2), abort(3), bsd_signal(3), killpg(3), longjmp(3), pthread_sigqueue(3), raise(3), sigqueue(3), sigset(3), sigsetops(3), sigvec(3), sigwait(3), strsignal(3), sysv_signal(3), core(5), proc(5), nptl(7), pthreads(7), sigevent(7)

COLOPHON

Cette page fait partie de la publication 4.16 du projet man-pages Linux. Une description du projet et des instructions pour signaler des anomalies et la dernière version de cette page peuvent être trouvées à l'adresse https://www.kernel.org/doc/man-pages/.

TRADUCTION

La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Jean-Paul Guillonneau <guillonneau.jeanpaul@free.fr>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.

15 septembre 2017 Linux