Reputation: 1655
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.
Upvotes: 2
Views: 1452
Reputation: 25388
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):
The function dladdr() determines whether the address specified in addr is located in one of the shared objects loaded by the calling application.
However, I found this link which suggests that linking with -Wl,-E
might help, so you could try that.
Upvotes: 2