使用libbpf通过kprobe追踪kill系统调用时pid参数值错误问题
问题根因
Linux x86_64架构下,所有系统调用的内核入口函数(如__x64_sys_kill)仅接收一个const struct pt_regs *类型的入参,该指针指向保存用户态寄存器上下文的结构体,并不会直接暴露系统调用的参数列表。你直接为BPF_KPROBE声明pid_t pid、int sig两个入参,本质是把pt_regs结构体的前两个字段值错误解读为了kill调用的参数,因此拿到的是无关的脏值。
解决方案
方案1:使用BPF_KPROBE_SYSCALL宏(推荐)
libbpf提供的BPF_KPROBE_SYSCALL是专门为系统调用追踪设计的宏,会自动完成pt_regs结构体的解析逻辑,直接获取系统调用参数,代码更简洁易维护:
SEC("kprobe/sys_kill") int BPF_KPROBE_SYSCALL(kill, pid_t pid, int sig) { bpf_printk("Pid = %i\n", pid); return 0; }
方案2:手动从寄存器上下文读取参数
如果你需要直接挂载到__x64_sys_kill符号上,可以手动从pt_regs中提取参数,使用libbpf提供的跨架构兼容宏PT_REGS_PARMx即可获取对应位置的系统调用参数:
SEC("kprobe/__x64_sys_kill") int BPF_KPROBE(__x64_sys_kill, const struct pt_regs *regs) { pid_t pid = (pid_t)PT_REGS_PARM1(regs); bpf_printk("Pid = %i\n", pid); return 0; }
以上两种方案修改后重新编译加载eBPF程序,即可获取到正确的pid参数值。
内容的提问来源于stack exchange,提问作者Skallwar
相关产品推荐
相关产品推荐

