012.实战:将eBPF程序load进Linux内核
简短结论先给你:
bpftool prog load u_ebpf/mem.bpf.o /sys/fs/bpf/test** 的核心意义是:
**把 eBPF 程序真正交给内核做一次“权威体检”。✔️ 能不能被 verifier 接受
✔️ BTF / 指令 / helper 是否合法
❌ 但不代表程序“逻辑一定正确”或“已经在运行”
下面我分层把这件事讲清楚。
一、这条命令到底做了什么?(逐步拆解)
sudo bpftool prog load u_ebpf/mem.bpf.o /sys/fs/bpf/test
1️⃣ bpftool prog load
- 调用的是
bpf(BPF_PROG_LOAD, …) - 把
.bpf.o里的 eBPF 指令送进内核 - 触发 verifier 全流程校验
👉 这是 eBPF 的“上内核考试”
2️⃣ u_ebpf/mem.bpf.o
- clang 编译出来的 eBPF ELF
- 包含:
- 指令
- maps
- BTF(如果有)
- license
3️⃣ /sys/fs/bpf/test
- pin 位置
- 表示:
“如果 load 成功,请把这个 eBPF 程序固定在 bpffs 里”
👉 程序 不会自动 attach,但已经存在于内核对象系统中。
二、所以:它是不是在“判断 eBPF 有没有问题”?
✅ 是,但只判断 这一类问题
| 能检查什么 | 说明 |
|---|---|
| verifier 是否通过 | 指令安全、控制流、栈 |
| helper 是否可用 | GPL / 非 GPL |
| BTF 是否匹配 | CO-RE / fentry |
| map 定义是否合法 | key/value/size |
| 指令是否合法 | 边界、指针 |
👉 这是“内核级正确性”
❌ 它不检查这些问题
| 检查不到 | 原因 |
|---|---|
| attach 点是否正确 | 还没 attach |
| 程序是否真的执行 | 没有 hook |
| 逻辑是否符合预期 | verifier 不管语义 |
| uprobe 路径是否存在 | 属于 attach 阶段 |
| 打印是否有输出 | 程序未运行 |
三、一个非常关键的误区(一定要澄清)
❌ load 成功 ≠ 程序在跑
此时状态是:
eBPF 程序
✔ 已通过 verifier
✔ 已驻留内核
✖ 没有挂到任何事件
四、那为什么很多人(包括你)会用这一步?
因为它是最干净的“分界线”。
用它可以把问题一刀切开:
如果 load 失败
👉 100% 是 eBPF 程序本身的问题
- 指令
- helper
- BTF
- license
- map
如果 load 成功,但 attach 失败
👉 问题在:
- hook 点
- 函数名
- 路径
- pid
- 内核支持情况
这是非常重要的调试策略。
五、你现在这个命令在工程中的“正确定位”
我给你一个推荐的标准调试流程(你已经走在这条路上了):
clang 编译
↓
bpftool prog load ←【你现在这一步】
↓
bpftool prog attach / libbpf attach
↓
触发事件
↓
bpftool prog tracelog / ringbuf
👉 prog load** 是 verifier 关卡**
六、进一步:怎么把它当成“自动体检”用?
1️⃣ 打开 verifier log(非常建议)
sudo bpftool prog load u_ebpf/mem.bpf.o /sys/fs/bpf/test \
verbose
或:
sudo bpftool prog load u_ebpf/mem.bpf.o /sys/fs/bpf/test \
log_level=2
你会看到:
- 指令逐条分析
- verifier 判断理由
👉 这是写 eBPF 最值钱的调试信息
七、和 libbpf / skeleton 的关系(帮你对齐认知)
| 方式 | 是否走 verifier | 是否 attach |
|---|---|---|
bpftool prog load |
✅ | ❌ |
libbpf load() |
✅ | ❌ |
bpf_program__attach_* |
已 load | ✅ |
👉 本质完全一致,只是入口不同
八、一句“工程级总结”(你可以直接放课里)
bpftool prog load** 的意义不是“程序跑没跑”,
****而是确认:
**“这个 eBPF 程序,内核愿不愿意接受它。”

浙公网安备 33010602011771号