valgrind的使用
下载 Valgrind 源码
wget https://sourceware.org/pub/valgrind/valgrind-3.22.0.tar.bz2
tar -xvf valgrind-3.22.0.tar.bz2 cd valgrind-3.22.0
交叉编译
# Valgrind 3.22.0 ARM64 静态编译指南 ## 概述 本文档详细介绍如何使用 `aarch64-linux-gnu-gcc` 交叉编译工具链,将 Valgrind 3.22.0 编译为 ARM64 架构的静态可执行文件,并创建可移植包以便在 ARM 开发板上使用。 --- ## 1. 环境准备 ### 1.1 检查交叉编译工具链 ```bash aarch64-linux-gnu-gcc --version # 输出示例: # aarch64-linux-gnu-gcc (Linaro GCC 7.5-2019.12) 7.5.0 ``` ### 1.2 获取 Valgrind 源码 ```bash # 假设源码已解压到以下目录 cd /home/shanghaojie/work/Third/valgrind-3.22.0 ``` --- ## 2. 编译步骤 ### 2.1 配置编译选项 ```bash # 清理之前的配置(如果有的话) make distclean # 配置交叉编译 ./configure \ --host=aarch64-linux-gnu \ --prefix=/home/shanghaojie/work/Third/valgrind-arm-static \ CC=aarch64-linux-gnu-gcc \ CXX=aarch64-linux-gnu-g++ \ CFLAGS=-static \ LDFLAGS=-static ``` **配置说明:** - `--host=aarch64-linux-gnu`: 指定目标架构为 ARM64 - `--prefix`: 指定安装路径 - `CC/CXX`: 指定交叉编译工具链 - `CFLAGS/LDFLAGS=-static`: 启用静态链接 ### 2.2 执行编译 ```bash make -j$(nproc) ``` 编译成功后会生成以下关键文件: - `coregrind/valgrind` - 主程序 - `memcheck/memcheck-arm64-linux` - Memcheck 工具 - `cachegrind/cachegrind-arm64-linux` - Cachegrind 工具 - `callgrind/callgrind-arm64-linux` - Callgrind 工具 - `helgrind/helgrind-arm64-linux` - Helgrind 工具 - `massif/massif-arm64-linux` - Massif 工具 --- ## 3. 创建可移植包 Valgrind 需要特定的目录结构才能正常工作,主程序需要知道工具的位置。 ### 3.1 创建目录结构 ```bash mkdir -p /tmp/valgrind-arm-portable/{bin,lib/valgrind} ``` ### 3.2 复制核心文件 ```bash # 主程序 cp coregrind/valgrind /tmp/valgrind-arm-portable/bin/ cp auxprogs/valgrind-listener /tmp/valgrind-arm-portable/bin/ cp auxprogs/valgrind-di-server /tmp/valgrind-arm-portable/bin/ # 工具模块 cp memcheck/memcheck-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ cp memcheck/vgpreload_memcheck-arm64-linux.so /tmp/valgrind-arm-portable/lib/valgrind/ cp cachegrind/cachegrind-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ cp callgrind/callgrind-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ cp helgrind/helgrind-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ cp helgrind/vgpreload_helgrind-arm64-linux.so /tmp/valgrind-arm-portable/lib/valgrind/ cp massif/massif-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ cp massif/vgpreload_massif-arm64-linux.so /tmp/valgrind-arm-portable/lib/valgrind/ cp drd/drd-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ 2>/dev/null || true cp drd/vgpreload_drd-arm64-linux.so /tmp/valgrind-arm-portable/lib/valgrind/ 2>/dev/null || true cp lackey/lackey-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ 2>/dev/null || true cp dhat/dhat-arm64-linux /tmp/valgrind-arm-portable/lib/valgrind/ 2>/dev/null || true # 支持文件 cp default.supp glibc-2.X.supp glibc-2.X-drd.supp glibc-2.X-helgrind.supp \ xfree-3.supp xfree-4.supp /tmp/valgrind-arm-portable/lib/valgrind/ ``` ### 3.3 打包压缩 ```bash cd /tmp tar czvf valgrind-arm-portable.tar.gz valgrind-arm-portable/ ``` --- ## 4. 可移植包目录结构 ``` valgrind-arm-portable/ ├── bin/ # 可执行文件 │ ├── valgrind # 主程序(静态编译) │ ├── valgrind-di-server # 调试信息服务器 │ └── valgrind-listener # 远程监听器 └── lib/ └── valgrind/ # 工具模块目录 ├── memcheck-arm64-linux # 内存错误检测 ├── vgpreload_memcheck-arm64-linux.so ├── cachegrind-arm64-linux # 缓存性能分析 ├── callgrind-arm64-linux # 调用图分析 ├── helgrind-arm64-linux # 线程竞争检测 ├── vgpreload_helgrind-arm64-linux.so ├── massif-arm64-linux # 堆内存分析 ├── vgpreload_massif-arm64-linux.so ├── drd-arm64-linux # 数据竞争检测 ├── vgpreload_drd-arm64-linux.so ├── dhat-arm64-linux # 内存分配分析 ├── lackey-arm64-linux # 跟踪工具 ├── default.supp # 默认抑制文件 ├── glibc-2.X.supp # glibc 抑制文件 ├── glibc-2.X-drd.supp ├── glibc-2.X-helgrind.supp └── xfree-3.supp / xfree-4.supp ``` --- ## 5. 在 ARM 板上使用 ### 5.1 传输到 ARM 板 ```bash # 使用 scp 传输压缩包 scp /tmp/valgrind-arm-portable.tar.gz root@<ARM板IP>:/opt/ # 在 ARM 板上解压 ssh root@<ARM板IP> "cd /opt && tar xzvf valgrind-arm-portable.tar.gz" ``` ### 5.2 设置环境变量 ```bash # 方法一:设置环境变量 export VALGRIND_LIB=/opt/valgrind-arm-portable/lib/valgrind # 方法二:使用 --lib 选项(每次运行时指定) /opt/valgrind-arm-portable/bin/valgrind --lib=/opt/valgrind-arm-portable/lib/valgrind ``` ### 5.3 常用命令示例 ```bash # 1. 查看版本 /opt/valgrind-arm-portable/bin/valgrind --version # 2. 检测内存泄漏(最常用) /opt/valgrind-arm-portable/bin/valgrind --leak-check=full ./your_program # 3. 显示详细的内存泄漏信息 /opt/valgrind-arm-portable/bin/valgrind \ --leak-check=full \ --show-leak-kinds=all \ --track-origins=yes \ ./your_program # 4. 使用 cachegrind 分析缓存性能 /opt/valgrind-arm-portable/bin/valgrind --tool=cachegrind ./your_program # 5. 使用 callgrind 分析函数调用 /opt/valgrind-arm-portable/bin/valgrind --tool=callgrind ./your_program ``` --- ## 6. 常见问题 ### 6.1 "failed to start tool 'memcheck' for platform 'arm64-linux': No such file or directory" **原因**:Valgrind 主程序找不到工具模块 **解决方法**: - 确保 `VALGRIND_LIB` 环境变量指向正确的工具目录 - 或使用 `--lib` 参数指定工具路径 - 确保工具文件名格式正确(如 `memcheck-arm64-linux`) ### 6.2 "exec format error" **原因**:在错误的架构上运行(如在 x86_64 主机上直接运行 ARM64 程序) **解决方法**: - 必须在 ARM64 架构的设备上运行 - 或使用 QEMU 进行模拟:`qemu-aarch64 ./valgrind` ### 6.3 静态编译优势 静态编译的 Valgrind 不需要目标系统上安装特定版本的 glibc,适合: - 嵌入式 Linux 环境 - 精简的根文件系统 - 不同 glibc 版本的系统 --- ## 7. 工具说明 | 工具名称 | 功能描述 | |---------|---------| | **memcheck** | 检测内存泄漏、越界访问、使用未初始化内存等 | | **cachegrind** | 分析 CPU 缓存使用情况 | | **callgrind** | 分析函数调用图和执行时间 | | **helgrind** | 检测线程间的数据竞争 | | **massif** | 分析堆内存分配情况 | | **drd** | 检测数据竞争(另一个实现) | | **lackey** | 简单的指令级跟踪工具 | | **dhat** | 检测内存使用热点 | --- **文档版本**: v1.0 **创建日期**: 2026年5月 **适用版本**: Valgrind 3.22.0移植到设备中
# 基本内存泄漏检测
valgrind --leak-check=full ./camera_vehicle
# 详细内存检测(含内存访问错误)
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./camera_vehicle
# 生成报告文件
valgrind --leak-check=full --log-file=valgrind_report.txt ./camera_vehicle
备注:
Valgrind 作为动态二进制插桩工具, 需要拦截目标程序调用的 libc 函数 (如 strlen )。为了实现这一点,Valgrind 需要动态链接器 ( ld-linux-aarch64.so.1 ) 导出这些函数符号。
当动态链接器被 stripped(剥离符号)后,Valgrind 无法找到这些符号,导致启动失败。
也就是 你的程序依赖的so 不能strip
