如何从C 函数的指针中获取函数的名字?
编辑:真正的案例是:我正在编写一个Linux内核模块,并且正在调用内核函数。其中一些函数是指针,我想检查内核源代码中的那个函数的代码。但我不知道它指向哪个功能。我认为可以这样做,因为当系统失败时(内核恐慌),它会在屏幕上打印出当前具有函数名称的callstack。但是,我想我错了......是吗?
发布于 2018-04-17 15:50:14
你可以:
但是,后者是困难的,而且是不可移植的。该方法将取决于操作系统的二进制格式(ELF,即OUT,.exe等),以及链接器所做的任何重定位。
编辑:既然你现在已经解释了你真正的用例是什么,答案其实就没那么难了。/proc/kallsyms
,并且有一个访问它的API:
#include <linux/kallsyms.h>
const char *kallsyms_lookup(unsigned long addr, unsigned long *symbolsize,
unsigned long *ofset, char **modname, char *namebuf)
void print_symbol(const char *fmt, unsigned long addr)
为了简单的调试目的,后者可能会完全满足你的需要-它获取地址,格式化它,并将它发送到printk
。
发布于 2018-04-17 16:30:29
我很惊讶为什么大家都说这是不可能的。在Linux上可以使用非静态函数。
我知道至少有两种方法可以实现这一点。
有用于回溯打印的GNU功能:backtrace()
和backtrace_symbols()
(请参阅man
)。在你的情况下,你不需要,backtrace()
因为你已经有函数指针,你只需要传递它backtrace_symbols()
。
示例(工作代码):
#include <stdio.h>
#include <execinfo.h>
void foo(void) {
printf("foo\n");
}
int main(int argc, char *argv[]) {
void *funptr = &foo;
backtrace_symbols_fd(&funptr, 1, 1);
return 0;
}
编译 gcc test.c -rdynamic
输出: ./a.out(foo+0x0)[0x8048634]
它为你提供二进制名称,函数名称,函数启动时的指针偏移量和指针值,以便你可以解析它。
另一种方法是使用dladdr()
(另一种扩展),我猜是print_backtrace()
使用dladdr()
。dladdr()
返回Dl_info
具有函数名称的结构dli_sname
。这里我没有提供代码示例,但很明显 - man dladdr
详细信息请参阅。
NB!两种方法都要求函数是非静态的!
那么还有另外一种方法 - 使用调试信息,libdwarf
但它需要未被二次开发的二进制文件,而且不是很容易,所以我不推荐它。
https://stackoverflow.com/questions/-100003899
复制相似问题