Je débogue en utilisant des vidages mémoire, et notez que gdb a besoin de vous pour fournir l'exécutable ainsi que le vidage mémoire. Pourquoi est-ce? Si le vidage de mémoire contient toute la mémoire utilisée par le processus, l'exécutable n'est-il pas contenu dans le vidage de mémoire? Peut-être n'y a-t-il aucune garantie que l'intégralité de l'exe est chargée en mémoire (les exécutables individuels ne sont généralement pas si gros cependant) ou peut-être que le vidage de mémoire ne contient pas toute la mémoire pertinente après tout? Est-ce pour les symboles (peut-être qu'ils ne sont pas chargés normalement en mémoire)?
11
Réponses:
Le vidage de mémoire n'est que le vidage de l'empreinte mémoire de vos programmes, si vous savez où tout était, vous pouvez simplement l'utiliser.
Vous utilisez l'exécutable car il explique où (en termes d'adresses logiques) les choses se trouvent dans la mémoire, c'est-à-dire le fichier principal.
Si vous utilisez une commande,
objdump
elle videra les métadonnées sur l'objet exécutable que vous étudiez. Utilisation d'un objet exécutable nommé a.out comme exemple.objdump -h a.out
vide les informations d'en-tête uniquement, vous verrez des sections nommées par exemple. .data ou .bss ou .text (il y en a beaucoup plus). Ceux-ci informent le chargeur du noyau où dans l'objet diverses sections peuvent être trouvées et où dans l'espace d'adressage du processus la section doit être chargée, et pour certaines sections (par exemple .data .text) ce qui doit être chargé. (La section .bss ne contient aucune donnée dans le fichier mais elle fait référence à la quantité de mémoire à réserver dans le processus pour les données non initialisées, elle est remplie de zéros).La disposition du fichier objet exécutable est conforme à un ELF standard.
objdump -x a.out
- décharge toutSi l'objet exécutable contient toujours ses tables de symboles (il n'a pas été supprimé -
man strip
et vous avez utilisé-g
pour générer une génération de débogage engcc
supposant une compilation de source CA), alors vous pouvez examiner le contenu principal par des noms de symboles, par exemple si vous aviez une variable / tampon nommé inputLine dans votre code source, vous pouvez utiliser ce nomgdb
pour consulter son contenu. c.-àgdb
-d. connaîtrait l'offset depuis le début du segment de données initialisé de votre programme où commence InputLine et la longueur de cette variable.Pour en savoir plus sur l' article 1 , l' article 2 , et pour la spécification Nitty Gritty Executable and Linking Format (ELF) .
Mettre à jour après le commentaire @mirabilos ci-dessous.
Mais si vous utilisez la table des symboles comme dans
Produit
puis ne pas utiliser la table des symboles et examiner l'adresse directement dans,
Produit
J'ai examiné la mémoire directement sans utiliser la table des symboles dans la 2e commande.
Je vois également que la réponse de @ user580082 ajoute des explications et fera un vote positif.
la source
Le fichier principal est un instantané de l'image de la pile, des mappages de la mémoire et des registres au moment de l'arrêt du processus. Dont le contenu peut être manipulé comme indiqué dans la page de manuel principale . Par défaut, les mappages privés, les mappages partagés et les informations d'en-tête ELF sont vidés dans le fichier principal.
En venant à votre question , la raison pour laquelle gdb nécessite un exécutable est parce qu'il ne simule pas l'exécution, en lisant et en interprétant les instructions binaires comme valgrind le fait à la place, il devient le parent du processus afin de contrôler le comportement du processus pendant l'exécution temps. Il utilise le fichier principal pour déterminer les mappages de mémoire et l'état du processeur du processus lors d'un crash.
Sous Linux, les processus parents peuvent obtenir des informations supplémentaires sur leurs enfants, en particulier la possibilité de les retracer, ce qui permet au débogueur d'accéder aux informations de bas niveau du processus comme lire / écrire sa mémoire, les registres, modifier les mappages de signaux, arrêter son exécution, etc.
Vous comprendrez l'exigence d'un exécutable malgré le fait d'avoir un fichier core plus une fois que vous aurez lu comment fonctionne un débogueur.
la source
(en plus d'autres bonnes réponses)
Sur les systèmes Linux modernes (et de nombreux systèmes similaires à Unix), les informations de débogage (y compris les métadonnées sur les types de symboles, l'emplacement du code source, le type de variables, etc., etc.) sont au format DWARF et se trouvent à l'intérieur de l' exécutable ELF ( ou bibliothèques partagées ELF) lorsqu'il est compilé avec une
-g
option. Je recommande de compiler les programmes à déboguer avec-g3 -O0
et peut-fno-inline
- être si vous utilisez un GCC récent ; cependant, avec GCC, vous pouvez même compiler avec à la fois des informations d'optimisation et de débogage, par exemple avec-O2 -g1
, bien que les informations de débogage puissent dans ce cas être un peu "floues" (cela pourrait légèrement aider à attraper quelques coquins Heisenbugs ).Il est assez judicieux d'éviter de mettre ces informations dans les fichiers core , car vous pourriez avoir de nombreux fichiers core différents (imaginez un logiciel largement utilisé avec de nombreux utilisateurs faisant des rapports de bogues, la plupart avec un
core
vidage) pour le même exécutable. Les fichiers core (5) sont également vidés par le noyau, qui ne devrait pas se soucier de l'existence de sections DWARF dans les exécutables elf (5) (car ces sections ne sont pas mappées dans l' espace d'adressage virtuel du processus défaillant qui a vidé le noyau sur un signal ( 7) ). Il est même possible de placer les informations de débogage dans des fichiers séparés (en dehors de l'exécutable).BTW, GDB peut être douloureusement utilisé pour déboguer les vidages de mémoire pour les exécutables sans aucune information de débogage. Mais ensuite, vous déboguez pratiquement au niveau du code machine (pas au niveau symbolique fourni par les langages de programmation et leurs compilateurs).
la source