众所周知,C/C++程序的内存问题较多。Valgrind 是一个用于构建动态分析工具的工具框架。其包含的工具可以自动检测许多内存管理和线程错误,并详细剖析程序。
于是,我希望在海思系列芯片上使用它。编译过程中遇到很多问题,然而一一解决之后却发现 Valgrind 在海思芯片上竟无用武之地。
首先下载源码,解压后使用如下脚本进行编译。需要注意的是
toolchain_dir
为工具链路径;--host
以armv7-
开头;--prefix
为预备置于开发板上的路径;DESTDIR
为编译后的安装路径。脚本执行成功后会在DESTDIR
文件夹下创建--prefix
所指定的路径,并将程序安装到此。
#!/bin/sh
set -e -x
toolchain_dir=/path/to/arm-himix200-linux/arm-himix200-linux
export CC=${toolchain_dir}/bin/arm-himix200-linux-gcc-6.3.0
#export CXX=${toolchain_dir}/bin/arm-himix200-linux-g++
#export CPP=${toolchain_dir}/bin/arm-himix200-linux-cpp
export LD=${toolchain_dir}/bin/arm-himix200-linux-ld
export AR=${toolchain_dir}/bin/arm-himix200-linux-ar
./configure \
--prefix=/mnt/valgrind \
CC=${toolchain_dir}/bin/arm-himix200-linux-gcc-6.3.0 \
CXX=${toolchain_dir}/bin/arm-himix200-linux-g++ \
LD=${toolchain_dir}/bin/arm-himix200-linux-ld \
CPP=${toolchain_dir}/bin/arm-himix200-linux-cpp \
AR=${toolchain_dir}/bin/arm-himix200-linux-ar \
LDFLAGS="-Wl,--rpath=./valgrind,--dynamic-linker=./valgrind/ld-linux.so.3"\
--target=armv7-himix200-linux \
--host=armv7-himix200-linux \
--program-prefix=hisi-
make -j$(nproc)
make -j$(nproc) install DESTDIR=`pwd`/Inst
Valgrind 运行时需要 untripped ld-2.24.so。ld-linux.so.3
是ld-2.24.so
的软链接。Valgrind-3.12.0 - Linux From Scratch! 中给出的方案是进行替换。然而这一操作是危险的,一旦ld-2.24.so
不可用,系统也会随之损坏。
readelf -l hisi-valgrind | grep interpreter
[Requesting program interpreter: /lib/ld-linux.so.3]
脚本中的LDFLAGS
修改 Valgrind 的默认链接器位置,从工具链中的arm-himix200-linux/arm-himix200-linux/target/lib/a7_softfp_neon-vfpv4
文件夹拷贝ld-2.24.so
到valgrind
文件夹并创建软链接:
ln -s ld-2.24.so ld-linux.so.3
在测试应用程序的 CMake 文件中也加入
add_link_options(-Wl,--rpath=./valgrind,--dynamic-linker=./valgrind/ld-linux.so.3)
将valgrind
文件夹拷贝到开发板上并以简单程序进行测试。
#!/bin/bash
export VALGRIND_LIB=valgrind/lib/valgrind
./valgrind/bin/hisi-valgrind --tool=memcheck --leak-check=full --vgdb=no /mnt/test
./valgrind/bin/hisi-valgrind -v --track-origins=yes --tool=memcheck --leak-check=yes --gen-suppressions=yes --num-callers=20 --track-fds=yes --vgdb=no ./test
海思将内存划分成了 OS 内存和 MMZ 内存两部分,Valgrind不能正确识别 MMZ 内存的内存分配,会报出大量的错误:
==23952== Invalid read of size 1
==23952== at 0x591EF7C: strncpy_s (in /mnt/3516_libs/libsecurec.so)
==23952== Address 0xb6e740e1 is not stack'd, malloc'd or (recently) free'd
==23952==
==23952== Invalid read of size 4
==23952== at 0x484CA74: memcpy (vg_replace_strmem.c:1034)
==23952== by 0x591F01B: strncpy_s (in /mnt/3516_libs/libsecurec.so)
==23952== Address 0xb6e740e0 is not stack'd, malloc'd or (recently) free'd
==23952==
虽然可以使用--suppressions
选项进行过滤,但这样一来检查功能残缺不全,效果大打折扣。
file
?