回调函数定位(如何根据函数指针获得函数名)

1 吐槽

        回调函数一个让人看着就有点神秘色彩的名字,说白了就是函数指针,linux内核中大量使用这种东西,这么做好像说是可以提升代码的可扩展性吧。跟java、go等高级语言里的接口、抽象类等概念有得一拼。

        不管什么原因要使用回调函数或者接口之类的东西吧,使用这了些东西之后,这份代码在不运行它的情况下基本上就算是不可读了。这好像也是我们一直看不懂linux内核的代码的原因,想像一下当我们读代码,一直追踪函数调用的时候,最后追踪到调用了一个函数指针,然后我们想这个指针指向谁呢?于是我们就得去找这个指针在哪赋了值,然后全局搜索变量名,我们太天真了,linux内核中会把这个赋值语言“藏”得很深,甚至会发现这个函数指针的值是根据用户输入来确定的。

        不运行代码就读不懂这些使用回调函数、接口或抽象类的代码,这可不是本人下的结论,而是它们自己说的。所谓“运行时绑定”,不就是不运行就不绑定,不绑定就不知道它到底实际调用了哪个函数或都接口实现吗?

        虽然难受,但是以前到现在大多人都这么写代码,我们也只好想办法把这恶心的东西吃下去,所以本文算是想办法给这东西加些香料吧。本文提供的方法也需要把代码运行起来的。

2 linux内核中根据函数指针追踪调用函数名

        linux内核的printks可以输出函数指针对应的函数名。

printk("func: %pF at address: %p\n", func, func); 

        当然,经过本人的实际实验,这个 %pF好像不能输出函数名,真正可用的是 %pS,而且%p也不能直接输出内核指针的值,而要用%px,因此上面的代码应该改为

printk("func: %pS at address: %px\n", func, func); 

         我们可以只输出指针地址,然后去系统目录下的: /proc/kallsyms 文件中根据指针值查相应的函数名,这个文件也是 printk  %pS的实现原理。

3 linux/mocos用户态下的C语言应用程序

#include <stdio.h>
#include <execinfo.h>
int test1(int a){
	printf("%s\n", __func__);
	printf("%d\n", a);
	return 0;
}
int test2(int b){
	return 1;
}
int main() {
	int (*p)(int a)  ;
	p = test2 ;
	p(10);
	backtrace_symbols_fd(&p, 1, 1); 
}

编译命令:gcc a.c -rdynamic

输出: 

 4 其他语言

         连C语言都有这种根据函数指针输出函数名方法,我们应该相信其他应该也一定有。现在我知道Go语言里的反射机制有什么用了,用来吃X的。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值