IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    kretprobe探究思考

    春秋十二月发表于 2023-09-12 18:26:00
    love 0
    近期朋友问到监控,使我探究了kretprobe的实现,想到编译中的尾调用优化,作个小结
    ​1. kretprobe_trampoline_holder该跳转函数无参是必须的或说最好的通用设计,因为替换返回地址是非正常程序流程,即被探测函数的调用者无感知,不存在为跳转函数准备入参。若要设计传参且只读,则不会破坏被探测函数调用者的上下文,但跳转函数内部流程怎么用参数是个问题,这需要一种约定
    ​2. 跳转函数为调用trampoline_handler准备入参,即在栈上构造一个(不完整的)pt_regs,再把它地址即栈顶赋给rdi,rdi是x86_64上传入第一参数使用的寄存器,同时预留一个栈单元存放原返回地址(为什么要预留?因为被探测函数返回时,其调用者存放返回地址的栈空间被释放了,所以得在跳转函数内造一个)。由于trampoline_handler内调到用户自定义handler而传入pt_regs,因此自定义handler内要注意最好别改动pt_regs,否则会破坏被探测函数调用者的上下文
    ​3. 表面看kretprobe的实现流程有点像尾调用优化,但有本质区别。后者中被调尾函数直接释放父调用者的栈帧,就可恢复到父调用者的返回地址;前者不能这样干,因为被探测函数的返回地址被替换了,所以需要一个时地(时机地点)恢复,而这时地正是跳转函数的收尾序列代码,把原来的返回地址放于上述2所讲的预留栈单元,这样最后的ret指令弹出它并跳到原返回地址执行。为保证恢复后正常执行,还得恢复被探测函数调用者的上下文即寄存器信息(无须恢复栈内容,因为上述1讲到了跳转函数是无参的)





    春秋十二月 2023-09-13 02:26 发表评论


沪ICP备19023445号-2号
友情链接