Mon programme fonctionne comme ceci:
exe -p param1 -i param2 -o param3
Il est écrasé et a généré un fichier de vidage de base, core.pid
.
Je souhaite analyser le fichier de vidage de mémoire en
gdb ./exe -p param1 -i param2 -o param3 core.pid
Mais GDB reconnaît les paramètres du fichier EXE comme entrée de GDB.
Comment analyser un fichier de vidage de mémoire dans cette situation?
exe
n'est pas un script shell (pour définir certaines variables, etc.) comme par exemplefirefox
sur Linux?Réponses:
Vous pouvez utiliser le core avec GDB de plusieurs manières, mais transmettre les paramètres qui doivent être passés à l'exécutable à GDB n'est pas la manière d'utiliser le fichier core. Cela pourrait également être la raison pour laquelle vous avez obtenu cette erreur. Vous pouvez utiliser le fichier core des manières suivantes:
gdb <executable> <core-file>
ougdb <executable> -c <core-file>
ouLorsque vous utilisez le fichier core, vous n'avez pas à passer d'arguments. Le scénario de plantage est affiché dans GDB (vérifié avec GDB version 7.1 sur Ubuntu).
Par exemple:
Si vous souhaitez transmettre des paramètres à l'exécutable à déboguer dans GDB, utilisez
--args
.Par exemple:
Les pages de manuel seront utiles pour voir d'autres options GDB.
la source
Utilisation simple de GDB, pour déboguer les fichiers coredump:
Un fichier coredump pour un "processus" est créé en tant que fichier "core.pid".
Une fois que vous êtes entré dans l'invite GDB (lors de l'exécution de la commande ci-dessus), tapez:
Cela vous donnera les informations de la pile, où vous pourrez analyser la cause du crash / de la panne. L'autre commande, aux mêmes fins est:
C'est la même chose que ci-dessus. Par convention, il répertorie toutes les informations de la pile (ce qui conduit finalement à l'emplacement du crash).
la source
Ignorez simplement les paramètres. GDB n'en a pas besoin:
la source
objdump
+gdb
exemple exécutable minimalTL; DR:
objdump -s core
peut être utilisé pour vider la mémoire en masseMaintenant, pour la configuration complète du test éducatif:
principal c
Compilez et exécutez pour générer le noyau:
Production:
GDB nous indique la ligne exacte où l'erreur de segmentation s'est produite, ce que la plupart des utilisateurs veulent lors du débogage:
puis:
qui nous dirige directement vers la ligne buggy 7.
Les arguments CLI sont stockés dans le fichier core et n'ont pas besoin d'être passés à nouveau
Pour répondre aux questions d'argument CLI spécifiques, nous voyons que si nous changeons les arguments cli par exemple avec:
alors cela se reflète dans le bactrace précédent sans aucun changement dans nos commandes:
Alors notez comment maintenant
argc=3
. Par conséquent, cela doit signifier que le fichier principal stocke ces informations. Je suppose que ça le stocke juste comme les arguments demain
, tout comme il stocke les arguments de toute autre fonction.Cela a du sens si vous considérez que le vidage de mémoire doit stocker la totalité de la mémoire et de l'état des registres du programme, et qu'il a donc toutes les informations nécessaires pour déterminer la valeur des arguments de fonction sur la pile actuelle.
Il est moins évident d'inspecter les variables d'environnement: Comment obtenir une variable d'environnement à partir d'un vidage de mémoire Les variables d'environnement sont également présentes en mémoire, de sorte que l'objdump contient ces informations, mais je ne sais pas comment les répertorier toutes en une seule fois. , un par un comme suit a cependant fonctionné sur mes tests:
Analyse Binutils
En utilisant des outils binutils comme
readelf
etobjdump
, nous pouvons vider en bloc les informations contenues dans lecore
fichier, telles que l'état de la mémoire.La plupart / tout cela doit également être visible via GDB, mais ces outils binutils offrent une approche plus globale qui est pratique pour certains cas d'utilisation, tandis que GDB est plus pratique pour une exploration plus interactive.
Première:
nous dit que le
core
fichier est en fait un fichier ELF :c'est pourquoi nous pouvons l'inspecter plus directement avec les outils binutils habituels.
Un rapide coup d'œil à la norme ELF montre qu'il existe en fait un type ELF qui lui est dédié:
Vous trouverez de plus amples informations sur le format à l'adresse:
Ensuite:
donne quelques indications sur la structure des fichiers. La mémoire semble être contenue dans les en-têtes de programmes ordinaires:
et il y a plus de métadonnées présentes dans une zone de notes, contient notamment
prstatus
le PC :objdump
peut facilement vider toute la mémoire avec:qui contient:
qui correspond exactement à la valeur stdout dans notre exécution.
Cela a été testé sur Ubuntu 16.04 amd64, GCC 6.4.0 et binutils 2.26.1.
la source
À partir du didacticiel du débogueur GDB de RMS :
Assurez-vous que votre fichier est vraiment une
core
image - vérifiez-le en utilisantfile
.la source
Une approche légèrement différente vous permettra de sauter complètement GDB. Si tout ce que vous voulez est une trace arrière, l'utilitaire spécifique à Linux 'catchsegv' capturera SIGSEGV et affichera une trace arrière.
la source
Peu importe si l'exécutable a des arguments ou non. Pour exécuter GDB sur n'importe quel binaire avec un fichier core généré, la syntaxe est ci-dessous.
Permettez-moi de prendre l'exemple ci-dessous pour plus de compréhension.
À partir de la sortie ci-dessus, vous pouvez deviner quelque chose à propos du core, s'il s'agit d'un accès NULL, SIGABORT, etc.
Ces nombres # 0 à # 10 sont les cadres de pile de GDB. Ces cadres de pile ne sont pas de votre binaire. Dans les 0 à 10 images ci-dessus, si vous suspectez quelque chose de mal, sélectionnez cette image
Maintenant, pour voir plus de détails à ce sujet:
Pour étudier le problème plus en détail, vous pouvez imprimer les valeurs de variable suspectées ici à ce stade.
la source
Tapez simplement la commande:
Ou
Il n'est pas nécessaire de fournir un argument de ligne de commande. Le vidage de code généré à la suite d'un exercice précédent.
la source
Vous pouvez analyser le fichier de vidage de mémoire en utilisant la commande "gdb".
la source