web-dev-qa-db-fra.com

Comment utiliser GDB pour trouver à quelle fonction correspond une adresse mémoire

J'utilise le vérificateur de tas de Google pour localiser une fuite de mémoire. Cela me donne une trace de pile telle que:

Leak of 21 bytes in 1 objects allocated from:                                                                                                                                                               
    @ 0xf6088241                                                                                                                                                                                               
    @ 0xf60890d2                                                                                                                                                                                               
    @ 0xf6089246                                                                                                                                                                                               
    @ 0x8054781                                                                                                                                                                                                
    @ 0x8054862                                                                                                                                                                                                
    @ 0xf684ee76                                                                                                                                                                                               
    @ 0xf684f343                                                                                                                                                                                               
    @ 0x804be4c                                                                                                                                                                                                
    @ 0x80544f6                                                                                                                                                                                                
    @ 0xf5e52bb6                                                                                                                                                                                               
    @ 0x804b101  

Comment déterminer les fonctions/lignes de code auxquelles ces adresses de mémoire correspondent?

21
Nathaniel Flath

Utilisez la commande info symbol gdb. 16 Examen de la table des symboles .

info symbol addr

Imprimer le nom d'un symbole qui est stocké à l'adresse addr. Si aucun symbole n'est stocké exactement à l'adresse addr, gdb imprime le symbole le plus proche et un décalage de celui-ci:

(gdb) info symbol 0x54320
_initialize_vx + 396 in section .text

C'est l'opposé de la commande info address. Vous pouvez l'utiliser pour trouver le nom d'une variable ou d'une fonction en fonction de son adresse.

Pour les exécutables liés dynamiquement, le nom de l’exécutable ou de la bibliothèque partagée contenant le symbole est également imprimé:

(gdb) info symbol 0x400225
_start + 5 in section .text of /tmp/a.out
(gdb) info symbol 0x2aaaac2811cf
__read_nocancel + 6 in section .text of /usr/lib64/libc.so.6
35
ks1322

En supposant que votre binaire ait des informations de débogage g++ -g, vous pourrez peut-être utiliser x/ pour obtenir les informations. Je sais que cela fonctionne pour vtables.

x/<num>xw pour imprimer <num> mots hexadécimaux de la mémoire, et gdb annotera le côté gauche avec des informations sur le contenu de l'adresse.

2
Mark B

La question initiale demandait comment faire cela dans GDB:

# NOT what you want; note the lack of '*':
(gdb) info symbol 0xfde09edc
blah() + 388 in section .text of /tmp/libblah.so

# IS what you want; note the presence of '*':
(gdb) info line *0xfde09edc
Line 91 of "blah.cc"
   starts at address 0xfde09ebc <blah()+356>
   and ends at 0xfde09ee4 <blah()+396>

Le * est nécessaire pour info line et ne doit pas être utilisé pour info symbol.

Vous pouvez également utiliser la commande disassemble avec son indicateur /m:

(gdb) disassemble /m 0xfde09edc

... bien que ce soit plutôt verbeux et que info line donne exactement ce qui a été demandé.

1
Brian Vandenberg