eBPF内存泄露检测-arm64

eBPF内存泄露检测-arm64

视频讲解:

eBPF内存泄露检测-arm64

目标

把之前在x86-64平台上实现的内存泄露检测工具移植到 arm64 平台;

为什么不移植到 arm32 平台?

因为内存泄露检测工具中使用了blazesym开源代码来解析堆栈指令地址的符号名,文件名,行号;但是blazesym开源代码目前不支持 32bit 系统,非常遗憾;

不过也有解决办法,可以参考 bpf-developer-tutorial: https://github.com/eunomia-bpf/bpf-developer-tutorial 的早期版本中 memleak 的代码实现;我就不详细讲了;

arm64 平台

在 ubuntu18.04 上用 qemu 模拟 arm64 平台

Linux (none) 4.19.304 #2 SMP PREEMPT Sun Jan 14 11:23:36 CST 2024 aarch64 GNU/Linux

网上有很多 qemu 模拟 arm64 平台的教程,我就不详细讲了;

需要交叉编译的库

  • libz - - libbpf-bootstrap 需要使用
  • libelf - - libbpf-bootstrap 需要使用
  • blazesym - - 内存泄露检测工具解析堆栈指令地址时使用

安装交叉编译工具链

arm64 交叉编译工具链下载链接:

https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads

# 选择:
x86_64 Linux hosted cross compilers
AArch64 GNU/Linux target (aarch64-none-linux-gnu)

下载后,解压,再 export 出来即可:

# 导出交叉编译工具链
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-
export PATH=$PATH:/home/zhanglong/Desktop/toolchain/arm64

交叉编译 libz

zlib源码下载链接:http://www.zlib.net/

tar -axf zlib-1.3.tar.gz
cd zlib-1.3
export PATH=$PATH:/home/zhanglong/Desktop/toolchain/arm64
export CC=aarch64-none-linux-gnu-gcc
./configure --prefix=$PWD/_install
make
make install
# 当前目录下的_install,就是编译出来的头文件和lib库
# /home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install

交叉编译 libelf

elfutils源码下载链接:https://sourceware.org/elfutils/

tar -axf elfutils-latest.tar.bz2
cd elfutils-0.189
# 参考当前目录下的 INSTALL 文档 和 网上资料
# libelf 使用了之前交叉编译好的 zlib 库,
# 需要 CFLAGS 指定 zlib 库的头文件 和 LDFLAGS 指定 zlib 库路径
./configure --prefix=$PWD/_install --build=x86_64-linux-gnu \
	--host=aarch64-none-linux-gnu \
    CC=aarch64-none-linux-gnu-gcc CXX=aarch64-none-linux-gnu-g++ \
    CFLAGS=-I/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/include \
    LDFLAGS=-L/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/lib \
    LIBS=-lz \
    --disable-nls --disable-rpath --disable-libdebuginfod --disable-debuginfod \
    --with-zlib
make
make install

# 当前目录下的_install,就是编译出来的头文件和lib库
# /home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/elfutils-0.189/_install

交叉编译 blazesym

在之前的视频中讲过 blazesym 依赖的 rust 语言编译环境的安装,就不再重复讲了;

source ~/.cargo/env

# 安装 rust 的交叉编译工具链
rustup target add aarch64-unknown-linux-gnu
# 查看安装好的交叉编译工具链
rustup show

cd libbpf-bootstrap/blazesym/
cd .cargo
mv config config.bak # 不要使用原来的配置文件

touch config.toml
##############################################################
# config.toml 的文件内容
[build]
target = "aarch64-unknown-linux-gnu"

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-none-linux-gnu-gcc"
##############################################################
cd ../
cargo build --release

交叉编译 memleak

如果系统自带的 clang 编译器版本过低,

编译之前需要先修改: libbpf-bootstrap/examples/c/Makefile 文件,指定 clang 编译器:

CLANG ?= clang
# 改为:
CLANG ?= /your-clang-version/clang  # your-clang-version 指的是自己下载的clang版本
# /home/zhanglong/Desktop/clang-16/clang

交叉编译命令:

# export 交叉编译工具链的路径
export PATH=$PATH:/home/zhanglong/Desktop/toolchain/arm64

make ARCH=arm64 CROSS_COMPILE=aarch64-none-linux-gnu- \
	EXTRA_CFLAGS="-I/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/include -I/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/elfutils-0.189/_install/include" \
	EXTRA_LDFLAGS="-L/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/lib -L/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/elfutils-0.189/_install/lib" \
	memleak V=1

为了编译方便,可以写一个shell脚本配置编译环境:

build_env.sh

#!/bin/sh
export PATH=$PATH:/home/zhanglong/Desktop/toolchain/arm64
export ARCH=arm64
export CROSS_COMPILE=aarch64-none-linux-gnu-

# 用 EXTRA_CFLAGS 指定 zlib 和 libelf 库的头文件路径
export EXTRA_CFLAGS="-I/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/include -I/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/elfutils-0.189/_install/include"

# 用 EXTRA_LDFLAGS 指定 zlib 和 libelf 的库路径
export EXTRA_LDFLAGS="-L/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/zlib-1.3/_install/lib -L/home/zhanglong/Desktop/ebpf/note/src/arm64/extra_libs/elfutils-0.189/_install/lib"

交叉编译时先执行一次: source build_env.sh

之后就可以简单执行:make clean; make memleak

拷贝x86-64平台上实现的内存泄露检测工具代码

因为这次 arm64 使用的内核版本是 4.19.304,还不支持 BTF,

所以memleak.bpf.c不能直接包含 #include "vmlinux.h",需要手动定义如下的数据类型才能编译通过,

下面的数据类型定义都是从 libbpf-bootstrap/vmlinux/arm64/vmlinux.h 文件中拷贝过来,并简单修改;

#define BPF_NO_GLOBAL_DATA
#include <linux/bpf.h>

typedef __u32 u32;
typedef __u64 u64;
typedef int pid_t;
typedef long unsigned int size_t;

struct user_pt_regs {
    __u64 regs[31];
    __u64 sp;
    __u64 pc;
    __u64 pstate;
};

struct pt_regs {
    union {
        struct user_pt_regs user_regs;
        struct {
            __u64 regs[31];
            __u64 sp;
            __u64 pc;
            __u64 pstate;
        };
    };
    __u64 orig_x0;
    __s32 syscallno;
    __u32 unused2;
    __u64 sdei_ttbr1;
    __u64 pmr_save;
    __u64 stackframe[2];
    __u64 lockdep_hardirqs;
    __u64 exit_rcu;
};

修改:libbpf-bootstrap/examples/c/Makefile

# BZS_APPS 加上 memleak 编译目标
BZS_APPS := profile memleak
###################################################################################
$(LIBBLAZESYM_SRC)/target/release/libblazesym.a::
	$(Q)cd $(LIBBLAZESYM_SRC) && $(CARGO) build --release

$(LIBBLAZESYM_OBJ): $(LIBBLAZESYM_SRC)/target/release/libblazesym.a | $(OUTPUT)
	$(call msg,LIB, $@)
	$(Q)cp $(LIBBLAZESYM_SRC)/target/release/libblazesym.a $@

###### 改为:
$(LIBBLAZESYM_SRC)/target/aarch64-unknown-linux-gnu/release/libblazesym.a::
	$(Q)cd $(LIBBLAZESYM_SRC) && $(CARGO) build --release

$(LIBBLAZESYM_OBJ): $(LIBBLAZESYM_SRC)/target/aarch64-unknown-linux-gnu/release/libblazesym.a | $(OUTPUT)
	$(call msg,LIB, $@)
	$(Q)cp $(LIBBLAZESYM_SRC)/target/aarch64-unknown-linux-gnu/release/libblazesym.a $@

内核需要打开ebpf相关的配置选项

ebpf 内核配置选项 (linux-4.19.304):

General setup  --->
	[*] Enable bpf() system call
	[*]   Permanently enable BPF JIT and remove BPF interpreter

General architecture-dependent options  --->
	[*] Kprobes

Kernel hacking  --->
	[*] Tracers  --->
		[*]   Enable kprobes-based dynamic events (NEW)
		[*]   Enable uprobes-based dynamic events (NEW)
Kylin-arm64是一个针对ARM64架构的操作系统,它是中国自主研发的开源操作系统项目。kylin-arm64是基于Kylin操作系统的ARM64版本,旨在为ARM64架构的设备提供稳定、安全和高效的操作系统。 kylin-arm64的开发目标是能够在ARM64架构的硬件平台上运行,并支持多种不同类型的应用程序。它可以应用于手机、平板电脑、物联网设备以及服务器等领域。 kylin-arm64具有以下特点: 1. 高性能:kylin-arm64经过优化,能够充分利用ARM64架构的优势,提供高性能的计算能力和响应速度。 2. 安全性:kylin-arm64采用多种安全措施,包括安全启动、权限控制等,保证用户数据的安全和隐私的保护。 3. 稳定性:kylin-arm64经过严格的测试和验证,能够保持系统的稳定运行,减少崩溃和错误的发生。 4. 兼容性:kylin-arm64兼容ARM64架构的硬件设备,并支持多种应用程序和软件库。它可以运行基于Android的应用程序,同时还支持Linux上常用的开发工具和框架。 5. 可定制性:kylin-arm64的设计允许用户根据自己的需求进行定制和扩展。用户可以根据自己的应用场景,选择不同的功能模块和驱动程序。 总之,kylin-arm64是一个全面支持ARM64架构的功能强大的操作系统,它为ARM64设备提供了稳定、安全和高效的运行环境。该操作系统具有高性能、安全性、稳定性、兼容性和可定制性等优势,适用于多种应用场景和领域。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值