这篇文章上次修改于 594 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

前言

最新内核的安卓手机的内核可能开启了CONFIG_DEBUG_INFO_BTF内核选项,但是也有不少安卓设备的内核其实是没开的

本着少一事的原则,综合考虑还是为安卓创建一个BTFhub,这样更灵活一点

根据【译】BTFGen: 让eBPF程序可移植发布更近一步的介绍可以知道,使用BTFhub的做法也可以让eBPF程序可移植发布更方便

个人理解,简单来说就是:

  • 开启CONFIG_DEBUG_INFO_BTF,编译一份带有BTF信息的内核
  • 通过pahole处理编译产物,即vmlinux,然后得到一个.btf文件
  • 通过bpftool处理vmlinux,得到一份vmlinux.h
  • 基于libbpf库开发,引入vmlinux.h,得到一份需要目标环境内核开启CONFIG_DEBUG_INFO_BTF即可顺利运行的eBPF程序
  • 如果目标环境内核没有开CONFIG_DEBUG_INFO_BTF,那么我们可以借助第二步得到的.btf文件和bpftool工具,生成一份精简后的携带有必要BTF信息的文件,然后在eBPF程序运行前需要做重定位工作时,加载该文件。这样同样可以实现一次编译到处运行

编译内核的过程是顺利的,但是使用pahole生成.btf`文件的时候,还是有一点小坑,简单记录一下

记录

假定现在已经成功编译好内核,已经有vmlinux文件了

根据how-to-use-pahole这篇文章说明,只需要使用下面的命令即可对vmlinux生成.btf文件

pahole --btf_encode_detached external.btf vmlinux

系统本身有pahole,于是我立刻执行了这个命令,然后提示:

pahole: unrecognized option '--btf_encode_detached'

尝试更新下,然后提示(PS,pahole是dwarves这个包的):

dwarves is already the newest version (1.21-0ubuntu1~20.04).

可能是这个源里面这个版本确实没有这个选项,于是下载最新源码编译:

git clone https://github.com/acmel/dwarves --depth=1
cd dwarves
mkdir build
cd build
cmake -D__LIB=lib ..
make install

cmake这一步报错,提示找不到dwarflibdw库,根据项目readme安装两个库:

sudo apt install libdwarf-dev
sudo apt install libdw-dev

清理build文件夹后,重新执行cmake命令,以及普通用户需要使用sudo执行make install

cmake -D__LIB=lib ..
sudo make install

这一次顺利完成编译和安装,但是当我使用这次编译出来的pahole执行前面的命令时,提示如下:

/usr/local/bin/pahole: error while loading shared libraries: libdwarves_emit.so.1: cannot open shared object file: No such file or directory

好在readme说了可以用-DBUILD_SHARED_LIBS=OFF设置为静态链接,这一次pahole终于可以正常使用了


总结下,编译pahole的完整步骤如下:

sudo apt install libdwarf-dev
sudo apt install libdw-dev
git clone https://github.com/acmel/dwarves --depth=1
cd dwarves
mkdir build
cd build
cmake -D__LIB=lib -DBUILD_SHARED_LIBS=OFF ..
sudo make install

vmlinux => btf

pahole --btf_encode_detached external.btf vmlinux

2023-04-07T16:15:52.png