Имя функции, определенной в исполняемом файле (используя dladdr)
У меня есть программа (приложение, а не общая библиотека):
void func() {
int RESULT = UNW_ESUCCESS;
unw_context_t context;
unw_getcontext(&context);
unw_cursor_t cursor;
RESULT = unw_init_local(&cursor, &context);
assert(RESULT == UNW_ESUCCESS);
const int BUFFER_SIZE = 512;
char functionName[BUFFER_SIZE] = {"<unknown>"};
unw_word_t offset;
RESULT = unw_get_proc_name(&cursor, functionName, BUFFER_SIZE, &offset);
}
int main() {
func();
}
Я ожидаю, что functionName будет "func" - имя функции, из которой я делаю вызов unw_get_proc_name(). Но unw_get_proc_name () не работает. Я отладил его и обнаружил, что он использует функцию dladdr (), чтобы получить имя функции:
Dl_info dyldInfo;
if (dladdr((void *)addr, &dyldInfo)) {
if (dyldInfo.dli_sname != NULL) {
snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
*offset = (addr - (pint_t) dyldInfo.dli_saddr);
return true;
}
}
По какой-то причине dyldInfo.dli_sname равно 0. Почему? Как я могу это исправить?
Я также использую функцию unw_get_proc_name () из общей библиотеки, и в этом случае это успешно. Итак, вопрос в том, почему он не может получить имя функции ("func" в программе выше) при вызове из приложения (не из общей библиотеки)? И как я могу это исправить?
Я попытался добавить атрибуты __attribute __ ((noinline)) и __attribute __ ((visibility("default"))) к моей функции func (), но это не помогло.
1 ответ
Мое чтение справочной страницы дляdladdr
является то, что он может найти только символы, расположенные в общих объектах, или общие библиотеки. Соответствующий раздел гласит (выделено мое):
Функция dladdr() определяет, находится ли адрес, указанный в addr, в одном из общих объектов, загруженных вызывающим приложением.
Тем не менее, я нашел эту ссылку, которая предполагает, что связь с -Wl,-E
может помочь, так что вы можете попробовать это.