近期的一个项目上遇到了dlalloc/dlfree有关的crash,logcat里位置不固定,而且call stack缺乏上下文,我的初步判断是内存错误造成的。这种Android native的内存错误比较难办,没有官方的debug工具。如果采取分步隔离的方式排查,“证明没有”比“证明有”困难得多,测试多少次才算是“证明没有”呢?况且如果内存错误有多处,工作量就相当大了。所以绝对不建议采用排查法。到底有没有memory check工具呢?有的,Valgrind就是。
Step by step:
1. 下载valgrind源码(我用的是valgrind-3.8.1)
2. 阅读Readme.android,官方只在Moto Xoom 1和Nexus S上跑通过。我选取的设备是Xoom android4.0.3 root
3. Ubuntu 12.04 32bit PC, NDK下载好(我用的是r8),逐行执行下面语句:
export NDKROOT=/home/xxx/ndk/android-ndk-r8
export HWKIND=nexus_s
cd /home/xxx/valgrind/valgrind-3.8.1
export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar
export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ld
export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc
export CPPFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm -DANDROID_HARDWARE_$HWKIND"
export CFLAGS="--sysroot=$NDKROOT/platforms/android-14/arch-arm"
./configure --prefix=/data/local/Inst --host=armv7-unknown-linux --target=armv7-unknown-linux --with-tmpdir=/sdcard
执行结束后,请务必保证有这句话:Platform variant: android。说明针对android平台做了配置,而不是其他linux平台。如果没有这句话,表示配置有错,不要继续了
4. 执行make -j2,编译valgrind。j2表示目标双核设备。编辑结束能看到valgrind下多了一个目录Inst
5. 新建一个文件val.sh,内容如下4行:
#!/system/bin/sh
VGPARAMS='--error-limit=no'
export TMDIR=/data/data/com.your.package
exec /data/local/Inst/bin/valgrind $VGPARAMS $*
然后chmod 777 val.sh
6. 连接设备到ubuntu,确保adb是通的,确保设备是root过的。执行下面语句
adb push Inst / (把Inst目录push到/data/local/下面)
adb push val.sh /data/local (把val.sh也放到/data/local/下面)
adb shell setprop wrap.com.your.package "logwrapper /data/local/val.sh" (给你的程序设置属性;必须确保adb shell有root权限,否则应先adb shell, su,再setprop)
adb shell
am start -a android.intent.action.MAIN -n com.your.package/.MainActivity (在adb shell下启动你的程序,MainActivity是主启动activity)
7. 等待Valgrind伴着你的应用程序起来,一般要一首歌的功夫,很慢滴。
8. 以上例子在照搬的时候注意有些地方必须修改,比如:valgrind和ndk的路径,your.package的名字, MainActivity的名字;有些地方可以修改,比如:ndk r8, android-14, val.sh的名字等等
后续:当我的程序起来后,简单操作了几遍,valgrind记录下了这中间的mem error。其中有两处mem invalid write,都是由于句柄释放后依旧在使用造成的。代码是平台通用的,win上的boundchecker并没有检查出这个错误,valgrind却发现它了,所以真的要感谢valgrind这个强大的runtime内存扫描工具!没有它,这个麻烦的crash还不知道要多久能解决呢!
阅读(9874) | 评论(1) | 转发(0) |