Например, я знаю, что 0x46767f0 принадлежит NSString *, есть ли способ узнать, что NSString поможет мне найти некоторые ошибки, с которыми я столкнулся?
Как получить имя символа для адреса памяти в GDB?
Ответ 1
Я считаю, что вы ищете:
info symbol <addresss>
Распечатайте имя символа, который хранится по адресу addr. Если символ не сохраняется точно в addr, GDB печатает ближайший символ и смещение от него.
Пример:
(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
gdb > list * 0xAABBCCDD
Это указывает имя файла и номер строки.
Ответ 3
Если это переменная стека, я не знаю, как это сделать. В противном случае попробуйте p/a <pointer symbol or address>
, и он напечатает имя символа (или смещение к ближайшему имени символа).
Ответ 4
po 0x46767f0
отправит сообщение -description
объекту. Это напечатает содержимое вашего NSString, но я предлагаю использовать ответ Брайана, чтобы проверить содержимое вашего адреса, прежде чем отправлять случайные сообщения на случайные адреса.
Ответ 5
addr2line
Эта утилита Binutils может обрабатывать любой адрес символа, включая переменные и имена функций.
По умолчанию он неинтерактивен, что полезно в некоторых случаях при выполнении вскрытия.
main.c
#include <stdio.h>
int myvar;
int main(void) {
printf("myvar = %d\n", myvar);
}
Скомпилируйте и разберите:
gcc -O 0 -g gdb3 -o main -pedantic-errors -std=c89 -Wextra main.c
readelf -s tmp.out | grep -E ' (main|myvar)'
дает:
55: 0000000000201014 4 OBJECT GLOBAL DEFAULT 24 myvar
65: 000000000000064a 32 FUNC GLOBAL DEFAULT 14 main
А теперь мы можем попробовать:
addr2line -e main 201014 64a
который дает:
/full/path/to/main.c:3
/full/path/to/main.c:5
Библиотека трассировки повышающего стека использует ее, например, для отображения линий трассировки стека: печатать стек вызовов в C или C++