我正在尝试使用 bcc-tools 使用 uprobe 跟踪用户进程,但有些函数采用浮点参数。根据 x86_64 ABI,这些值通常在 xmm 寄存器中传递。
bcc 中的 eBPF 函数接受一个struct pt_regs *
参数,因为我可以访问(?的副本?)大多数“常用”寄存器,但不能访问 xmm 寄存器。
有没有办法做到这一点?或者这是在 eBPF 的设计中被忽略的东西
TL;DR这不是 BPF 的问题,uprobes 和 kprobes 都不能访问 AVX 寄存器,例如 xmm 寄存器。
uprobe 程序实际上作为 kprobe 程序(即)加载到内核中BPF_PROG_TYPE_KPROBE
。
与大多数 BPF 程序相反,kprobe 程序可以在挂钩点访问未经修改的、不受限制的上下文参数。我的意思是 BPF 程序的参数通常是挂钩点给出的实际对象的镜像,访问由验证者重写。例如,几个 BPF 程序将struct __sk_buff
其作为参数,这实际上是(有关更多详细信息,请参阅其他 StackOverflow 答案)的镜像。sk_buff
相反,kprobe 程序可以访问原始对象(的字段为null)。struct pt_regs
convert_ctx_access
struct bpf_verifier_ops
由此我们可以得出结论,kprobes(接收struct pt_regs
)无权访问 AVX 寄存器。所以这是 kprobes 而不是 BPF 的限制。造成这种情况的一个原因可能只是内核中对 AVX 寄存器的支持不足。请参阅此 StackOverflow 答案以获取更多信息。