BPF
CO-RE BTF Libbpf
bpftool 工具
-
查看
.bpf.o中包含的 BTF 信息:bpftool btf dump file hello-buffer-config.bpf.o -
dump 出
vmlinux.h头文件,这个头文件包含内核中所有公开结构体。bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h -
查看已加载 bpf 程序的 debug 信息:
bpftool -d prog load hello.bpf.o /sys/fs/bpf/hello其中
hello.bpf.o是带调试信息的编译产物,/sys/fs/bpf/hello是 bpftool 加载 bpf 程序强制要求指定的 bpf 程序挂载点。有这个程序 在文件系统中的挂载点,bpf 程序,才能做到加载到内核中,不 attach 到 实际运行的 hook 点上。没有这个文件系统的挂载点,那么内核中这个 bpf 程序的引用计数会为 0,内核会清零该 bpf 程序。 -
生成用户空间程序调用的骨架代码(Skeletons):
bpftool gen skeleton hello-buffer-config.bpf.o > hello-buffer-config.skel.h -
查看 bpf 特性,jit、内核 CONFIG 等可用的帮助函数等
bpftool feature
bpf 程序的类型与 attach 类型
bpf 类型定义在头文件 include/uapi/lniux/bfp.h 的 enum bpf_prog_type,
大约有三十种 bpf prog type. enum bpf_attach_type 规定了 bpf 程序 attach
的类型。根据 bpf 程序类型不同,该程序能使用的 helper 函数也有所不同,bpf verifier
会做类型与帮助函数的检查,确保 bpf 程序的稳定性。
对于学习内核工作原理、debug、perf 需求来说主要是以下类型需要重点关注:
SYSCSLL 系统调用相关
KPROBE 附加到任意内核函数
TRACING 动态追踪
TRACEPOINT 静态追踪点
RAW_TRACEPOINT 不封装数据的 TRACEPOINT
STRUCT_OPS 替换或扩展内核中特定数据结构
EXT 替换或修改内核函数
KPROBE
-
kprobe 的 context paramete 作用于 syscall 的时候,parameter 是用户空间传递到内核空间的结构体。 作用于 nonsyscall 的 kprobe 的 paramter 就是内核中相关函数的参数.
-
kretprobe 用法与 kprobe 相似,区别在于 kretprobe 在函数返回时触发, 并且可以获取函数的返回值。kprobe 在函数的入口处触发。
-
fentry/fexit 是 kprobe/kretprobe 新版本内核上更高效的实现。 同时,fexit 相比 kretprobe 可以获取到函数的入参。
-
uprobe/uretprobe 是对应的 userspace 版本,可以追踪用户空间函数。
TRACEPOINT
查看可用的 tracepoints:
cat /sys/kernel/tracing/available_events
查看 tracepoint 的格式:
cat /sys/kernel/tracing/events/syscalls/sys_enter_execve/format
Python BPF
https://github.com/iovisor/bcc/tree/master/src/python/bcc
Rust Aya
bpftrace
https://github.com/bpftrace/bpftrace
Caveats
-
clang 优化等级必须是
-O2. 因为 clang 默认的优化等级会使用call <register>指令; 然而 ebpf 不支持这条指令。 -
必须传递
-g参数,ebpf 程序需要 debug 信息, 同时也可以使用llvm-strip -g <objfile>strip 掉dwarf信息。
Links
ebpf.io https://docs.ebpf.io
helpers https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
bpf kernel functions https://docs.kernel.org/bpf/kfuncs.html
bpftrace cheat sheet https://www.brendangregg.com/BPF/bpftrace-cheat-sheet.html