異なるカーネルのvmlinux.h
を生成するには
bpftool
プログラムはvmlinux
ファイルからもvmlinux.
を生成してくれます。もしamd64マシンの上から異なるアーキテクチャーのvmlnux.
を生成したいなら次のようにデバッグシンボル付きパッケージを取得・
$ wget http://ddebs.ubuntu.com/pool/main/l/linux/linux-image-unsigned-5.15.0-12-generic-dbgsym_5.15.0-12.12_amd64.ddeb $ dpkg-deb -x linux-image-unsigned-5.15.0-12-generic-dbgsym_5.15.0-12.12_amd64.ddeb . $ bpftool btf dump file usr/lib/debug/boot/vmlinux-5.15.0-12-generic format c > vmlinux.h
デバッグシンボル付きパッケージは,
- ※5
- 詳細は第674回
「カーネルのクラッシュ情報を解析する」 を参照してください。 - ※6
- リリースごのフレーバーとバージョンはカーネルチームのサイトにあるバージョン情報が参考になります。
もし実機があるなら次の方法でダウンロードURLを取得できます。
$ apt download --print-uris linux-image-unsigned-$(uname -r) 'http://jp.archive.ubuntu.com/ubuntu/pool/main/l/linux/linux-image-unsigned-5.13.0-21-generic_5.13.0-21.21_amd64.deb' (略)
ここの
ユーザーランドプログラムの作成
次に,execsnoop.
)
/* SPDX-License-Identifier: CC0-1.0 */
#include <stdio.h>
#include <unistd.h>
#include "execsnoop.skel.h"
int main(void)
{
struct execsnoop_bpf *obj;
obj = execsnoop_bpf__open();
if (!obj) {
fprintf(stderr, "failed to open BPF object\n");
return 1;
}
if (execsnoop_bpf__load(obj)) {
fprintf(stderr, "failed to load BPF object\n");
goto cleanup;
}
if (execsnoop_bpf__attach(obj)) {
fprintf(stderr, "failed to attach BPF object\n");
goto cleanup;
}
for (;;) {
sleep(1);
}
cleanup:
execsnoop_bpf__destroy(obj);
return 0;
}
これが実質最低限必要なプログラムです。このうちexecsnoop_
」
FOO__
でBPFオブジェクトをメモリ上に展開します。一度成功したあとは,open() 不要になったら FOO__
で破棄する必要があります。destroy() FOO__
でBPFオブジェクトの検証が行われます。コードに問題があった場合は,load() だいたいはここでエラーになります。 FOO__
でカーネルにアタッチします。実際にBPFプログラムが動き出すのはこのタイミングです。attach()
FOO__
とFOO__
はまとめて実行するFOO__
も用意されているので,
今回はbpf_
」
ユーザーランドプログラムをビルドしましょう。こちらはGCCなりClangなり,
$ cc -g -O2 -Wall -c execsnoop.c -o execsnoop.o $ cc -g -O2 -Wall execsnoop.o -lbpf -o execsnoop $ ldd execsnoop linux-vdso.so.1 (0x00007fff2413c000) libbpf.so.0 => /lib/x86_64-linux-gnu/libbpf.so.0 (0x00007f83d6ece000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f83d6ca6000) libelf.so.1 => /lib/x86_64-linux-gnu/libelf.so.1 (0x00007f83d6c88000) libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f83d6c6c000) /lib64/ld-linux-x86-64.so.2 (0x00007f83d6f2b000)
やっていることは単純です。ldd
の実行結果だとlibelfやlibzをリンクしていますが,