为 Android 开发了一个 native 程序,使用 C 语言。测试时观察内存占用,发现有内存泄漏。之前在 Linux 下使用过 valgrind ,于是想针对 Android 平台编译一个 Valgrind 版本,用来检测我的 native 程序。
我的开发环境是 Windows 7,决定使用 Cygwin 来编译。
Cygwin 的具体安装不多说了,注意的是,一些开发工具必须选择,比如 gcc 、 autoconf 、 automake 等等。
Valgrind 最新的 release 版本是 3.9.0 ,官网下载。下载后解压,阅读源码根目录下的 README.android 文件,先有个初步了解。
使用 Cygwin 来编译 Valgrind 和在 Linux 环境下编译还是有一些差别。我已经编译通过并正常使用。首先进入 Cygwin 的 shell ,然后,下面是详细的步骤。
(一)设置 NDK 路径
命令很简单,export NDKROOT=E:/android-ndk-r8d (替换为你开发主机上的实际路径)。
需要注意的是,这里的 NDKROOT 不能用 Cygwin 挂载的路径 /cygdrive/e/xxx 这种形式,否则 configure 时检测工具链是否可以生成可执行文件时会找不到 ctrbegin_dynamic.o 及 C 库,导致 configure 失败。这个花费了我将近一个小时的时间!
(二)设置硬件型号
export HWKIND=generic
我设置了上面的类型,实际应用中可以和具体的目标设备关联起来。
(三)设置工具链
这里和 README.android 稍有不同。具体如下:
export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ar.exe
export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ld.exe
export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-gcc.exe
(四)配置( configure )
先进入到 valgrind 源码根目录。
找到 configure 文件,做一些修改,否则 configure 会失败。因为 configure 会检测编译主机内核版本,Cygwin 的 uname -r 返回的版本不是 Linux 内核版本号,我的环境返回是 1.7.28(0.271/5/3) 。找到 5508 行,修改成下面的样子(在2.6.*前加入了1.7.*):
case "${kernel}" in
1.7.*|2.6.*|3.*)
这样内核版本检测才会通过。
配置选项还要做一些修改,这里和 README.android 稍有不同,我添加 LIBS 选项,修改了 --target 。具体如下:
CPPFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm -DANDROID_HARDWARE_$HWKIND" \
CFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm" \
LIBS="-L$NDKROOT/platforms/android-14/arch-arm/usr/lib" \
./configure --prefix=/data/local/Inst --host=armv7-unknown-linux \
--target=arm-linux-androideabi --with-tmpdir=/sdcard
(五)
编译
执行 make ,就这么简单了,我这里通过了。
(六)安装
make install ,这里会失败。我的错误信息如下:
make[2]: Entering directory '/cygdrive/e/sources/valgrind-3.9.0/VEX'
priv/.deps/libvex_arm_linux_a-host_s390_defs.Po:1: *** 多个目标匹配。 停止。
make[2]: Leaving directory '/cygdrive/e/sources/valgrind-3.9.0/VEX'
Makefile:665: recipe for target 'install-recursive' failed
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory '/cygdrive/e/sources/valgrind-3.9.0'
Makefile:990: recipe for target 'install' failed
make: *** [install] Error 2
我没有搭理它,因为我发现 valgrind 和 memcheck 已经编译出来,决定放到目标设备上跑跑看,一跑,成功了!
实际上为了做内存检测,需要 valgrind 、memcheck 、default.supp 、vgpreload_core-arm-linux.so 、vgpreload_memcheck-arm-linux.so 这五个文件, push 到设备上即可。
(六)运行
像上面那样 push 程序到设备上,要想运行,必须设置一个环境变量VALGRIND_LIB ,valgrind 会根据这个环境变量来查找要加载的工具,如 memcheck 等,否则会报错,找不到文件。
现在可以这么启动目标程序了:
/data/data/valgrind/valgrind --leak-check=full --track-origins=yes --log-file=check.log your-target-executable
我们把日志输出到 check.log 文件中,方便查看。
------------
好啦,到现在为止, valgrind for android 已经可以使用了。
整个过程花了我 2 个多小时,对着 Cygwin 下面的报错,查看 config.log ,修改命令,修改 configure ,push 到设备上运行,根据出错信息找缺失的文件……不过还是相当值得,利器在手啦。
分享到:
相关推荐
亲测可以正常使用的valgrind在android板子上使用,对于需要用valgrind检测内存泄漏等问题的开发者有参考价值。
Linux 系统中valgrind检查内存泄露说明和安装包,只是简单的说明,使用方法说明中只是说明了一种检测内存泄漏问题的方法和语句
valgrind源码 内存泄露 内存检测 工具
在linux下使用内存检测工具valgrind对程序进行内存泄露检测及绘制函数调用关系。
arm环境内存泄漏检测工具valgrind,用于检测arm环境下的内存泄漏
valgrind for android NDK, 由国外相关资源整理,并亲测试可用,只支持 arm 架构.
Linux系统中valgrind检查内存泄露.rar
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。Valgrind这个名字取自北欧神话中英灵殿的入口。 Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届...
valgrind,内存检查工具,用于内存泄漏的检查
预先编译好的Android平台Valgrind工具,亲测可用。
linux平台下内存泄漏检测工具valgrind3.11
内存泄漏工具 使用命令例子,xxx为执行文件 可执行文件目录下执行: valgrind --leak-check=full --show-leak-kinds=all --log-file=log ./xxx 执行后的信息在log文件里。(路径:与exe相同)
详细说明了如何在ROOTED设备上自动检测内存管理,线程错误和配置Android应用程序的说明。 连接到Android设备 $ adb connect [device_ip] 转到Android Valgrind的文件夹 $ cd [android-valgrind] 在设备上安装...
Valgrind是一款用于内存调试、内存泄漏检测以及性能分析的软件开发工具。 内含中文手册,说明如何安装及使用
valgrind-3.19.0 内存检测工具 aarch64 6.5.0交叉编译移植版本
内存检查工具valgrind 的使用方法,通过valgrind 可以检查程序中的内存情况。
防止内存泄露 Linux下用Valgrind做检查 C语言
介绍algrind的安装与使用方法,通过对内存错误的各种出错信息的认识,帮助使用者正确使用valgrind工具。是在ubuntu上编辑的,请在ubuntu上打开 参考:https://blog.csdn.net/u012662731/article/details/78652651 ...
介绍了使用内存泄漏检测工具valgrind的安装和使用,内附安装包,测试程序,使用说明文档。
valgrind是一款运行在linux下的,用来定位c/c++程序中内存使用方面的错误的工具,包括:内存泄漏、使用未初始化的内存、读/写已释放的内存、读/写内存越界、使用malloc/new/new[]和free/delete/delete[]不匹配,等等...