web-dev-qa-db-fra.com

Utiliser gdb pour convertir des adresses en lignes

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?

34
Allan

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

  • vous devez corriger l'application pour qu'elle imprime ces informations (la trace de la pile est généralement inutile sans elle), et
  • vous pouvez toujours deviner: regardez le code dans l'exécutable à 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.
33
Employed Russian

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

35
whitey04