Utiliser gdb pour convertir des adresses en lignes

J’ai une trace de stack 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 les 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-ssortingpped/edition/of/root/filesystem/sysroot/ file /path/to/non-ssortingpped/edition/of/root/filesystem/sysroot/usr/bin/my-buggy-app info line *0x7f0e457c5696 

Lorsque je saisis la commande de fichier, elle ne charge que les symboles du fichier, pas toutes les bibliothèques utilisées. Y a-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, c’est parce que l’adresse est dans l’une des bibliothèques partagées, mais comment puis-je savoir lequel d’entre eux?

Mais comment puis-je traduire l’adresse en fichiers et numéros de ligne?

Pour le fichier exécutable principal (adresses comme 0x4e8765 ), procédez comme 0x4e8765 :

 addr2line -e /path/to/non-ssortingpped/.../my-buggy-app \ 0x4a6889 0x4a8b43 0x4e8765 

En fait, vous pourriez vouloir soustraire 5 (longueur habituelle de l’instruction CALL ) 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 , les (gdb) info shared vous indiqueront où les bibliothèques ont été chargées.

Si vous n’avez pas obtenu de fichier core et que l’application n’a pas imprimé le mappage requirejs,

  • vous devez corriger l’application pour qu’elle imprime cette information (la trace de la stack est généralement inutile sans elle), et
  • vous pouvez toujours deviner: regardez le code dans l’exécutable à 0x4e8760 – ce devrait être une instruction CALL pour certaines fonctions. Trouvez maintenant la bibliothèque dans laquelle se trouve cette fonction et trouvez son adresse dans la bibliothèque (via nm ). Si vous avez de la chance, cette adresse est près de 0xNc56NN . Vous pouvez maintenant deviner l’adresse de chargement de la bibliothèque à l’ 0x7f0e457NNNNNN . Répétez 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 la suivante:

 info line *0x10045740 

Edit : Remplacé “info symbol 0x10045740” qui ne fonctionnera pas sous certaines conditions (merci @ Thomasa88).