我正在通过
libbpf
库学习如何在 Linux 环境中使用 eBPF。我有一个简单的 eBPF 程序,可以在内核版本 5.15.0-125-generic 上成功编译并运行,但是将内核升级到 6.8.0-48-generic 后,程序无法运行并出现以下错误消息:
libbpf: failed to find valid kernel BTF
libbpf: Error loading vmlinux BTF: -3
libbpf: failed to load object 'execve.bpf.o'
Failed to load eBPF object
环境:
neofetch
命令结果如下:
项目详情:
我正在开发一个小型 eBPF 项目,该项目跟踪
execve()
系统调用。该代码可在我的 GitHub 存储库中找到:
https://github.com/KnightChaser/hello-eBPF/tree/main/application/00_execve_tracking
该项目包括:
execve()
执行的内核端代码。采取的步骤:
生成
vmlinux.h
:
sudo apt update
sudo apt install linux-headers-$(uname -r) clang llvm libbpf-dev gcc-multilib make
bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
构建程序:
make
运行程序:
sudo ./execve_user
这会导致上述错误消息。
故障排除尝试:
已验证内核 BTF 支持:确保内核编译时支持 BTF。
已检查
pahole
版本:确认pahole
为1.25版本。
设置
LIBBPF_LOG_LEVEL=debug
:尝试获取更详细的日志,但没有产生额外的输出。
LIBBPF_LOG_LEVEL=debug sudo ./execve_user
已使用
strace
:跟踪系统调用并注意到程序尝试访问不存在的文件,例如/boot/vmlinux-6.8.0-48-generic
:
access("/boot/vmlinux-6.8.0-48-generic", R_OK) = -1 ENOENT (No such file or directory)
access("/lib/modules/6.8.0-48-generic/vmlinux-6.8.0-48-generic", R_OK) = -1 ENOENT (No such file or directory)
...
相反,在内核5.15.0-125-generic上,程序不会尝试访问这些文件并成功运行。
附加信息:
vmlinux.h
文件存在并且生成时没有错误。问题:
为什么我的 eBPF 程序在升级到内核
6.8.0-48-generic后失败并显示
libbpf: failed to find valid kernel BTF
,如何解决此问题?
任何关于为什么
libbpf
无法在新内核上找到有效内核 BTF 以及我可以采取哪些步骤来解决此问题的见解将不胜感激。
到目前为止我尝试过的:
vmlinux.h
:确保 vmlinux.h
与新内核保持同步。/sys/kernel/btf/vmlinux
存在且可访问。libbpf
在多个位置搜索 BTF 文件,但新内核不存在这些文件。任何有关如何解决此问题的帮助或指导将不胜感激!
(注:目前,这个问题正在 https://github.com/libbpf/libbpf/issues/863 的 GitHub 问题上持续进行,这是我昨天写的。由于
libbpf
存储库 GitHub 不太活跃,我再次精炼句子后将我的问题上传到 StackOverflow,在那里可以联系到相关开发人员。)
出现此问题的原因是旧版本的
libbpf
,某些功能与升级后的内核(内核6.x.x.)不兼容。自从将 libbpf
软件包升级到 1.5.0
并为我的 Linux 机器重新配置库配置后,我发现此类问题不再出现。
您可以在https://github.com/libbpf/libbpf/issues/863找到更多详细信息。