Je suis parfois un peu confus par tous les signaux qu'un processus peut recevoir. Si je comprends bien, un processus a un gestionnaire par défaut ( disposition du signal ) pour chacun de ces signaux, mais il peut fournir son propre gestionnaire en appelant sigaction()
.
Voici donc ma question: qu'est-ce qui provoque l'envoi de chacun des signaux? Je me rends compte que vous pouvez envoyer manuellement des signaux aux processus en cours d'exécution via le -s
paramètre to kill
, mais quelles sont les circonstances naturelles dans lesquelles ces signaux sont envoyés? Par exemple, quand est- SIGINT
il envoyé?
Existe-t-il également des restrictions sur les signaux pouvant être traités? Peut-on même SIGSEGV
traiter des signaux et renvoyer le contrôle à l'application?
Réponses:
En plus des processus appelant
kill(2)
, certains signaux sont envoyés par le noyau (ou parfois par le processus lui-même) dans diverses circonstances:SIGINT
(veuillez retourner à la boucle principale) sur Ctrl+ C,SIGQUIT
(veuillez quitter immédiatement) sur Ctrl+ \,SIGTSTP
(veuillez suspendre) sur Ctrl+ Z. Les clés peuvent être modifiées avec lastty
commande.SIGTTIN
etSIGTTOU
sont envoyés lorsqu'un processus d'arrière-plan tente de lire ou d'écrire sur son terminal de contrôle.SIGWINCH
est envoyé pour signaler que la taille de la fenêtre du terminal a changé.SIGHUP
est envoyé au signal que le terminal a disparu (historiquement parce que votre modem avait h ung jusqu'à , généralement de nos jours parce que vous avez fermé la fenêtre d'émulation de terminal).SIGBUS
pour une mémoire d'accès non alignée;SIGSEGV
pour un accès à une page non mappée;SIGILL
pour une instruction illégale (mauvais opcode);SIGFPE
pour une instruction à virgule flottante avec de mauvais arguments (par exemplesqrt(-1)
).SIGALRM
notifie qu'un minuteur défini par le processus a expiré. Les minuteries peuvent être réglées avecalarm
,setitimer
et d' autres.SIGCHLD
informe un processus que l'un de ses enfants est décédé.SIGPIPE
est généré lorsqu'un processus essaie d'écrire dans un canal lorsque la fin de lecture est fermée (l'idée est que si vous exécutezfoo | bar
etbar
quitte,foo
est tué par unSIGPIPE
).SIGPOLL
(également appeléSIGIO
) signale au processus qu'un événement pollable s'est produit. POSIX spécifie les événements interrogables enregistrés via leI_SETSIG
ioctl
. De nombreux systèmes autorisent les événements pollables sur n'importe quel descripteur de fichier, définis via l'O_ASYNC
fcntl
indicateur. Un signal associé estSIGURG
, qui notifie les données urgentes sur un appareil (enregistré via leI_SETSIG
ioctl
) ou prise .SIGPWR
est envoyé à tous les processus lorsque l' onduleur signale qu'une panne de courant est imminente.Ces listes ne sont pas exhaustives. Les signaux standard sont définis dans
signal.h
.La plupart des signaux peuvent être capturés et traités (ou ignorés) par l'application. Les deux seuls signaux portables qui ne peuvent pas être capturés sont
SIGKILL
(simplement mourir) etSTOP
(arrêter l'exécution).SIGSEGV
( défaut de segmentation ) et son cousinSIGBUS
( erreur de bus ) peuvent être capturés, mais c'est une mauvaise idée à moins que vous ne sachiez vraiment ce que vous faites. Une application courante pour les attraper est l'impression d'une trace de pile ou d'autres informations de débogage. Une application plus avancée consiste à implémenter une sorte de gestion de la mémoire en cours ou à intercepter les mauvaises instructions dans les moteurs de machine virtuelle.Enfin, permettez-moi de mentionner quelque chose qui n'est pas un signal. Lorsque vous appuyez sur Ctrl+ Dau début d'une ligne dans un programme qui lit les entrées du terminal, cela indique au programme que la fin du fichier d'entrée est atteinte. Ce n'est pas un signal: il est transmis via l'API d'entrée / sortie. Comme Ctrl+ Cet amis, la clé peut être configurée avec
stty
.la source
SIGFPE
, un peu unintuitively, est également signalé sur entier de division par zéro, et parfois entier signé trop - plein.Pour répondre à votre deuxième question en premier:
SIGSTOP
etSIGKILL
ne peut pas être capté par l'application, mais tous les autres signaux le peuvent, mêmeSIGSEGV
. Cette propriété est utile pour le débogage - par exemple, avec la bonne prise en charge de bibliothèque, vous pouvez écouterSIGSEGV
et générer une trace de pile pour montrer exactement où ce défaut de segmentation s'est produit.Le mot officiel (pour Linux, de toute façon) sur ce que fait chaque signal est disponible en tapant à
man 7 signal
partir d'une ligne de commande Linux. http://linux.die.net/man/7/signal contient les mêmes informations, mais les tableaux sont plus difficiles à lire.Cependant, sans une certaine expérience des signaux, il est difficile de savoir à partir des courtes descriptions de ce qu'ils font dans la pratique, alors voici mon interprétation:
Déclenché depuis le clavier
SIGINT
arrive quand vous frappezCTRL+C
.SIGQUIT
est déclenché parCTRL+\
, et vide le noyau.SIGTSTP
suspend votre programme lorsque vous appuyez surCTRL+Z
. Contrairement àSIGSTOP
, il est capturable, ce qui donne aux programmesvi
une chance de réinitialiser le terminal à un état sûr avant de se suspendre.Interactions terminales
SIGHUP
("raccrochage") est ce qui se produit lorsque vous fermez votre xterm (ou déconnectez le terminal d'une autre manière) pendant l'exécution de votre programme.SIGTTIN
etSIGTTOU
suspendez votre programme s'il essaie de lire ou d'écrire sur le terminal pendant qu'il s'exécute en arrière-plan. Pour queSIGTTOU
cela se produise, je pense que le programme doit écrire/dev/tty
, pas seulement la sortie standard par défaut.Déclenché par une exception CPU
Cela signifie que votre programme a essayé de faire quelque chose de mal.
SIGILL
signifie une instruction de processeur illégale ou inconnue. Cela peut se produire si vous essayez d'accéder directement aux ports d'E / S du processeur, par exemple.SIGFPE
signifie qu'il y avait une erreur mathématique matérielle; le programme a probablement tenté de diviser par zéro.SIGSEGV
signifie que votre programme a tenté d'accéder à une région de mémoire non mappée.SIGBUS
signifie que le programme a accédé incorrectement à la mémoire d'une autre manière; Je n'entrerai pas dans les détails de ce résumé.Interaction de processus
SIGPIPE
se produit si vous essayez d'écrire sur un tuyau après que le lecteur du tuyau a fermé son extrémité. Tu voisman 7 pipe
.SIGCHLD
se produit lorsqu'un processus enfant que vous avez créé se ferme ou est suspendu (parSIGSTOP
ou similaire).Utile pour l'auto-signalisation
SIGABRT
est généralement causé par le programme appelant laabort()
fonction et provoque un vidage de mémoire par défaut. Une sorte de "bouton panique".SIGALRM
est causée par l'alarm()
appel système, qui amènera le noyau à fournir unSIGALRM
au programme après un nombre spécifié de secondes. Voirman 2 alarm
etman 2 sleep
.SIGUSR1
etSIGUSR2
sont utilisés comme le programme le souhaite. Ils pourraient être utiles pour signaler entre les processus.Envoyé par l'administrateur
Ces signaux sont généralement envoyés à partir de l'invite de commande, via la
kill
commande,fg
oubg
dans le cas deSIGCONT
.SIGKILL
etSIGSTOP
sont les signaux imblocables. Le premier termine toujours le processus immédiatement; le second suspend le processus.SIGCONT
reprend un processus suspendu.SIGTERM
est une version capturable deSIGKILL
.la source
shutdown
commande est utilisée?SIGTERM
est envoyé en premier, suivi d'un délai, suivi deSIGKILL
. En principe, pour un arrêt dur et immédiat, le noyau n'a pas du tout besoin d'envoyer un signal; il pourrait simplement arrêter d'exécuter le processus.