2011-10-03 2891 views
17

我正在使用谷歌的堆检查器来追踪内存泄漏。它给了我一个堆栈跟踪,如:如何使用GDB来查找内存地址对应的函数

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

如何确定这些内存地址对应的代码的哪些函数/行?

+3

我很惊讶谷歌的堆检查器不会为你做这种转换。你确定你用“-g”编译? (另外,请看[addr2line命令](http://sourceware.org/binutils/docs/binutils/addr2line.html)) – Nemo

+0

任何符号类型的问题:http://stackoverflow.com/questions/762628/ gdb-getting-a-symbol-name-from-a-memory-address –

回答

33

使用info symbol gdb命令。 16 Examining the Symbol Table

info symbol addr 
Print the name of a symbol which is stored at the address addr. If no symbol is stored exactly at addr, gdb prints the nearest symbol and an offset from it: 
      (gdb) info symbol 0x54320 
      _initialize_vx + 396 in section .text 

This is the opposite of the info address command. You can use it to find out the name of a variable or a function given its address. 

For dynamically linked executables, the name of executable or shared library containing the symbol is also printed: 

      (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 
+0

所以,当我得到一个info命令列表后,发现'info address'没有查找地址,结果还有一个'info符号“命令,它不查询符号。 –

2

假设你的二进制有g++ -g您可以使用x/来获取信息的调试信息,我知道,虚函数表的工作原理。

x/<num>xw要打印<num>内存的十六进制字,gdb将在左侧注释有关地址内容的信息。

1

原来的问题问如何做到这一点的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> 

*是必要的info line,不应该被用于info symbol

您还可以使用disassemble命令其/m标志:

(gdb) disassemble /m 0xfde09edc 

...虽然这是相当冗长,info line给被要求什么。

+0

请注意,'/ m'修饰符不赞成'/ s'(出现在gdb 7.11中)。无论如何,您可以使用'x/i 0xfde09edc'的更多详细输出,而不是反汇编整个函数。 – Ruslan