1

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: How to use bpf_probe_read() to copy large length data in EBPF program?

Any help sorting this out would be much appreciated.

Greg Brown
  • 43
  • 5

1 Answers1

1

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.

Kozydot
  • 515
  • 1
  • 6
  • the part I somehow missed is that, for example in the syscall_tp_kern.c example, the structure syscalls_enter_open_args overlays trace_event_raw_sys_enter exactly – Greg Brown Aug 24 '23 at 15:58