Bonjour à tous,
voila si dans mon code il y a un segfault, alors mon programme attrape le signal SIGSEGV et lance ma fonction void gestionnaire(int num) grace à la fonction sigaction().
Mais au bout de combien de temps le noyau va tuer mon processus ? à la fin de ma fonction gestionnaire(int num) ?
Le SIGSEGV est émie par le noyau ou par le MMU ?
Merci d'avance pour vos réponses
# Reprenons les bases
Posté par Renault (site web personnel) . Évalué à 9.
Quand un processus reçoit un signal, le noyau va chercher à appeler le gestionnaire de signal associé à celui-ci. S'il n'existe pas, car le processus n'en a pas installé un, il va réaliser le comportement par défaut associé à ce signal. Or à quelques exceptions près, c'est terminer le logiciel voire avec un coredump.
Par contre, si un tel gestionnaire existe, le noyau va appeler ce gestionnaire. Et c'est tout. Ce sera au gestionnaire d'avoir un comportement correct vis à vis du signal reçu. Cela signifie que si tu n'arrêtes pas le programme via un exit() dans le gestionnaire, ce dernier continuera de vivre sa vie.
Cependant, certains signaux comme SIGSEGV ont un comportement indéfini si le programme n'est pas stoppé dans le gestionnaire de signal. C'est donc une mauvaise idée d'essayer de faire poursuivre le programme dans cette situation. En effet, le but d'un gestionnaire de signal est surtout d'essayer de sauver les meubles avant la fin du programme : enregistrer des données sur le disque, ajouter des logs plus précis, etc. Rarement pour essayer de poursuivre l'exécution de celui-ci au delà (car cela ne fait pas forcément sens, et parce que c'est souvent compliqué à réaliser).
La MMU (comme tout composant matériel en fait) n'a aucune notion de ce qu'est POSIX, d'un signal UNIX ou quoique ce soit relatif à tout cela. C'est forcément le noyau qui envoie ce genre de signaux, car c'est son rôle de faire interface entre un logiciel et le matériel.
En fait la MMU va générer une interruption suite à l'erreur mémoire du programmer. Le noyau va recevoir cette interruption (via le gestionnaire d'interruptions) et enverra ensuite le signal au processus fautif.
[^] # Re: Reprenons les bases
Posté par viviNeutron . Évalué à 2.
Merci beaucoup Renault pour ta réponse tres complete qui répond parfaitement à ma question.
Une derniere chose. Lors d'un Segfault, est ce que dans mon gestionnaire je peux utiliser la fonction malloc() ou ce n'est pas possible car il y a eu un segfault ?
Merci d'avance pour ta réponse
[^] # Re: Reprenons les bases
Posté par Renault (site web personnel) . Évalué à 8.
Non, tu ne dois pas appeler malloc dans ce contexte.
La liste des fonctions que tu peux appeler dans ce cas car considérées comme sûres sont listées dans le manuel : http://man7.org/linux/man-pages/man7/signal-safety.7.html
[^] # Re: Reprenons les bases
Posté par viviNeutron . Évalué à 1.
mais que se passe t'il si je fais tout de meme un malloc ? et pourquoi ce n'est pas safe?
# sequenceur
Posté par David Marec . Évalué à 4.
Attention, en matière de signaux, on ne peut pas tout faire, consultez la page de
man 7 signal
pour connaitre les fonctions que vous pouvez utiliser dans un handler.D'une part, ce n'est pas une question de temps et surtout, il ne va pas tuer votre processus.
Le séquenceur (donc le noyau pour répondre à la deuxième question), va suspendre le processus pour donner la main au code du gestionnaire de signal, puis, reprendre le processus là où vous l'avez laissé.
Dans le cas d'un
SIGSEGV
vous pouvez entrer dans une boucle infinie, terminez par unabort
, quoiqu'il arrive.Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.