当前位置:  开发笔记 > 运维 > 正文

如何从C中的函数指针获取函数的名称?

如何解决《如何从C中的函数指针获取函数的名称?》经验,为你挑选了4个好方法。

如何从C中的函数指针获取函数的名称?

编辑:真实情况是:我正在编写一个Linux内核模块,我正在调用内核函数.其中一些函数是指针,我想检查内核源代码中该函数的代码.但我不知道它指向哪个功能.我认为可以这样做,因为当系统出现故障(内核崩溃)时,它会在屏幕上打印出具有函数名称的当前callstack.但是,我想我错了......是吗?



1> qrdl..:

我很惊讶为什么每个人都说这是不可能的.在Linux上可以实现非静态功能.

我知道至少有两种方法可以实现这一目标.

有用于回溯打印的GNU函数:backtrace()backtrace_symbols()(参见参考资料man).在你的情况下,你不需要backtrace()因为你已经有了函数指针,你只需将其传递给backtrace_symbols().

示例(工作代码):

#include 
#include 

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]

它为您提供二进制名称,函数名称,函数start和指针值的指针偏移量,以便您可以解析它.

另一种方法是使用dladdr()(另一个扩展),我想print_backtrace()使用dladdr().dladdr()返回Dl_infodli_sname字段中具有函数名称的结构.我这里不提供代码示例,但很明显 - 请参阅man dladdr详细信息.

NB!两种方法都要求功能是非静态的!

好吧,还有一种方法 - 使用调试信息,libdwarf但它需要未经剥离的二进制文件,并不是很容易做到这一点,我不推荐它.



2> Alnitak..:

没有额外的帮助,这是不可能的.

你可以:

    在程序映射函数指针中维护一个表到名称

    检查可执行文件的符号表(如果有).

然而,后者很难,并且不便携.该方法将取决于操作系统的二进制格式(ELF,a.out,.exe等),以及链接器完成的任何重定位.

编辑:既然你现在已经解释了你的真实用例,答案实际上并不那么难.内核符号表可用/proc/kallsyms,并且有一个用于访问它的API:

#include 

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,也可以使用printk%pF格式说明.



3> Zskdan..:

在Linux内核中,您可以直接使用printk的"%pF"格式!

void *func = &foo;
printk("func: %pF at address: %p\n", func, func);


@QiZhang它是`%p`格式说明符的扩展,用于打印原始指针地址.此说明符打印函数名称.有关详细信息,请参阅[printk kernel docs](https://www.kernel.org/doc/Documentation/printk-formats.txt).

4> Calmarius..:

以下是我在Linux上的工作原理:

printf使用函数的地址 %p

然后做一个nm | grep

(没有0x前缀)

它应该显示函数名称.

它仅在相关函数位于同一程序中时才有效(不在动态链接库中).

如果您可以找到已加载的共享库的加载地址,则可以从打印的数字中减去地址,并使用库上的nm来查找函数名称.

推荐阅读
拾味湖
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有