我有一个程序(一个应用程序,而不是一个共享库):
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()函数,但这没有帮助。
答案 0 :(得分:1)
我对man page for dladdr
的理解是,它只能定位位于共享库(也称为共享库)中的符号。相关部分内容如下(强调我的意思):
函数dladdr()确定在addr中指定的地址是否位于调用应用程序加载的共享对象之一中。
但是,我发现this link暗示与-Wl,-E
的链接可能会有所帮助,因此您可以尝试一下。