当我尝试执行sudo ./mineonlyret加载 ebpf 程序的用户空间程序时,我在 ubuntu 19.04 上收到此错误消息,稍后对此进行描述。我在 ubuntu 18.04 上尝试了相同的配置,并且没有错误。导致此错误的原因可能是什么?\n如果您需要更多详细信息,请告诉我。
libbpf: Error loading ELF section .BTF: 0.\nRun Code Online (Sandbox Code Playgroud)\n\nmineonlyret_user.c
\n\n// SPDX-License-Identifier: GPL-2.0\n#include <stdio.h>\n#include <assert.h>\n#include <linux/bpf.h>\n#include "libbpf.h"\n#include <unistd.h>\n#include <arpa/inet.h>\n#include <linux/if_ether.h>\n\nint main(int ac, char **argv)\n{\n int sock, prog_fd;\n struct bpf_object *obj;\n char filename[256];\n\n if (bpf_prog_load("mineonlyret_kern.o", BPF_PROG_TYPE_SOCKET_FILTER,\n &obj, &prog_fd))\n return 1;\n\n /* open up a packet socket */\n sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); \n if(sock < 0){\n printf("socket");\n return -1;\n }\n\n /* attach the filter */\n assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,\n sizeof(prog_fd)) == 0);\n\n int i;\n char buf[65535];\n for (i = 0; i < 5; i++) {\n printf("ci\\n");\n int res = recvfrom(sock, buf, sizeof(buf), 0, NULL, 0);\n printf("res=%d\\n", res);\n\n sleep(5);\n }\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\nmineonlyret_kern.c
\n\n#include <linux/bpf.h>\n#include <linux/if_ether.h>\n#include <linux/if_packet.h>\n#include <linux/ip.h>\n#include <linux/udp.h>\n#include <linux/in.h>\n#include "bpf_helpers.h"\n#include <stddef.h>\nSEC("socket")\nint bpf_sk_prog(struct __sk_buff *skb)\n{\n\n return 0;\n\n}\nchar _license[] SEC("license") = "GPL";\nRun Code Online (Sandbox Code Playgroud)\n\n我用以下命令编译 _kern.c
\n\nclang -S -I. -O2 -emit-llvm -c mineonlyret_kern.c -o - | llc -march=bpf -filetype=obj -o mineonlyret_kern.o\nRun Code Online (Sandbox Code Playgroud)\n\n和 _user.c 与
\n\ngcc -o mineonlyret mineonlyret_user.c -I../libbpf/src/ ../libbpf/src/libbpf.a -lelf\nRun Code Online (Sandbox Code Playgroud)\n\n另外,我还有另一个疑问:为什么如果我使用库的共享版本它不起作用?我的意思是如果我执行
\n\ngcc -o mineonlyret mineonlyret_user.c -I../libbpf/src/ -L../libbpf/src/ -lbpf\nRun Code Online (Sandbox Code Playgroud)\n\n目录树
\n\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 libbpf\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 include\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 libbpf.so\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 libbpf.a\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 libbpfebpf\n |\xe2\x94\x80\xe2\x94\x80 mineonlyret_user.c\n |\xe2\x94\x80\xe2\x94\x80 mineonlyret_kern.c\nRun Code Online (Sandbox Code Playgroud)\n
小智 5
您需要指定-g请求 Clang 生成 .BTF(它也会生成 DWARF 调试信息,但您可以忽略或删除它,libbpf 不使用它)。虽然 .BTF 最初是一个可选的额外信息,用于更好的调试和 BPF 程序集转储,但它已发展成为现代 BPF 应用程序(至少是那些使用 libbpf 的应用程序)非常必需的部分,因此请确保始终具有“-g”指定的。