Qu'est-ce qui provoque l'envoi de divers signaux?

28

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 -sparamètre to kill, mais quelles sont les circonstances naturelles dans lesquelles ces signaux sont envoyés? Par exemple, quand est- SIGINTil envoyé?

Existe-t-il également des restrictions sur les signaux pouvant être traités? Peut-on même SIGSEGVtraiter des signaux et renvoyer le contrôle à l'application?

Nathan Osman
la source
Une bonne réponse à cela va être épique, et essentiellement reproduire les informations dans l'article de Wikipédia sur la question, donc je vais simplement pointer là.
Shawn J. Goff,
@Shawn: L'article de Wikipédia contient une liste de signaux, mais aucune présentation claire de qui envoie quels signaux.
Gilles 'SO- arrête d'être méchant'

Réponses:

41

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:

  • Les pilotes de terminal envoient des signaux correspondant à divers événements:
    • Notifications de pression des touches: 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 la sttycommande.
    • SIGTTINet SIGTTOUsont 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é.
    • SIGHUPest 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).
  • Certains pièges de processeur peuvent générer un signal. Les détails dépendent de l'architecture et du système; voici des exemples typiques:
    • 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);
    • SIGFPEpour une instruction à virgule flottante avec de mauvais arguments (par exemple sqrt(-1)).
  • Un certain nombre de signaux indiquent au processus cible qu'un événement système s'est produit:
    • SIGALRMnotifie qu'un minuteur défini par le processus a expiré. Les minuteries peuvent être réglées avec alarm,setitimer et d' autres.
    • SIGCHLD informe un processus que l'un de ses enfants est décédé.
    • SIGPIPEest 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écutez foo | baret barquitte, fooest 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 le I_SETSIG ioctl. De nombreux systèmes autorisent les événements pollables sur n'importe quel descripteur de fichier, définis via l' O_ASYNC fcntlindicateur. Un signal associé est SIGURG, qui notifie les données urgentes sur un appareil (enregistré via le I_SETSIG ioctl) ou prise .
    • Sur certains systèmes, SIGPWRest 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) et STOP(arrêter l'exécution).

SIGSEGV( défaut de segmentation ) et son cousin SIGBUS( 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.

Gilles 'SO- arrête d'être méchant'
la source
Et SIGHUP, votre modem a raccroché. :-)
Keith
1
Une autre chose à noter: SIGFPE, un peu unintuitively, est également signalé sur entier de division par zéro, et parfois entier signé trop - plein.
éphémère
18

Pour répondre à votre deuxième question en premier: SIGSTOPet SIGKILLne peut pas être capté par l'application, mais tous les autres signaux le peuvent, même SIGSEGV. Cette propriété est utile pour le débogage - par exemple, avec la bonne prise en charge de bibliothèque, vous pouvez écouter SIGSEGVet 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 signalpartir 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

  • SIGINTarrive quand vous frappez CTRL+C.
  • SIGQUITest déclenché par CTRL+\, et vide le noyau.
  • SIGTSTPsuspend votre programme lorsque vous appuyez sur CTRL+Z. Contrairement à SIGSTOP, il est capturable, ce qui donne aux programmes viune 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.
  • SIGTTINet SIGTTOUsuspendez votre programme s'il essaie de lire ou d'écrire sur le terminal pendant qu'il s'exécute en arrière-plan. Pour que SIGTTOUcela 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.

  • SIGILLsignifie 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.
  • SIGFPEsignifie 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.
  • SIGBUSsignifie 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

  • SIGPIPEse produit si vous essayez d'écrire sur un tuyau après que le lecteur du tuyau a fermé son extrémité. Tu vois man 7 pipe.
  • SIGCHLDse produit lorsqu'un processus enfant que vous avez créé se ferme ou est suspendu (par SIGSTOPou similaire).

Utile pour l'auto-signalisation

  • SIGABRTest généralement causé par le programme appelant la abort()fonction et provoque un vidage de mémoire par défaut. Une sorte de "bouton panique".
  • SIGALRMest causée par l' alarm()appel système, qui amènera le noyau à fournir un SIGALRMau programme après un nombre spécifié de secondes. Voir man 2 alarmet man 2 sleep.
  • SIGUSR1et SIGUSR2sont 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 killcommande, fgou bgdans le cas de SIGCONT.

  • SIGKILLet SIGSTOPsont les signaux imblocables. Le premier termine toujours le processus immédiatement; le second suspend le processus.
  • SIGCONT reprend un processus suspendu.
  • SIGTERMest une version capturable de SIGKILL.
Jander
la source
Quel signal est envoyé lorsque la shutdowncommande est utilisée?
Nathan Osman le
Cela dépend des scripts d'arrêt. En règle générale, SIGTERMest envoyé en premier, suivi d'un délai, suivi de SIGKILL. 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.
Jander