• datadog ebpf模块 offset-guess.o 问题排查解决


    解决好公司的好问题,一直是自己从业的准则,我认为这是一件十分幸福的事情。

    一、定位问题

    datadog system-probe 模块打开network-tracer后出现问题:

    ERROR | (cmd/system-probe/api/module/loader.go:60 in Register) | new module `network_tracer` error: error guessing offsets: could not load bpf module for offset guessing: load BTF maps: section .maps: map tracer_status already exists

    offset-guess.o 模块是偏移量猜想的一个模块,我估计datadog这么做的原因是处于linux内核兼容性的原因,但是这种兼容性的代码为什么会在这里出现问题呢?

    查找代码位置,出现问题位置:

    1. if err := ec.loadBTFMaps(maps); err != nil {
    2. return nil, fmt.Errorf("load BTF maps: %w", err)
    3. }

    loadBTFMaps

    1. v, ok := vs.Type.(*btf.Var)
    2. if !ok {
    3. return fmt.Errorf("section %v: unexpected type %s", sec.Name, vs.Type)
    4. }
    5. name := string(v.Name)
    6. // The BTF metadata for each Var contains the full length of the map
    7. // declaration, so read the corresponding amount of bytes from the ELF.
    8. // This way, we can pinpoint which map declaration contains unexpected
    9. // (and therefore unsupported) data.
    10. _, err := io.Copy(internal.DiscardZeroes{}, io.LimitReader(rs, int64(vs.Size)))
    11. if err != nil {
    12. return fmt.Errorf("section %v: map %s: initializing BTF map definitions: %w", sec.Name, name, internal.ErrNotSupported)
    13. }
    14. if maps[name] != nil {
    15. return fmt.Errorf("section %v: map %s already exists", sec.Name, name)
    16. }

    会发现出现这个问题是因为btf里面的ebpf的.maps 出现了两次,那么我进一步定位elf文件看下里面的.maps情况

    readelf -x .maps -r  /opt/datadog-agent/embedded/share/system-probe/ebpf/offset-guess.o

    发现.maps出现了两次,正常情况下不应该这样

    1. Hex dump of section '.maps':
    2. 0x00000000 00000000 00000000 00000000 00000000 ................
    3. 0x00000010 00000000 00000000 00000000 00000000 ................
    4. 0x00000020 00000000 00000000 ........
    5. Hex dump of section '.maps':
    6. 0x00000000 00000000 00000000 00000000 00000000 ................
    7. 0x00000010 00000000 00000000 00000000 00000000 ................
    8. 0x00000020 00000000 00000000 ........

    定位到出问题的文件是/opt/datadog-agent/embedded/share/system-probe/ebpf/offset-guess.o

    进一步这个文件出问题的阶段可能是在编译时期,那么我们回顾ebpf 模块的整个编译周期,发现有一个错误出现了

    1. [19/33] clang -MD -MF pkg/ebpf/bytecode/build/offset-guess-debug.bc.d -emit-llvm -D__KERNEL__ -DCONFIG_64BIT -D__BPF_TRACING__ -DKBUILD_MODNAME=\"ddsysprobe\" -Wno-unused-value -Wno-pointer-sign -Wno-compare-distinct-pointer-types -Wunused -Wall -Werror -include pkg/ebpf/c/asm_goto_workaround.h -O2 -fno-stack-protector -fno-color-diagnostics -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-jump-tables -fmerge-all-constants -Ipkg/ebpf/c -isystem/usr/src/linux-headers-5.15.0-52-generic/include -isystem/usr/src/linux-headers-5.15.0-52-generic/include/uapi -isystem/usr/src/linux-headers-5.15.0-52-generic/include/generated/uapi -isystem/usr/src/linux-headers-5.15.0-52-generic/arch/x86/include -isystem/usr/src/linux-headers-5.15.0-52-generic/arch/x86/include/uapi -isystem/usr/src/linux-headers-5.15.0-52-generic/arch/x86/include/generated -Ipkg/network/ebpf/c -g -DDEBUG=1 -c pkg/network/ebpf/c/prebuilt/offset-guess.c -o pkg/ebpf/bytecode/build/offset-guess-debug.bc
    2. [20/33] cd pkg/network/http && CC=clang go tool cgo -godefs -- -fsigned-char http_types.go | go run /home/zhanglei/data/datadog-agent/pkg/ebpf/cgo/genpost.go > http_types_linux.go
    3. cgo-builtin-prolog:1:10: fatal error: 'stddef.h' file not found
    4. #include <stddef.h> /* for ptrdiff_t and size_t below */

    看到这个错误一切就变得非常简单了,意味着clang 版本很低和操作系统并不兼容,因为data-dog依赖genpost生成cgo文件,用于运行时编译

    datadog里面的system-probe 使用的clang版本是12明显和主机的不兼容,断定关键点的位置:

    1. if clang_version_str != CLANG_VERSION:
    2. # download correct version from dd-agent-omnibus S3 bucket
    3. clang_url = f"https://dd-agent-omnibus.s3.amazonaws.com/llvm/clang-{CLANG_VERSION}.{arch}"
    4. ctx.run(f"{sudo} wget -q {clang_url} -O /opt/datadog-agent/embedded/bin/clang-bpf")
    5. ctx.run(f"{sudo} chmod 0755 /opt/datadog-agent/embedded/bin/clang-bpf")
    6. if llc_version_str != CLANG_VERSION:
    7. llc_url = f"https://dd-agent-omnibus.s3.amazonaws.com/llvm/llc-{CLANG_VERSION}.{arch}"
    8. ctx.run(f"{sudo} wget -q {llc_url} -O /opt/datadog-agent/embedded/bin/llc-bpf")
    9. ctx.run(f"{sudo} chmod 0755 /opt/datadog-agent/embedded/bin/llc-bpf")

    datadog运行的clang版本是12,但是和我主机不兼容

    二、解决问题

    我是ubuntu系统,所以我只需要安装和我主机兼容的clang 和llvm版本就行了

    apt install clang

    我安装的是clang-14,所以我需要把/usr/bin下面的clang 替换为和我的主机兼容的

    cp /usr/bin/clang-14 /usr/bin/clang

    重新编译datadog的system-probe模块

    invoke system-probe.build

    发现没有任何报错,再次运行system-probe ,没有任何报错,发现ebpf层的网络数据可以正常采集了

  • 相关阅读:
    Docker搭建Sentinel 控制台环境搭建及使用介绍
    【环形链表】
    阿里云Linux中安装MySQL,并使用navicat连接以及报错解决
    TDK | EMC是什么?
    Mybatis04(关联关系映射)
    Linux 网络配置 01
    【小程序自动化Minium】一、框架介绍和环境搭建
    【图像分割】图像检测(分割、特征提取)、各种特征(面积等)的测量和过滤(Matlab代码实现)
    Android优化篇|网络预连接
    PostgreSQL性能调优:优化查询和索引设计
  • 原文地址:https://blog.csdn.net/qq_32783703/article/details/127690233