运行eBPF程序时bpf_prog_test_run_opts返回未知错误524求助
加载eBPF程序时遇到错误代码524的解决思路
问题描述
尝试加载并运行一个简单eBPF程序时遇到未知错误524,相关代码及配置如下:
eBPF程序(hello.bpf.c)
#include "vmlinux.h" #include <bpf/bpf_helpers.h> SEC("tracepoint/syscalls/sys_exit_open") int tracepoint__syscalls__sys_exit_open(struct trace_event_raw_sys_exit* ctx) { return 0; } char LICENSE[] SEC("license") = "GPL";
用户态加载代码(test.c)
int main (int argc, char *argv[]) { struct __sk_buff skb = {0}; struct hello_bpf *skel; int prog_fd, err = 0; // 定义BPF_PROG_RUN选项和模拟数据 struct bpf_test_run_opts opts = { .sz = sizeof(struct bpf_test_run_opts), .ctx_in = &skb, .ctx_size_in = sizeof(skb) }; // 加载eBPF程序并获取骨架句柄 skel = hello_bpf__open_and_load(); if (!skel) { printf("[error]: failed to open and load skeleton: %d\n", err); return -1; } // 获取程序FD并运行测试 prog_fd = bpf_program__fd(skel->progs.tracepoint__syscalls__sys_exit_open); err = bpf_prog_test_run_opts(prog_fd, &opts); if (err != 0) { printf("[error]: bpf test run failed: %d\n", err); // 返回-1 perror("bpf_prog_test_run_opts"); // 输出:bpf_prog_test_run_opts: Unknown error 524 return -2; } return 0; }
内核配置
CONFIG_BPF=y CONFIG_HAVE_EBPF_JIT=y CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y # BPF subsystem CONFIG_BPF_SYSCALL=y CONFIG_BPF_JIT=y CONFIG_BPF_JIT_ALWAYS_ON=y CONFIG_BPF_JIT_DEFAULT_ON=y CONFIG_BPF_UNPRIV_DEFAULT_OFF=y # CONFIG_BPF_PRELOAD is not set CONFIG_BPF_LSM=y # end of BPF subsystem CONFIG_CGROUP_BPF=y CONFIG_IPV6_SEG6_BPF=y CONFIG_NETFILTER_XT_MATCH_BPF=m CONFIG_BPFILTER=y CONFIG_BPFILTER_UMH=m CONFIG_NET_CLS_BPF=m CONFIG_NET_ACT_BPF=m CONFIG_BPF_STREAM_PARSER=y CONFIG_LWTUNNEL_BPF=y CONFIG_BPF_EVENTS=y CONFIG_BPF_KPROBE_OVERRIDE=y CONFIG_TEST_BPF=m
Makefile
all: hello.bpf.o hello.skel.h test hello.bpf.o: hello.bpf.c clang -target bpf -Wall -O2 -c $< hello.skel.h: hello.bpf.o bpftool gen skeleton $< > $@ test: test.c gcc -Wall -o $@ $< -lbpf .PHONY: clean: rm -rf hello.bpf.o rm -rf hello.skel.h rm -rf test
运行编译后的二进制文件时,输出错误:bpf_prog_test_run_opts: Unknown error 524
问题原因及解决方向
错误码524的内核定义
错误码524对应内核中的BPF_TEST_RUN_CNT_OVERFLOW,但核心触发原因是传入的上下文类型与eBPF程序预期完全不匹配。核心问题:上下文类型不兼容
你的eBPF程序是tracepoint类型,预期接收struct trace_event_raw_sys_exit类型的上下文,但用户态调用bpf_prog_test_run_opts时传入的是struct __sk_buff(网络skb上下文),内核无法处理这种错误的上下文匹配,因此返回错误。具体解决步骤
- 移除
bpf_prog_test_run_opts调用:tracepoint类型的eBPF程序不需要手动调用测试函数,它会在对应的系统调用触发时自动运行。 - 正确挂载tracepoint程序:使用骨架提供的
hello_bpf__attach()函数挂载程序,修改用户态代码如下:int main (int argc, char *argv[]) { struct hello_bpf *skel; int err = 0; // 加载skeleton skel = hello_bpf__open_and_load(); if (!skel) { fprintf(stderr, "[error]: failed to open and load skeleton\n"); return -1; } // 挂载tracepoint程序 err = hello_bpf__attach(skel); if (err != 0) { fprintf(stderr, "[error]: failed to attach skeleton: %d\n", err); hello_bpf__destroy(skel); return -2; } printf("Program attached successfully, press Ctrl+C to exit...\n"); // 等待用户中断 pause(); // 清理资源 hello_bpf__destroy(skel); return 0; } - 验证程序运行:编译运行后,执行任意
open相关系统调用(比如cat /etc/passwd),后续可以在eBPF程序中添加bpf_printk逻辑,通过cat /sys/kernel/debug/tracing/trace_pipe查看程序触发日志。
- 移除
补充说明
bpf_prog_test_run_opts仅适用于XDP、TC、socket filter等可传入模拟上下文的eBPF程序,tracepoint、kprobe类型的程序依赖内核事件触发,无需手动测试运行。- 确保编译时
vmlinux.h存在,可通过bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h生成。
内容的提问来源于stack exchange,提问作者tomwassing
相关产品推荐
相关产品推荐

