kprobe 和 kretprobe 隐藏的秘密

我总劝人不要用 kretprobe 耍技巧,会脱手。

Linux kernel 的 kretprobe 机制和 kprobe 完全不同,本质原因在于,函数的入口地址是固定的,但函数的返回地址不固定,由于返回位置不固定,无法固定函数大小,无法事先插桩。一图以示之:
在这里插入图片描述

想在函数返回时插入个 hook,只有在函数被调用时确定了函数返回地址(x86 为例,压栈返回地址)后才可能。

因此,kprobe 在 register 时即可将 hook 挂载,与 kprobe 不同,kretprobe 需在函数每次被调用时才能将 hook 挂载。这只是事情的轮廓,“在函数调用时挂载 hook” 才是大头。

task 将函数返回地址替换成 kretprobe 的 hook 地址之前要保存旧返回地址,由于函数可被不同 task 同时调用,因此不同 task 需拥有独立的 kretprobe_instance。

同一个 kretprobe hook,不同 kretprobe_instance,Linux kernel 预分配了若干(与 CPU 数量相关) kretprobe_instance,挂接在 kretprobe 的某 list 上,每当有 task 需要 kretprobe 特定函数时,在函数的入口处先从 kretprobe 的 list 上摘出一个 kretprobe_instance 供自己私用,此时函数返回地址已经压栈,替换返回地址为 hook 前将其 save 在独享的 kretprobe_instance 中。

很长一段时间跨越很多内核版本,多个 kretprobe_instance 以 hlist_node 的方式挂接在以 task 地址 hash 为 key 的 hlist 上,而对 hlist_node 的 CURD 必然涉及 lock,对于高频调用的热点函数,kretprobe 里的这个 lock 相当于自设的路障,hash 到同一个 bucket 的 task 同时调用一个函数时会被串行化,严重影响性能,甚至使系统 soft/hard lockup。这是一个知道的人很少的秘密。

为什么不用 percpu lock?因为函数调用返回前可能发生 task 迁移。

后来,那些煤炭奈儿(maintainer,妹忒讷儿)估计也发现了问题,提交了一些派驰(patch),将 hlist 改成了 CAS-based lock-free free list,但人家自己也说了 Not the fastest thing in the world under heavy contention, but simple and correct,详见源文件

上面这些话,请自行比较不同内核版本的 pre_handler_kretprobe 函数实现。该函数的注释是:This kprobe pre_handler is registered with every kretprobe. When probe hits it will set up the return probe.

so?

别张口就来,挂 kretprobe 的前提是你理解它的副作用,而不是只知道个词,特别是那些上了 ebpf 毒瘾的。

我讨厌一些脱离一线很久却又要彰显自己懂得很多而对工人精确指点的经理。这些经理给出一个祈使句指导,代码脚本还是工人照着经理意思去写,经理彰显才华后,事了拂衣去。

经理知道 kretprobe 可以修改函数返回值,但他大概不知道 kretprobe 隐藏的秘密。知道这些秘密的经理不会指使工人用 kretprobe 修改返回值。经理就好好当经理,做好资源和人力的分配调度,别天天混进工人队伍里瞎指挥,还美其名曰技术导向,这就是扯淡。

kretprobe 的理论解法是将 return address 也固定,因此理论上可以截获 ret 指令,进入一个 common stub hook 中判定该函数是不是需要被 hook,如果不需要这就返回,如果需要就先调用 hook 再返回,但依然会引入别的开销,那么可以缩小替换范围,只在 kretprobe function 附近搜索并替换 ret 指令。

还有吗,还有,但不相关了。

工人提出用 kretprobe 修改 init_cwnd,经理会说这是非标的方案,kprobe/kretprobe 更多只做 debug 和可观测性,不能上线…但工人想修改 init_cwnd 却没方案时,经理会让工人用 kretprobe 来改,绝口不提是否非标。经理知道 kprobe/kretprobe,但并不真懂,仅科普水平,或做过 demo,但也仅此。对技术细节非常感兴趣又亲自指挥细节的经理不是合格经理。但不知何时,不知为什么,工人们普遍觉得懂技术的经理才合格,于是经理们不得不去懂点技术,显得很 geek,这样才是真经理。很多经理都会此地无银三百两式地强调自己写过代码,懂技术,可也没人问啊。

浙江温州皮鞋湿,下雨进水不会胖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值