为 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.exeexport LD=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ld.exeexport 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' failedmake[1]: *** [install-recursive] Error 1make[1]: Leaving directory '/cygdrive/e/sources/valgrind-3.9.0'Makefile:990: recipe for target 'install' failedmake: *** [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 到设备上运行,根据出错信息找缺失的文件……不过还是相当值得,利器在手啦。

更多相关文章

  1. cocos2d-x 2.x版本之win32 window移植android 环境搭配 只用NDK
  2. android程序目录结构及分析
  3. Android布局优化之Include(一)
  4. Android(安卓)文件读写操作方法总结
  5. 关于Renderscript的理解
  6. 对android里布局文件当中的TextView对象设置事件监听,但是不响应
  7. Android之Adapter用法总结
  8. android中AVD的使用
  9. NPM 和webpack 的基础使用

随机推荐

  1. Android(安卓)开发遇坑备忘录(二)
  2. Android(安卓)访问FTP 服务器,实现文件的
  3. android studio 报错 non-zero exit valu
  4. Android(安卓)TextView 自动换行问题
  5. Android(安卓)MVVM架构模式 详解和综合运
  6. Android(安卓)中实现分享和第三方登陆---
  7. Android线程安全问题总结
  8. Android[学习] UI优化方案
  9. android四大组件之Service服务之总体概述
  10. android冷启动与热启动面试知识小结