J'ai une trace de pile générée par une application supprimé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 supprimé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 en 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. Existe-t-il un moyen de le faire?
La commande "info line" dit:
Aucune information de numéro de ligne disponible pour l'adresse 0x7f0e442d801d
Ce que je suppose est que l'adresse se trouve dans l'une des bibliothèques partagées, mais comment puis-je savoir dans laquelle d'entre elles?
Mais comment puis-je traduire l'adresse en fichiers et en numéros de ligne?
Pour l'exécutable principal (adresses comme 0x4e8765
) faites ceci:
addr2line -e /path/to/non-stripped/.../my-buggy-app \
0x4a6889 0x4a8b43 0x4e8765
En fait, vous voudrez peut-être soustraire 5
(longueur habituelle de l'instruction CALL
) à partir de toutes les adresses ci-dessus.
Pour les adresses dans les 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ù les bibliothèques ont été chargées.
Si vous n'avez pas obtenu de fichier principal et que l'application n'a pas imprimé le mappage requis, alors
0x4e8760
- il doit s'agir d'une instruction CALL
d'une fonction. Maintenant, découvrez dans quelle bibliothèque se trouve cette fonction et recherchez son adresse dans la bibliothèque (via nm
). Si vous avez de la chance, cette adresse est proche de 0xNc56NN
. Vous pouvez maintenant deviner l'adresse de chargement de n'importe quelle bibliothèque à 0x7f0e457NNNNNN
. Répétez l'opération pour 0x7f0e457c55e1
, et vous pouvez trouver l'adresse de chargement de la bibliothèque à 0x7f0e442dNNNN
.Selon l'OP, la commande dans GDB pour trouver la ligne de code source à partir d'une adresse est:
info line *0x10045740
Edit : "Info symbol 0x10045740" remplacé qui ne fonctionnera pas sous certaines conditions (merci @ Thomasa88).