284 votes

Quand un processus obtient-il SIGABRT (signal 6) ?

Quels sont les scénarios dans lesquels un processus reçoit un SIGABRT en C++ ? Ce signal provient-il toujours de l'intérieur du processus ou peut-il être envoyé d'un processus à un autre ?

Existe-t-il un moyen d'identifier le processus qui envoie ce signal ?

7 votes

Il y a plusieurs façons de procéder. La plus simple, si vous avez écrit le programme, est d'enregistrer un gestionnaire de signal pour SIGABRT qui imprime cette information et vide ses flux avant de revenir. La deuxième façon la plus simple est d'exécuter le programme dans strace. Le troisième moyen le plus simple est de s'assurer que le programme génère un fichier core lorsqu'il se plante, et de le découvrir via le core dump.

274voto

Nordic Mainframe Points 13717

abort() envoie au processus appelant le SIGABRT signal, c'est ainsi que abort() fonctionne fondamentalement.

abort() est généralement appelé par des fonctions de bibliothèque qui détectent une erreur interne ou une contrainte sérieusement brisée. Par exemple malloc() appellera abort() si ses structures internes sont endommagées par un débordement de tas.

45 votes

Pour moi, dans la plupart des cas, SIGABRT a été envoyé par libc J'essaie d'appeler free() sur un pointeur non initialisé/corrompu

1 votes

Si j'ai, quelque part dans le code, enterré un appel de fonction virtuelle pure à l'intérieur du constructeur, est-ce que cela peut aussi se terminer par le signal SIGABRT ? Je pose la question car je vois une erreur indiquant que j'ai un appel virtuel pur, et la ligne suivante me donne un message SIGABRT et l'application se plante ou est fermée par le système d'exploitation. Merci.

5 votes

Sous MacOS, nous avons obtenu SIGABRT pour avoir ouvert environ 1000 handles de fichiers sans les fermer. Au lieu d'utiliser des simulacres, nos tests ont abstrait le fichier avec un type de lecteur plus générique, qui n'a pas d'attribut Close() la méthode, elle a donc été oubliée. Mais la couverture était excellente :

71voto

IanH Points 1633

SIGABRT est couramment utilisé par libc et d'autres bibliothèques pour interrompre le programme en cas d'erreurs critiques. Par exemple, la glibc envoie un SIGABRT en cas de détection d'un double-free ou d'autres corruptions du tas.

En outre, la plupart des assert Les implémentations font appel à SIGABRT en cas d'échec de l'affirmation.

En outre, SIGABRT peut être envoyé depuis n'importe quel autre processus comme n'importe quel autre signal. Bien sûr, le processus d'envoi doit être exécuté par le même utilisateur ou Root.

53voto

sarnold Points 62720

Vous pouvez envoyer n'importe quel signal à n'importe quel processus en utilisant la fonction kill(2) interface :

kill -SIGABRT 30823

30823 était un dash le processus que j'ai commencé, afin que je puisse facilement trouver le processus que je voulais tuer.

$ /bin/dash
$ Aborted

El Aborted La sortie est apparemment comment dash signale un SIGABRT.

Il peut être envoyé directement à n'importe quel processus en utilisant kill(2) ou un processus peut s'envoyer le signal à lui-même par l'intermédiaire de assert(3) , abort(3) o raise(3) .

22voto

Mig Points 435

Cela se produit généralement lorsqu'il y a un problème d'allocation de mémoire.

Cela m'est arrivé alors que mon programme essayait d'allouer un tableau de taille négative.

18voto

Sudip Bhattarai Points 643

Il y a une autre cause simple dans le cas du c++.

std::thread::~thread{
    if((joinable ())
        std::terminate ();
}

c'est-à-dire que la portée du fil s'est terminée mais que vous avez oublié d'appeler soit

thread::join();

o

thread::detach();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X