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?

24
demandé sur Basile Starynkevitch 2011-12-17 19:59:27

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 instruction CALL à une fonction. Découvrez maintenant dans quelle bibliothèque se trouve cette fonction et trouvez son adresse dans la bibliothèque (via nm). Si vous avez de la chance, que l'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.
27
répondu Employed Russian 2011-12-19 15:57:35

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).

22
répondu whitey04 2015-12-11 19:35:10