Comment déboguer une erreur de segmentation alors que la trace de la pile gdb est pleine de '??'?
Mon exécutable contient la table des symboles. Mais il semble que la trace de la pile est écrasé.
Comment obtenir plus d'informations de cette base s'il vous plaît? Par exemple, il est un moyen d'inspecter le tas ? Voir les objets instances de peupler le tas pour obtenir quelques indices. Que ce soit, toute idée est apprécié.
source d'informationauteur yves Baumes
Vous devez vous connecter pour publier un commentaire.
Je suis un programmeur C++ et j'ai rencontré ce problème plusieurs fois que je l'admettre. Votre demande est smashing ÉNORME partie de la pile. Les Chances sont la fonction qui est la corruption de la pile est aussi de s'écraser sur le retour. La raison en est parce que l'adresse de retour a été remplacé, et c'est pourquoi GDB trace de la pile est foiré.
C'est comment je déboguer cette question:
1)à chacune des étapes de l'application jusqu'à ce qu'il se bloque. (Chercher une fonction qui est de s'écraser sur le retour).
2)une Fois que vous avez identifié la fonction, de déclarer une variable au niveau de la PREMIÈRE LIGNE de la fonction:
(La raison pour laquelle elle doit être la première ligne, c'est que cette valeur doit être tout en haut de la pile. Cette "canaries" sera remplacé avant que la fonction de l'adresse de retour.)
3) Mettre une variable regarder sur les canaries, à chacune des étapes de la fonction et quand canaries!=0, alors vous avez trouvé votre dépassement de tampon! Une autre possibilité de mettre une variable de point d'arrêt pour quand canaries!=0 et il suffit d'exécuter le programme normalement, c'est un peu plus facile, mais pas tous les IDE soutien de la variable de points d'arrêt.
EDIT: j'ai parlé à un programmeur senior dans mon bureau et dans le but de comprendre le core dump vous avez besoin pour résoudre les adresses de mémoire. Une façon de comprendre ces adresses est de regarder la CARTE de fichier pour le binaire, qui est lisible par l'homme. Voici un exemple de génération d'un fichier de la CARTE à l'aide de gcc:
C'est une pièce du puzzle, mais il sera toujours très difficile d'obtenir l'adresse de la fonction qui est en échec. Si vous exécutez cette application sur une plate-forme moderne puis ASLR sera probablement l'une des adresses dans le vidage de la mémoire inutile. Certains de la mise en œuvre de l'ASLR sera de rendre aléatoire la fonction d'adresses de votre binaire qui rend le core dump absolument sans valeur.
ex: gcc -Wall-g -c -o oke.o oke.c
3. Assurez-vous que vous avez également l'option-g pour produire des informations de débogage. Vous pouvez appeler des informations de débogage à l'aide de macros. Les macros suivantes sont très utiles pour moi:
__LINE__
: vous indique la ligne__FILE__
: vous indique le fichier source__func__
: raconte yout la fonctionEspère que cela aiderait
TL;DR: très grand local déclarations de variables dans les fonctions sont alloués sur la pile, qui, sur certaines plate-forme et le compilateur combinaisons, peuvent aisément et endommager la pile.
Juste pour ajouter une autre cause potentielle à ce problème. J'ai été récemment débogage très semblable à la question. L'exécution de gdb avec l'application et le fichier de base serait de produire des résultats tels que:
Qui était très inutile et décevant. Après des heures de récurer l'internet, j'ai trouvé un forum qui parlait de la façon dont le compilateur particulier, nous avons été à l'aide de (Intel compilateur) avait une petite taille de pile par défaut que les autres compilateurs, et que les grands les variables locales pourrait un dépassement de capacité et d'endommager la pile. En regardant notre code, j'ai trouvé le coupable:
}
Bingo! J'ai trouvé MAX_BUFFER_SIZE a été mis à 10000000, donc un 10MB variable locale a été alloué sur la pile! Après la modification de la mise en œuvre de l'utilisation d'un shared_ptr et de créer de la mémoire tampon de façon dynamique, tout à coup le programme a commencé à travailler à la perfection.
Essayez d'exécuter avec Valgrind débogueur mémoire.
À confirmer, a votre exécutable compilé en mode release, c'est à dire pas de symboles de débogage....cela pourrait expliquer pourquoi il y a ?? Essayez de recompiler avec
-g
interrupteur qui "inclut les informations de débogage et de l'ancrer dans l'exécutable" ..à part ça, je suis d'idées de pourquoi vous avez '??'...Pas vraiment. Bien sûr, vous pouvez creuser autour de la mémoire et de voir les choses. Mais sans une trace de la pile vous ne savez pas comment vous en êtes arrivé là où vous êtes ou ce que les valeurs des paramètres ont été.
Cependant, le fait même que votre pile est corrompu, vous dit que vous avez besoin de regarder pour le code qui écrit dans la pile.
Si vous avez un système Unix, "valgrind" est un bon outil pour trouver certains de ces problèmes.
Je suppose que, puisque vous dites "Mon exécutable contient la table des symboles" que vous avez compilé et lié avec-g, et que le binaire n'est pas dépouillé.
Nous pouvons simplement confirmer ce:
cordes -a |grep function_name_you_know_should_exist
Également essayer d'utiliser pstack sur la base du sna voir si il fait un meilleur travail de la cueillette jusqu'à la pile des appels. Dans ce cas, il semble que votre gdb est pas à jour par rapport à votre gcc/g++ version.
Sonne comme vous ne l'utilisez pas l'identique de la glibc version sur votre ordinateur le fichier mémoire, c'est quand il s'est écrasé sur la production. Obtenir les fichiers de sortie par "ldd ./appname" et de les charger sur votre machine, alors dites-gdb où chercher;