dladdr()
сообщает только о глобальных и слабых символах.Но все функциональные символы Objective C являются локальными:
$ readelf -s so_backtrace
Symbol table '.dynsym' contains 29 entries:
…
Symbol table '.symtab' contains 121 entries:
Num: Value Size Type Bind Vis Ndx Name
…
49: 08048a01 13 FUNC LOCAL DEFAULT 14 _c_TheObject___printTrace
50: 08048a0e 47 FUNC LOCAL DEFAULT 14 _c_TheObject__printTrace
…
Вы можете убедиться, что локальные символы никогда не возвращаются, посмотрев исходный код GNU libc самостоятельно.backtrace_symbols()
определяется в sysdeps / generic / elf / backtracesyms.c.Он использует _dl_addr()
, который определен в elf / dl-addr.c, для предоставления ему имен символов.Это в конечном итоге называет determine_info()
.Если это возможно, он использует хэш-таблицу GNU , которая не включает в себя локальные символы:
49 /* We look at all symbol table entries referenced by the hash
50 table. */
…
60 /* The hash table never references local symbols so
61 we can omit that test here. */
Если хеш-таблица GNU отсутствует, она возвращается кстандартная хеш-таблица.Это включает в себя все символы, но код determine_info()
отфильтровывает все, кроме глобальных символов и слабых символов:
90 if ((ELFW(ST_BIND) (symtab->st_info) == STB_GLOBAL
91 || ELFW(ST_BIND) (symtab->st_info) == STB_WEAK)
Чтобы символизировать адреса функций Objective C, вы должны выполнить поисксебя и не отфильтровывать символы локальных функций.Кроме того, вам придется разобрать символы функции Objective C, чтобы восстановить _c_TheObject___printTrace
в +[TheObject _printTrace]
.