eBPF程序使用Ringbuffer时exec__open触发段错误求助
问题:使用ringbuffer时
exec__open触发段错误 我在学习eBPF,参考一个libbpf示例项目,其中simple程序运行正常,但尝试使用ringbuffer时,调用exec__open会触发段错误。
exec.bpf.c
#include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_core_read.h> #include "exec.h" struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } rb SEC(".maps"); struct exec_params_t { u64 __unused; u64 __unused2; char *file; }; SEC("tp/syscalls/sys_enter_execve") int handle_execve(struct exec_params_t *params) { struct task_struct *task = (struct task_struct*)bpf_get_current_task(); struct exec_evt *evt = {0}; evt = bpf_ringbuf_reserve(&rb, sizeof(*evt), 0); if (!evt) { bpf_printk("ringbuffer not reserved\n"); return 0; } evt->tgid = BPF_CORE_READ(task, tgid); evt->pid = BPF_CORE_READ(task, pid); bpf_get_current_comm(&evt->comm, sizeof(evt->comm)); bpf_probe_read_user_str(evt->file, sizeof(evt->file), params->file); bpf_ringbuf_submit(evt, 0); bpf_printk("Exec Called\n"); return 0; } char LICENSE[] SEC("license") = "GPL";
exec.c
#include <stdio.h> #include <stdlib.h> #include <sys/resource.h> #include "exec.skel.h" #include "exec.h" static int libbpf_log_fn(enum libbpf_print_level level, const char *format, va_list args){ vprintf(format,args); fflush(stdout); return 0; } static void bump_memlock_rlimit(void) { struct rlimit rlim_new = { .rlim_cur = RLIM_INFINITY, .rlim_max = RLIM_INFINITY, }; if (setrlimit(RLIMIT_MEMLOCK, &rlim_new)) { fprintf(stderr, "Failed to increase RLIMIT_MEMLOCK limit!\n"); exit(1); } } static int handle_evt(void *ctx, void *data, size_t sz) { const struct exec_evt *evt = data; fprintf(stdout, "tgid: %d <> pid: %d -- comm: %s <> file: %s\n", evt->tgid, evt->pid, evt->comm, evt->file); return 0; } int main(void) { libbpf_set_print(libbpf_log_fn); printf("reached start\n"); fflush(stdout); bump_memlock_rlimit(); printf("bumped the memory limit\n"); fflush(stdout); struct exec *skel = exec__open(); printf("opened the ebpf program\n"); fflush(stdout); exec__load(skel); printf("loaded the ebpf program\n"); fflush(stdout); exec__attach(skel); printf("attached the ebpf program\n"); fflush(stdout); struct ring_buffer *rb = ring_buffer__new(bpf_map__fd(skel->maps.rb), handle_evt, NULL, NULL); for(;;) { ring_buffer__poll(rb, 1000); } return 0; }
exec.h
#ifndef __EXEC_H__ #define __EXEC_H__ struct exec_evt { pid_t pid; pid_t tgid; char comm[32]; char file[32]; }; #endif // __EXEC_H__
程序输出日志(ring.log)
reached start bumped the memory limit libbpf: loading object 'exec' from buffer libbpf: elf: section(3) tp/syscalls/sys_enter_execve, size 56, link 0, flags 6, type=1 libbpf: sec 'tp/syscalls/sys_enter_execve': found program 'handle_execve' at insn offset 0 (0 bytes), code size 7 insns (56 bytes) libbpf: elf: section(4) .reltp/syscalls/sys_enter_execve, size 16, link 26, flags 40, type=9 libbpf: elf: section(5) .rodata, size 12, link 0, flags 2, type=1 libbpf: elf: section(6) license, size 4, link 0, flags 3, type=1 libbpf: license of exec is GPL libbpf: elf: section(7) .maps, size 24, link 0, flags 3, type=1 libbpf: elf: section(16) .BTF, size 1098, link 0, flags 0, type=1 libbpf: elf: section(18) .BTF.ext, size 112, link 0, flags 0, type=1 libbpf: elf: section(26) .symtab, size 360, link 1, flags 0, type=2 libbpf: looking for externs among 15 symbols... libbpf: collected 0 externs total libbpf: map 'rb': at sec_idx 7, offset 0. libbpf: map 'rb': found type = 27. libbpf: map 'rb': found max_entries = 262144. libbpf: map 'rb': found map_flags = 0x0. libbpf: map 'exec.rodata' (global data): at sec_idx 5, offset 0, flags 80. libbpf: map 1 is "exec.rodata" libbpf: sec '.reltp/syscalls/sys_enter_execve': collecting relocation for section(3) 'tp/syscalls/sys_enter_execve' libbpf: sec '.reltp/syscalls/sys_enter_execve': relo #0: insn #0 against '.rodata' libbpf: prog 'handle_execve': found data map 1 (exec.rodata, sec 5, off 0) for insn 0
日志中未显示任何错误,但程序在调用exec__open时崩溃。移除所有ringbuffer相关代码后,程序可正常运行,说明问题出在BPF代码的ringbuffer使用部分。
更新:
更奇怪的是,触发段错误的环境是定制化Debian系统,内核版本6.x.x且启用了PREEMPT_DYNAMIC;但在我的个人机器(Linux Mint,内核6.8)上程序运行完全正常。
内容的提问来源于stack exchange,提问作者Huchsle
相关产品推荐
相关产品推荐

