You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

eBPF新手使用bpf_trace_printk触发加载错误,TCP报文排查程序运行失败求助

问题分析与解决

1. 你的程序报错根源

首先,程序运行失败的核心问题不是bpf_trace_printk本身,而是kprobe参数处理错误和不安全的内存访问导致eBPF验证器拒绝加载程序:

错误点1:kprobe参数定义错误

tcp_v4_rcv的原型是int tcp_v4_rcv(struct sk_buff *skb),但kprobe类型的eBPF程序的第一个参数必须是struct pt_regs *ctx(保存被挂钩函数的寄存器状态),而不是直接声明struct sk_buff* skb。你需要通过PT_REGS_PARM1(ctx)来获取tcp_v4_rcv的第一个参数(也就是skb)。

错误点2:内存访问未通过验证器检查

即使你正确拿到skb指针,直接访问tcp_hdr(skb)->dest时,eBPF验证器无法确认该内存区域是合法可访问的,因此会抛出R2 !read_ok错误。你需要使用安全的内存读取方式(比如bpf_probe_read)来获取TCP头部数据。

2. 修正后的代码

下面是可以正常运行的修改版本:

hello_kern.c

#include <linux/tcp.h>
#include <uapi/linux/bpf.h>
#include <uapi/linux/ptrace.h>
#include <uapi/linux/tcp.h>
#include <uapi/linux/byteorder/generic.h>
#include "bpf_helpers.h"

SEC("kprobe/tcp_v4_rcv") 
int bpf_prog(struct pt_regs *ctx) {
    // 从寄存器中获取tcp_v4_rcv的skb参数
    struct sk_buff *skb = (struct sk_buff *)PT_REGS_PARM1(ctx);
    struct tcphdr th;
    __u16 dest_port;
    char msg[] = "hello world! My dest is %d\n";

    // 先检查skb指针是否有效
    if (!skb)
        return 0;

    // 使用bpf_probe_read安全读取TCP头部数据,避免验证器报错
    if (bpf_probe_read(&th, sizeof(th), tcp_hdr(skb)) != 0)
        return 0;

    // 将网络字节序的端口号转换为主机字节序,确保打印结果可读
    dest_port = ntohs(th.dest);
    bpf_trace_printk(msg, sizeof(msg), dest_port);

    return 0;
}

char _license[] SEC("license") = "GPL";

hello_user.c(无需修改)

#include "bpf_load.h"
int main(void) {
    if (load_bpf_file("hello_kern.o"))
        return -1;
    read_trace_pipe();
    return 0;
}

修改说明:

  • 用struct pt_regs *ctx作为kprobe程序的入口参数,通过PT_REGS_PARM1宏跨平台获取目标函数的参数。
  • 添加skb空指针检查,避免无效内存访问。
  • 使用bpf_probe_read读取TCP头部,这是eBPF验证器认可的安全内存操作方式。
  • 用ntohs转换端口号的字节序,确保打印出的是十进制的可读端口。

3. 推荐的eBPF学习资源

如果你想系统学习eBPF,这些资源会很有帮助:

  • Linux内核官方文档:内核源码中的Documentation/bpf/目录包含了最权威的eBPF核心概念、辅助函数、程序类型说明,是入门的基础参考。
  • 《BPF Performance Tools》书籍:Brendan Gregg编写,涵盖eBPF的实战应用、工具开发和性能分析,是从入门到进阶的经典读物。
  • 内核eBPF示例程序:Linux源码的samples/bpf/目录提供了大量可运行的示例,覆盖kprobe、tracepoint、XDP等多种场景,适合动手实践。
  • Cilium项目文档:Cilium的文档中有大量eBPF在网络、安全领域的实战教程,适合有实际场景需求的学习者。
  • eBPF官方教程:内核社区维护的教程,包含从基础到高级的概念讲解和示例代码,内容全面且更新及时。

内容的提问来源于stack exchange,提问作者GODP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 17:12:35