基于libbpf-bootstrap用C实现bcc的killsnoop时出现加载失败错误(错误码-13)的调试求助
Hey there, that "failed to load: -13" error corresponds to EACCES (permission denied), but there are a few specific issues in your code and setup that are likely causing this. Let's break down the fixes step by step:
1. Critical Map Type Mistake (Biggest Culprit)
In your killsnoop.bpf.c, you defined the event map as a HASH map, but it needs to be a BPF_MAP_TYPE_PERF_EVENT_ARRAY to work with bpf_perf_event_output. This type mismatch is almost certainly triggering the load failure. Fix the map definition like this:
struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); __uint(key_size, sizeof(int)); __uint(value_size, sizeof(int)); __uint(max_entries, 1024); } event SEC(".maps");
Perf event arrays require key/value sizes to match int (for CPU indices), not the struct types you used for the hash map.
2. Wrong Map Used for Perf Buffer in User-Space
In your killsnoop.c main function, you're passing obj->maps.info_map to perf_buffer__new, but you should be using the event map instead:
perfBuffer = perf_buffer__new(bpf_map__fd(obj->maps.event), PERF_BUFFER_PAGES, handle_event, handle_lost_event, NULL, NULL);
You were trying to attach a perf buffer to a hash map, which the kernel rejects with a type/permission error.
3. Kprobe Function Name Portability
Hardcoding __x64_sys_kill isn't portable across kernel versions or architectures. Instead, use the BPF_KPROBE_SYSCALL macro from libbpf to automatically target the correct syscall entry point:
SEC("kprobe/sys_kill") BPF_KPROBE_SYSCALL(kill_entry, int tpid, int sig) { // Your entry probe logic here } SEC("kretprobe/sys_kill") BPF_KRETPROBE_SYSCALL(kill_return) { // Your return probe logic here }
This avoids architecture-specific prefixes like __x64_ and works reliably across kernel versions.
4. Permission & Kernel Configuration
- Run with sufficient privileges: You need either
sudoor theCAP_BPFandCAP_PERFMONcapabilities to load BPF programs. Try running your binary withsudofirst to rule out permission issues. - Check kernel config: Ensure your kernel has these options enabled:
CONFIG_BPF=yCONFIG_BPF_SYSCALL=yCONFIG_KPROBES=yCONFIG_PERF_EVENTS=y
Verify withzcat /proc/config.gz | grep CONFIG_BPF(adjust the path if your kernel config is stored elsewhere).
5. Minor Code Cleanups
- In your
return_probe, simplify reading the return code withPT_REGS_RC(ctx)instead ofPT_REGS_RC_CORE(unless you're targeting very old libbpf versions). - Update your
killsnoop.hto use standard types instead of defining them manually to avoid mismatches:
#include <stdint.h> #define TASK_COMM_LEN 16 struct event { uint32_t uid; uint32_t pid; int tpid; int sig; int ret; char comm[TASK_COMM_LEN]; };
After applying these fixes, recompile using the libbpf-bootstrap build system (make sure you're using the latest version of libbpf-bootstrap to avoid compatibility issues) and run with sudo. That should resolve the load error and get your killsnoop implementation working.
内容的提问来源于stack exchange,提问作者Yogaraj

