Utilisation de gdb pour convertir des adresses en lignes
J'ai une trace de pile générée par une application dépouillée qui ressemble à ceci:
*** Check failure stack trace: ***
@ 0x7f0e442d392d (unknown)
@ 0x7f0e442d7b1f (unknown)
@ 0x7f0e442d7067 (unknown)
@ 0x7f0e442d801d (unknown)
@ 0x7f0e457c55e6 (unknown)
@ 0x7f0e457c5696 (unknown)
@ 0x4e8765 (unknown)
@ 0x4a8b43 (unknown)
@ 0x7f0e43197ced (unknown)
@ 0x4a6889 (unknown)
Et j'ai une version non dépouillée de l'exécutable et de toutes ses bibliothèques (compilées avec des informations de débogage). Mais comment puis-je traduire l'adresse en fichiers et numéros de ligne??
Voici ce que j'ai essayé:
gdb
set solib-absolute-prefix /path/to/non-stripped/edition/of/root/filesystem/sysroot/
file /path/to/non-stripped/edition/of/root/filesystem/sysroot/usr/bin/my-buggy-app
info line *0x7f0e457c5696
Lorsque je tape la commande file, elle ne charge que les symboles du fichier, pas toutes les bibliothèques utilisées. Est-il possible de ce qui peut être fait?
Le la commande "info line" indique:
Aucune information de numéro de ligne disponible pour l'adresse 0x7f0e442d801d
, Qui je suppose est parce que l'adresse est dans l'une des bibliothèques partagées, mais comment puis-je savoir où l'un d'eux?
2 réponses
Mais comment puis-je traduire l'adresse en fichiers et numéros de ligne?
Pour l'exécutable principal (adresses comme 0x4e8765
) faire ceci:
addr2line -e /path/to/non-stripped/.../my-buggy-app \
0x4a6889 0x4a8b43 0x4e8765
En Fait, vous pourriez vouloir soustraire 5
(longueur habituelle de la CALL
instruction) de toutes les adresses ci-dessus.
Pour les adresses dans des bibliothèques partagées, vous devez connaître l'adresse de chargement de la bibliothèque.
Si votre application a produit un fichier core
, alors (gdb) info shared
vous indiquera où se trouvaient les bibliothèques charger.
Si vous n'avez pas obtenu de fichier principal et que l'application n'a pas imprimé le mappage requis, alors
- vous devriez réparer l'application afin qu'elle imprime cette information (la trace de la pile est surtout inutile sans elle), et
- Vous pouvez toujours deviner: regardez le code dans l'exécutable à
0x4e8760
- CE devrait être une instructionCALL
à une fonction. Découvrez maintenant dans quelle bibliothèque se trouve cette fonction et trouvez son adresse dans la bibliothèque (vianm
). Si vous avez de la chance, que l'adresse est proche de0xNc56NN
. Vous pouvez maintenant deviner l'adresse de chargement de n'importe quelle bibliothèque à0x7f0e457NNNNNN
. Répétez l'opération pour0x7f0e457c55e1
, et vous pouvez trouver l'adresse de chargement de la bibliothèque à0x7f0e442dNNNN
.
Par L'OP, la commande dans GDB pour trouver la ligne source du code à partir d'une adresse est:
info line *0x10045740
Edit : remplacé "info symbol 0x10045740" qui ne fonctionnera pas sous certaines conditions (merci @ Thomasa88).