Android Valgring检测Native内存泄漏

3/3/2017来源:C/C++教程人气:2016

说明:

Native内存泄漏 --- 泛指底层库文件中的代码存在的内存泄漏,在我们的项目里是指   NavSDK底层so文件中存在的内存泄漏 .

 

Valgrind --- 一款开源的跨平台的支持多种语言的描绘和检测内存操作相关问题的监 测工具 , 在我们的项目目前只检测内存泄漏 ,内存操作错误以及调用堆栈 .

 

使用流程 --- 通过NDK交叉编译把Android版的Valgrind 编译好并拷贝到Android设 备的某目录下, 在Android 设备的某个目录下编写一个sh脚本,在这个脚 本中去设置Valgrind的内存检测参数和启动Valgrind , 最后设置App的启 动配置项 , 让App在启动的同时调用之前编写的sh脚本 .

 

前提条件 --- 一个已经root了的Android 设备 , 一个已经用NDK交叉编译好了的 Valgrind (编译过程参考Valgrind源码目录下的README.android)

 

注意事项 --- Valgrind检测的库文件必须是带调试符号的库文件才能看到行信息和调 用堆栈 , 而在一般我们在Eclipse开发的Native项目中,虽然我们使用的是ndk-build NDK_DEBUG=1 , 但是我们的App打包到Android 系统里的 so文件并不是有调试符号的 ,因为Android Native调试是基于gdb-server 和gdb-client 这种CS模式的 . 有调试符号的so文件是放在里本地系统 的PRoject/obj/local/armeabi/下,而打包进apk的是libs/armeabi/下的so文件, 这些so文件是不带调试符号的. 所以我们必须用有符号的so文件替换掉 无符号的so文件 . 详细步骤后面会说明 .

操作:

1 准备 

root一台Android设备 , SVN check Valgrind 源代码 , 参考README.android 用NDK交叉编译Valgrind 并拷贝到Android /data/local/目录下

其中Inst是交叉编译后会产生的一个文件夹 

 

2 设置

在/data/local目录下编写一个sh脚本 .内容:

#!/system/bin/sh

VGPARAMS='--leak-check=yes --trace-children=yes --num-callers=100 --log-file=/sdcard/valgrind.log'

export TMPDIR=/data/data/com.msd.followme

exec /data/local/Inst/bin/valgrind $VGPARAMS $*

 

其中VGPARAMS是valgrind的设置参数 参数解释参考官方文档

http://valgrind.org/docs/manual/manual-core.html#manual-core.options

 

修改val.sh的控制权限 :

命令 : chmod 777 val.sh 

 

已经找到启动apk的方法,把apk的启动包装一下即可: setprop wrap.pakeage名 "logwrapper /data/local/val.sh"

修改 com.msd.followme的启动项 ,让它启动的时候去调用val.sh 并且把日志输出的logcat

命令 : setprop wrap.com.msd.followme “logwrapper  /data/local/val.sh”

 

验证设置启动项是否设置成功:打印出 ” /data/local/val.sh ” 则设置成功, 否则失败.

命令 : echo $(getprop wrap.com.msd.followme) 

 

 

3 使用

在eclipse中run as Android Appllication 我们的followme项目,在followme项目的apk 成功部署到Android 设备并启动主Activity后 ,退出followme应用 ,然后

 

替换无符号的so文件 (其中的 /project 应为我们的NavSDK项目根目录)

 

使用adb 把/project/obj/local/armeabi/下的带调试符号的so文件拷贝到Android sdcard/ 下

命令 : adb push /project/obj/local/armeabi/ /sdcard/lib/ 

在Android 下使用root shell (因为只有root权限才能对data/data/下的文件进行读写)

命令androidShell #: cp -p /sdcard/lib/ /data/data/com.msd.followme/

到此 , com.msd.followme 下的so文件已经被替换成带调试符号的so文件

 

可以通过ls -al 命令查看so文件大小来判断是否替换成功 ,带符号的so文件会比无符号的大很多 .

 

 

替换成功后我们使用adb shell 启动followme的主Activity 

命令 : adb shell start -a android.intent.action.MAIN -n   com.msd.followme/.ui.FMAppStartActivity

 

启动成功后就可以进行测试需要测试的功能模块了, 测试完成后推出整个followme应用,此时Valgrind的会将Native内存使用情况的描述和总结输出到/sdcard/valgrind.log中,使用adb shell 可以将日志文件pull到本地系统里面来,方便查看

命令 : adb pull /sdcard/valgrind.log  /root/            ( windows下改其他盘符 )

 

通过查看valgrind.log 就能知道哪些地方存在内存操作错误和调用堆栈了

转自:http://blog.csdn.net/wangliang198901/article/details/12856027

其他相关链接:http://stackoverflow.com/questions/9123124/how-to-start-an-android-app-with-valgrind

http://www.educity.cn/wenda/158843.html