12
votes

Ne peut pas reproduire segfault dans gdb

Je reçois des segfault quand je gère mon projet. Chaque fois que je gère le programme dans GDB, les Segfault disparaissent. Ce comportement n'est pas aléatoire: chaque fois que je l'exécute dans ma coquille, segfaults, chaque fois que je l'exécute dans GDB, les Segfault disparaissent. (Je me suis recompilé avec -g).

Donc avant de commencer à ajouter des impressions frantiquement partout dans mon code, j'aimerais connaître quelques choses:

  • Ce comportement est-il commun?
  • Quelle est la meilleure façon d'aborder la question?

    Je ne sais pas si les tests peuvent être scripts car mon application est interactive et se bloque sur une entrée d'utilisateur particulière.

    Je ne colle pas mon code ici parce que ce serait beaucoup trop longtemps. Mais si quelqu'un est intéressé à aider, ici c'est: https://github.com/rahmu/agros

c gdb

5 commentaires

en.wikipedia.org/wiki/unusual_software_bug#heisenbug


Essayez d'exécuter votre application dans Valgrind si cela est disponible sur votre plate-forme.


Votre programme est-il exécuté sans segfault lorsqu'il est compilé avec -g mais qui ne fonctionne pas dans gdb?


Bienvenue dans le monde merveilleux du Heisenbug. Avez-vous Valgrind ? Si oui, utilisez-le. Compilez-vous avec au moins ' GCC -G -WALL -WERROR '? Sinon, obtenez votre code à un point où vous pouvez. Envisagez d'ajouter ' -wextra ' à cette ligne de commande. Avez-vous eu un centimètre? Sinon, les réactivez-les ( ulimit -c illimité illimité ) et au moins obtenir gdb de vous dire où se produit le crash.


Essayez de compiler avec -wextra -peantique ainsi que -wall / -wextra , cela pourrait choisir quelque chose. A défaut de vous préparer à obtenir un vidage de base (utiliser ulimit -c Si vous ne les obtenez pas par défaut - sur Ubuntu de toute façon) et chargez-le dans GDB avec gdb myProgram mycore < / code>.


4 Réponses :


0
votes

Est-ce que cela fait un vidage de base? Est donc de charger le vidage du noyau dans le débogueur. Sinon, changez le code pour l'obtenir pour faire un vidage de base.


1 commentaires

Sinon, vous pouvez installer un gestionnaire de Segfault et une impression de retour d'impression (et espérons que le bogue n'a pas gâché la pile).



0
votes

Je suppose que c'est un problème de concurrence causant une référence à la libération de la méthode qui suppose que le pointeur qu'il reste valable. La raison pour laquelle GDB masquait probablement cela est que GDB n'autorise que 2 threads de fonctionner simultanément. Si vous avez plus de 2 threads en cours d'exécution, le seul 2 sera activement exécuté simultanément. GDB a également des hits de performance qui pourraient masquer cette condition spécifique. Comme mentionné par ED, effectuez simplement votre dépotoir de l'application et vous pouvez ouvrir le noyau dans GDB et vérifier la pile.


0 commentaires

0
votes

Ce comportement est-il commun?

oui. Le comportement non défini est la source de la plupart de ces problèmes et, par définition, cela n'est pas défini. Recompilation avec -g peut certainement affecter les résultats. Le recompilation peut-être de modifier les résultats, si le compilateur utilise un algorithme génétique pseudo-aléatoire pour optimiser les choses ou quelque chose comme ça.

Quel est le meilleur moyen d'aborder le problème?

Une once de prévention vaut la peine de guérir; Apprenez les causes courantes du comportement indéfini et récupérez de bonnes habitudes pour éviter de les écrire. Une fois que vous avez constaté qu'il y avait un problème, une analyse statique du code est souvent une bonne idée; Passez et raisonnez-vous et prouvez que les indices resteront dans les limites, les données conviendront à ses tableaux, les pointeurs non valides ne seront pas déréférencés, etc.


0 commentaires

16
votes

Le moyen le plus simple de comprendre est de capturer des vidages de noyau: xxx

puis exécutez votre programme. Il générera un fichier core

puis utilisez gdb: xxx

et gdb se chargera et vous pouvez exécuter une arrière-marche à Voir exactement quelle opération a suscité le Segfault.


0 commentaires