Exported symbol为空时怎么获取函数名
时间: 2024-03-18 22:42:16 浏览: 115
如果一个函数没有导出符号,无法通过`dladdr`函数获取函数名。但是我们可以通过解析可执行文件的符号表获取函数名。
首先需要使用`dlopen`函数打开可执行文件,然后通过`dlsym`函数获取可执行文件中函数的地址。接着使用`nm`命令或`libbfd`库解析可执行文件的符号表,找到函数的名称。
以下是一个示例代码,可以获取可执行文件中所有函数的名称:
```c++
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <bfd.h>
#include <string.h>
#include <errno.h>
void print_function_name(void* addr) {
Dl_info info;
if (dladdr(addr, &info) && info.dli_sname) {
printf("%s\n", info.dli_sname);
return;
}
bfd* abfd;
bfd_init();
abfd = bfd_openr("/path/to/executable", 0);
if (!abfd) {
fprintf(stderr, "Failed to open executable: %s\n", strerror(errno));
return;
}
if (!bfd_check_format(abfd, bfd_object)) {
fprintf(stderr, "Invalid executable format\n");
bfd_close(abfd);
return;
}
long storage_needed = bfd_get_symtab_upper_bound(abfd);
if (storage_needed < 0) {
fprintf(stderr, "Failed to get symbol table size\n");
bfd_close(abfd);
return;
}
asymbol** symbol_table = (asymbol**)malloc(storage_needed);
long symbols_read = bfd_canonicalize_symtab(abfd, symbol_table);
if (symbols_read < 0) {
fprintf(stderr, "Failed to read symbol table\n");
bfd_close(abfd);
free(symbol_table);
return;
}
for (long i = 0; i < symbols_read; ++i) {
if (symbol_table[i]->flags & BSF_FUNCTION) {
bfd_vma value = symbol_table[i]->value;
if (value == (bfd_vma)addr) {
printf("%s\n", symbol_table[i]->name);
}
}
}
bfd_close(abfd);
free(symbol_table);
}
int main() {
// Call some functions
print_function_name((void*)&main);
print_function_name((void*)&printf);
print_function_name((void*)&print_function_name);
return 0;
}
```
需要注意的是,`libbfd`库是GNU binutils的一部分,需要安装binutils才能使用。另外,该库可能会影响程序性能,因为它需要解析可执行文件的符号表。
阅读全文