I have an eBPF programs that currently fails to attach to trace point syscalls/sys_exit_mmap; ebpf.NewCollectionWithOptions() throws an error: "invalid memory address or nil pointer dereference [signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x6ab850]".
Here is the relevant part of my source code. The root cause is apparently in e->sys_exit_mmap_ret = (__s32)ctx.ret, for if I assign 0 (i.e. do not use ctx) the error goes away. What could be wrong here?
struct rb_event {
__u16 opcode;
union {
// ...
struct {
__s32 sys_exit_mmap_ret;
};
};
};
// see /sys/kernel/debug/tracing/events/syscalls/sys_exit_mmap/format
struct sys_exit_mmap_ctx {
__s64 ret;
};
SEC("tracepoint/syscalls/sys_exit_mmap")
int sys_exit_mmap(
struct sys_exit_mmap_ctx *ctx
) {
struct rb_event *e;
e = bpf_ringbuf_reserve(&rb, sizeof(*e), 0);
if (e == NULL) {
return 0;
}
e->opcode = OPCODE_SYS_EXIT_MMAP;
e->sys_exit_mmap_ret = (__s32)ctx->ret;
bpf_ringbuf_submit(e, 0);
return 0;
}
This was a rookie mistake: my
struct rb_eventwas missing header fields as e.g. referred to asstruct trace_entryandsyscall_nrhere and here respectively:These also show up e.g. also in
/sys/kernel/debug/tracing/events/sched/sched_process_exec/format(16 bytes of header fields for a trace event in general) and/sys/kernel/debug/tracing/events/syscalls/sys_exit_kill/format(16 + bytes of header fields for a syscall in particular).