Chinaunix首页 | 论坛 | 博客
  • 博客访问: 161212
  • 博文数量: 19
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 722
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-12 14:11
个人简介

而立之年,一事无成。

文章分类

全部博文(19)

文章存档

2016年(1)

2014年(4)

2013年(14)

我的朋友

分类: Android平台

2013-10-09 15:22:46

近期的一个项目上遇到了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还不知道要多久能解决呢!



阅读(9801) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

lihansey2014-06-09 11:22:28

我已成功在android 跑起来
valgrind也帮我找出  Invalid write of size 4 之类的内存错误

但是, 它没有详细显示 :  哪个c文件的具体行数 line number, 只是显示在某个 .so里面 , 请问大神怎么解决?? 我想要的是具体位置!!!!


06-09 11:09:38.825: I/valgrind_wrapper.sh(9943): ==9944==    at 0x14D94CC8: Java_com_example_hellojni_HelloJni_stringFromJNI (in /data/data/com.example.hellojni/lib/libxo-jni.so)
06-09 11:09:38.825: I/valgrind_wrapper.sh(9943): ==9944==  Addre