Как использовать GDB для определения того, какая функция соответствует адресу памяти
Я использую google checker для отслеживания утечки памяти. Это дает мне трассировку стека, такую как:
Leak of 21 bytes in 1 objects allocated from:
@ 0xf6088241
@ 0xf60890d2
@ 0xf6089246
@ 0x8054781
@ 0x8054862
@ 0xf684ee76
@ 0xf684f343
@ 0x804be4c
@ 0x80544f6
@ 0xf5e52bb6
@ 0x804b101
Как определить, какие функции/строки кода соответствуют этим адресам памяти?
Ответы
Ответ 1
Используйте команду info symbol
gdb. 16 Изучение таблицы символов.
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
Ответ 2
Предполагая, что ваш двоичный файл имеет отладочную информацию g++ -g
, вы можете использовать x/
для получения информации, я знаю, что это работает для vtables.
x/<num>xw
для печати <num>
шестнадцатеричных слов памяти, а gdb будет аннотировать левую часть информацией о том, что по адресу.
Ответ 3
Оригинальный вопрос задал вопрос, как это сделать в 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
дает именно то, что было запрошено.