bpftrace报错多因权限或配置问题:需确保用户有CAP_SYS_ADMIN能力、/proc/sys/kernel/unprivileged_bpf_disabled=0,且内核启用CONFIG_BPF=y等必要选项。

运行 bpftrace 报 permission denied 或 BPF program compile failed,绝大多数情况不是程序写错了,而是内核权限、用户能力或安全机制没开到位。核心问题往往出在三处:CAP_SYS_ADMIN 缺失、bpf 系统调用被禁用、或内核未启用必要配置。
确认当前用户是否具备 CAP_SYS_ADMIN 能力
bpftrace 加载 BPF 程序必须拥有 CAP_SYS_ADMIN(或以 root 运行)。普通用户即使加了 sudo,若 sudoers 配置未显式保留能力,也可能失败。
- 检查当前 shell 是否有该能力:
capsh --print | grep cap_sys_admin,无输出即缺失 - 临时测试:用
sudo capsh --caps=cap_sys_admin+eip --user=$USER --shell进入带能力的 shell,再运行 bpftrace - 生产环境建议:将用户加入
sudo组,并确保/etc/sudoers中包含Defaults env_keep += "CAPS"或直接用sudo -E bpftrace ...
检查 /proc/sys/kernel/unprivileged_bpf_disabled 是否为 0
该 sysctl 控制非特权用户能否使用 bpf() 系统调用。值为 1 时,即使有 CAP_SYS_ADMIN,部分 bpftrace 功能(如 map 创建、辅助函数调用)也会静默失败,报错常表现为 “BPF program compile failed”。
- 查看状态:
cat /proc/sys/kernel/unprivileged_bpf_disabled - 临时开启:
sudo sysctl kernel.unprivileged_bpf_disabled=0 - 永久生效:在
/etc/sysctl.conf中添加kernel.unprivileged_bpf_disabled = 0,然后sudo sysctl -p - 注意:某些发行版(如 Ubuntu 22.04+、RHEL 9)默认设为 1,且部分云主机/容器环境可能锁定该值不可改
验证内核是否启用必需的 BPF 配置项
bpftrace 依赖多个内核编译选项,缺失任一关键项都可能导致编译失败或运行时拒绝加载。
- 必须启用:
CONFIG_BPF=y、CONFIG_BPF_SYSCALL=y、CONFIG_BPF_JIT=y(推荐)、CONFIG_BPF_EVENTS=y、CONFIG_TRACING=y - 快速检查:
zcat /proc/config.gz | grep -E 'CONFIG_BPF|CONFIG_TRACING' | grep "=y"(若无 config.gz,可查/boot/config-$(uname -r)) - 常见坑:
CONFIG_BPF_JIT关闭时,某些复杂 probe(如 kprobe 带参数过滤)会编译失败;CONFIG_TRACING缺失则 tracepoint 类型 probe 不可用
其他易忽略的限制点
有些错误表面是权限问题,实则是运行环境或版本不兼容导致的间接表现。
-
seccomp 或容器限制:Docker/Kubernetes 默认禁用
bpf和perf_event_open系统调用。需显式添加--cap-add=SYS_ADMIN --security-opt seccomp=unconfined(生产慎用) - 内核版本过低:bpftrace v0.14+ 要求内核 ≥ 4.18;若用较新 bpftrace 运行在 4.15 上,可能报奇怪的编译错误而非明确提示
- LLVM 版本不匹配:bpftrace 编译依赖 LLVM。若系统装了多个 LLVM(如 llvm-14 和 llvm-16),而 bpftrace 是用 llvm-14 构建的,却运行在 llvm-16 环境下,可能触发 JIT 失败或 verifier 拒绝










