【问题标题】:libbpf: Error loading ELF section .BTF: 0libbpf:加载 ELF 部分时出错。BTF:0
【发布时间】:2020-03-13 18:58:35
【问题描述】:

当我尝试执行 sudo ./mineonlyret 这是加载 ebpf 程序的用户空间程序时,我在 ubuntu 19.04 上收到此错误消息,稍后对其进行描述。我在 ubuntu 18.04 上尝试了相同的配置,并且没有错误。哪个可能是导致此错误的原因? 如果您需要更多详细信息,请告诉我。

libbpf: Error loading ELF section .BTF: 0.

mineonlyret_user.c

// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <assert.h>
#include <linux/bpf.h>
#include "libbpf.h"
#include <unistd.h>
#include <arpa/inet.h>
#include <linux/if_ether.h>

int main(int ac, char **argv)
{
    int sock, prog_fd;
    struct bpf_object *obj;
    char filename[256];

    if (bpf_prog_load("mineonlyret_kern.o", BPF_PROG_TYPE_SOCKET_FILTER,
              &obj, &prog_fd))
        return 1;

    /* open up a packet socket */
    sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));  
    if(sock < 0){
        printf("socket");
        return -1;
    }

    /* attach the filter */
    assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
              sizeof(prog_fd)) == 0);

    int i;
        char buf[65535];
    for (i = 0; i < 5; i++) {
        printf("ci\n");
            int res = recvfrom(sock, buf, sizeof(buf), 0, NULL, 0);
            printf("res=%d\n", res);

        sleep(5);
    }

    return 0;
}

mineonlyret_kern.c

#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <linux/in.h>
#include "bpf_helpers.h"
#include <stddef.h>
SEC("socket")
int bpf_sk_prog(struct __sk_buff *skb)
{

        return 0;

}
char _license[] SEC("license") = "GPL";

我用 _kern.c 编译

clang -S -I. -O2 -emit-llvm -c mineonlyret_kern.c -o - | llc -march=bpf -filetype=obj -o mineonlyret_kern.o

和 _user.c 一起

gcc  -o mineonlyret mineonlyret_user.c -I../libbpf/src/  ../libbpf/src/libbpf.a -lelf

另外我还有一个疑问:为什么如果我使用库的共享版本它不起作用?我的意思是如果我执行

gcc  -o mineonlyret mineonlyret_user.c -I../libbpf/src/  -L../libbpf/src/ -lbpf

目录树

.
├── libbpf
│   ├── include
│   ├── src
│   │   ├── libbpf.so
│   │   └── libbpf.a
└── libbpfebpf
    |── mineonlyret_user.c
    |── mineonlyret_kern.c

【问题讨论】:

  • 这可能来自您的两台机器之间的clang版本差异,也许?你用什么版本?关于共享库,你得到什么错误?还有你用的是什么版本的 libbpf?
  • UBUNTU: 18.04 clang 版本 6.0.0-1ubuntu2 (tags/RELEASE_600/final) libbpf 我认为是 0.0.3 (我在 10 月之前 git 克隆了存储库) UBUNTU: 19.04 clang 版本 8.0.0-3 (tags/RELEASE_800/final) libbpf 我认为是 0.0.5 (我昨天克隆了存储库) 当我执行 gcc -o mineonlyret mineonlyret_user.c -I../libbpf/src -L ../libbpf/src/ -lbpf似乎编译得很好。但是当我执行程序 ./mineonlyret 时出现错误:加载共享库时出错:libbpf.so.0:无法打开共享对象文件:没有这样的文件或目录(如果我使用 .a
  • 对于共享库的东西:看起来您的系统找不到共享库。您是否已编译 libbpf.so 并将其安装在您的系统上?如果是这样,它是否在您的二进制文件所期望的位置(ldd mineonlyret)?是否在您的 ldconfig 缓存中 (ldconfig -p)?
  • 不确定您的 libbpf ELF/BTF 错误。这可能是 clang 和 libbpf 版本之间的兼容性问题,因为它在 lib 解析您的目标文件时命中,在数据实际发送到内核之前(因此独立于内核或 Ubuntu 版本)。但除此之外,我不确定。我的建议是尝试较旧的 libbpf 或更新的 clang。
  • 如果 libbpf 可以继续,您很可能会忽略该错误,BTF 用于调试。见example。如果您想要 BTF,请在编译时使用带有 clang (v8+) 的 -g 标志。你也试过删除-S 标志,它会改变什么吗?如果您有可能,我正在考虑尝试更新版本的 clang(请参阅 LLVM APT repo)而不是旧版本。

标签: c elf bpf ebpf


【解决方案1】:

您需要指定-g 以请求Clang 生成.BTF(它也会生成DWARF 调试信息,但您可以忽略或删除它,它不被libbpf 使用)。虽然 .BTF 最初是用于更好地调试和 BPF 程序集转储的可选附加信息,但它已成为现代 BPF 应用程序(至少那些使用 libbpf 的应用程序)非常需要的部分,因此请确保您始终使用“-g”指定。

【讨论】:

    猜你喜欢
    • 2021-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    相关资源
    最近更新 更多