I have a program (an application, not a shared library):
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();
}
I expect functionName to be "func" - the name of the function from which I make a call to unw_get_proc_name(). But unw_get_proc_name() fails. I've debugged it and found out that it uses a function dladdr() to get the name of a function:
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;
}
}
For some reason dyldInfo.dli_sname is 0. Why? How can I fix this?
I also use the function unw_get_proc_name() from a shared library and in this case it succeeds. So the question is why does it fail to retrieve a function name ("func" in the program above) when being called from an application (not a shared library)? And how can I fix it?
I tried to add attributes __attribute__((noinline)) and __attribute__((visibility("default"))) to my func() function, but it didn't help.
My reading of the man page for
dladdr
is that it can only locate symbols located in shared objects, aka shared libraries. The relevant section reads (emphasis mine):However, I found this link which suggests that linking with
-Wl,-E
might help, so you could try that.