BPF tracepoint参数以及它们在不同示例代码中的差异原因

huangapple go评论83阅读模式
英文:

BPF tracepoint args and why they're different in different example code

问题

我已经做了很多关于编写用于跟踪点的BPF程序的信息搜索,似乎我缺少一个重要的信息,我找不到明确的答案。

让我们以tracepoint/syscalls/sys_enter_open为例。

在某些代码中,我看到:

SEC("tracepoint/syscalls/sys_enter_open")
int tracepoint_sys_enter_open(struct trace_event_raw_sys_enter* ctx)

而在其他代码中,他们似乎会使用/sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format来派生一个本地结构(比如struct open_enter_ctx),然后使用它:

SEC("tracepoint/syscalls/sys_enter_open")
int tracepoint_sys_enter_open(struct open_enter_ctx* ctx)

也许这与构建环境/工具有关?

mozillazg的博客讨论了使用struct trace_event_raw_sys_enter,但没有提到环境。
https://mozillazg.com/2022/05/ebpf-libbpf-tracepoint-common-questions-en

BCC的libbpf-tools中的opensnoop也使用struct trace_event_raw_sys_enter,但我已经成功构建和运行了这段代码,而无需安装BCC(只需安装libbpf和clang)。
https://github.com/iovisor/bcc/blob/master/libbpf-tools/opensnoop.bpf.c

其他示例使用本地结构,比如这个内核源代码示例:https://github.com/torvalds/linux/blob/5d0c230f1de8c7515b6567d9afba1f196fb4e2f4/samples/bpf/syscall_tp_kern.c

以及这个Stack Overflow的问题:https://stackoverflow.com/questions/75294010/how-to-use-bpf-probe-read-to-copy-large-length-data-in-ebpf-program

任何帮助澄清这个问题都将不胜感激。

英文:

I've done a lot of searching for information about writing a BPF program for tracepoints and I seem to be missing an important nugget of information that I can't find a definitive answer for.

Let's take tracepoint/syscalls/sys_enter_open as an example.

In some code I see:

SEC("tracepoint/syscalls/sys_enter_open")
int tracepoint_sys_enter_open(struct trace_event_raw_sys_enter* ctx)

and in others they'll (apparently) use /sys/kernel/debug/tracing/events/syscalls/sys_enter_open/format to derive a local struct (say struct open_enter_ctx) and use that:

SEC("tracepoint/syscalls/sys_enter_open")
int tracepoint_sys_enter_open(struct open_enter_ctx* ctx)

perhaps it has something to do with the build environment/tools?

mozillazg's blog discusses using struct trace_event_raw_sys_enter but but doesn't mention the environment.
https://mozillazg.com/2022/05/ebpf-libbpf-tracepoint-common-questions-en

opensnoop in BCC's libbpf-tools also uses struct trace_event_raw_sys_enter, but I've gotten this code to build and run w/o installing BCC (just libbfp and clang)
https://github.com/iovisor/bcc/blob/master/libbpf-tools/opensnoop.bpf.c

other examples use a local struct, such as in this kernel source example: https://github.com/torvalds/linux/blob/5d0c230f1de8c7515b6567d9afba1f196fb4e2f4/samples/bpf/syscall_tp_kern.c

and this SO question: https://stackoverflow.com/questions/75294010/how-to-use-bpf-probe-read-to-copy-large-length-data-in-ebpf-program

Any help sorting this out would be much appreciated.

答案1

得分: 1

在为跟踪点编写BPF程序时,例如syscalls:sys_enter_open,您可能会遇到不同的访问跟踪点上下文(ctx)的方式。一些关键点需要考虑:

  • 选择使用struct trace_event_raw_sys_enter还是自定义本地结构体(struct open_enter_ctx)取决于您所参考的代码以及您正在使用的环境或工具。没有明确的答案来确定哪种方法是正确的。
  • struct trace_event_raw_sys_enter是内核提供的预定义结构体,代表跟踪点事件的原始数据。它允许您直接访问跟踪点字段。这种方法通常在BCC的libbpf工具中使用,如opensnoop.bpf.c示例中所示。
  • 使用自定义本地结构体,如struct open_enter_ctx,允许您定义一个更具体的结构,以匹配您从跟踪点事件中感兴趣的字段。这种方法使您可以更好地控制您希望访问的数据,并且可以使您的代码更易读。内核源代码示例和您提到的Stack Overflow问题演示了这种方法。

选择使用struct trace_event_raw_sys_enter还是自定义本地结构体取决于您的具体要求以及您所参考的代码。这两种方法都是有效的,决策可能会受到您正在使用的环境或工具的影响。

英文:

When writing a BPF program for tracepoints, such as syscalls:sys_enter_open, you may come across different ways of accessing the tracepoint context (ctx). Some key points to consider:

  • The choice of using struct trace_event_raw_sys_enter or a custom local struct (struct open_enter_ctx) depends on the code you are referencing and the environment or tools you are using. There is no definitive answer as to which one is the correct approach.
  • The struct trace_event_raw_sys_enter is a predefined structure provided by the kernel that represents the raw data of the tracepoint event. It allows you to access the tracepoint fields directly. This approach is commonly used in BCC's libbpf-tools, as seen in the opensnoop.bpf.c example.
  • Using a custom local struct, like struct open_enter_ctx, allows you to define a more specific structure that matches the fields you are interested in from the tracepoint event. This approach gives you more control over the data you want to access and can make your code more readable. The kernel source example and the Stack Overflow question you mentioned demonstrate this approach.

The choice between using struct trace_event_raw_sys_enter or a custom local struct depends on your specific requirements and the code you are referencing. Both approaches are valid, and the decision may be influenced by the environment or tools you are using.

huangapple
  • 本文由 发表于 2023年8月4日 02:23:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830721.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定