libbpf队列映射创建失败及循环丢首值问题求助
问题解决:libbpf BPF程序监控文件打开的异常修复
一、启动时的libbpf错误日志处理
错误分析
.rodata.str1.16、.eh_frame等段的警告:是GCC编译生成的额外辅助段,libbpf无法识别,不影响程序功能,但可通过编译选项消除。bpf_create_map_xattr(queue_map):Invalid argument(-22):libbpf尝试带BTF信息创建队列映射失败,自动重试不带BTF的方式并成功,程序可正常运行,但该错误提示可通过调整映射定义解决。
修复步骤
- 消除elf段警告:
在BPF程序的编译命令中添加以下参数,禁止生成不必要的段:-fno-asynchronous-unwind-tables # 禁用.eh_frame段 -fdata-sections -ffunction-sections # 优化段生成 - 解决队列映射创建错误:
确保内核版本≥5.8(BPF_MAP_TYPE_QUEUE/STACK从5.8开始支持),同时在映射定义中添加BPF_F_NO_PREALLOC标志,避免预分配内存导致的兼容性问题:struct { __uint(type, BPF_MAP_TYPE_QUEUE); __type(value, struct hash_key); __uint(max_entries, 10); __uint(map_flags, BPF_F_NO_PREALLOC); // 添加此行 } queue_map SEC(".maps");
二、循环丢失第一个值的问题修复
错误分析
核心错误在于打印逻辑顺序颠倒:从队列中取出第一个元素nhkey后,打印时使用的是未初始化的hkey.pathname,而非刚取出的nhkey.pathname,导致第一个元素的路径名无法正确输出,后续打印的是上一次循环的hkey值,造成“丢失第一个值”的假象。
修复代码
修改用户空间的打印逻辑,直接使用取出的nhkey结构体中的字段,移除不必要的hkey冗余定义:
//print out signal(SIGINT, do_quit); int count = 0; while (!quit) { int key = 0; unsigned long long val; struct hash_key nhkey= {}; // 移除多余的hkey定义 printf("******Loop times %d ******\n", count); count++; memset(&nhkey, 0, sizeof(nhkey)); while (bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) == 0) { // 直接使用nhkey的所有字段打印 printf("pid=%d \t\t cmd=%s \t\t pathname=%s\n", (__u32) nhkey.pid, nhkey.comm, nhkey.pathname); //print_stack(&nhkey, stack_map_fd); //usleep(1000000); } usleep(1000000); }
若确实需要保留上一次的hkey数据,调整打印顺序为先打印nhkey再赋值:
while (bpf_map_lookup_and_delete_elem(queue_map_fd, 0, &nhkey) == 0) { printf("pid=%d \t\t cmd=%s \t\t pathname=%s\n", (__u32) nhkey.pid, nhkey.comm, nhkey.pathname); hkey = nhkey; // 先打印再赋值 //print_stack(&nhkey, stack_map_fd); }
内容的提问来源于stack exchange,提问作者deadpool
相关产品推荐
相关产品推荐

