使用ndk-stack追踪程序崩溃

http://mogoweb.net/categories/android-ndk

2011年9月1日 alex 3 条评论

程序崩溃无疑是程序员最头疼的事情,而android native程序崩溃简直是令程序员崩溃。Android java程序在异常之前还打印出代码调用栈,让程序员有迹可寻,结合单步调试,定位问题相对容易些。而native程序崩溃,只会打印出一段天书,让人摸不着头脑。比如,下面就是一段native程序异常后,在logcat中打印出的信息:

09-01 07:20:39.170: INFO/DEBUG(31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 
09-01 07:20:39.170: INFO/DEBUG(31): Build fingerprint: ‘generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys’ 
09-01 07:20:39.180: INFO/DEBUG(31): pid: 339, tid: 347  >>> mogoweb.browser.app <<< 
09-01 07:20:39.180: INFO/DEBUG(31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr bbadbeef 
09-01 07:20:39.180: INFO/DEBUG(31):  r0 00000093  r1 ffffff1c  r2 00000000  r3 bbadbeef 
09-01 07:20:39.180: INFO/DEBUG(31):  r4 0029d378  r5 0029d2c0  r6 00000000  r7 43eaeeb4
09-01 07:20:39.180: INFO/DEBUG(31):  r8 43fcdb4c  r9 43eaeea8  10 43eaee90  fp 43fcda3c 
09-01 07:20:39.180: INFO/DEBUG(31):  ip 00000029  sp 43fcda28  lr 822d6ee8  pc 822d6ef0  cpsr 00000010 
09-01 07:20:39.270: INFO/ActivityManager(61): Displayed mogoweb.browser.app/.BrowserActivity: +1s98ms 
09-01 07:20:39.669: INFO/DEBUG(31):          #00  pc 002d6ef0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.669: INFO/DEBUG(31):          #01  lr 822d6ee8  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.669: INFO/DEBUG(31): code around pc: 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ed0 e08f3003 e1a02003 e59f3038 e08f3003 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ee0 eb2a28bf eb2a290b e59f302c e3a02000 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ef0 e5832000 e3a03000 e12fff33 e51b3008 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6f00 e1a00003 e24bd004 e8bd8800 0173faf0 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6f10 00cea68c 00cec48c 00cea6c0 bbadbeef 
09-01 07:20:39.669: INFO/DEBUG(31): code around lr: 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ec8 e3a01040 e59f3040 e08f3003 e1a02003 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ed8 e59f3038 e08f3003 eb2a28bf eb2a290b 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ee8 e59f302c e3a02000 e5832000 e3a03000 
09-01 07:20:39.669: INFO/DEBUG(31): 822d6ef8 e12fff33 e51b3008 e1a00003 e24bd004 
09-01 07:20:39.679: INFO/DEBUG(31): 822d6f08 e8bd8800 0173faf0 00cea68c 00cec48c 
09-01 07:20:39.679: INFO/DEBUG(31): stack: 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9e8  83875a54  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9ec  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f0  00000040  
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f4  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9f8  43fcda24  
09-01 07:20:39.679: INFO/DEBUG(31):     43fcd9fc  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda00  00000040  
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda04  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda08  43fcda24  
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda0c  82d61244  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda10  82fc15a4  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda14  82fc3364  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda18  00000040  
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda1c  82fc1554  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.679: INFO/DEBUG(31):     43fcda20  df002777  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda24  e3a070ad  
09-01 07:20:39.690: INFO/DEBUG(31): #00 43fcda28  4051f020  /dev/ashmem/dalvik-heap (deleted) 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda2c  00000000  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda30  0029d2c0  [heap] 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda34  0029d378  [heap] 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda38  43fcdaac  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda3c  82330ec0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda40  43fcdac8  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda44  0029d2c0  [heap] 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda48  00000003  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda4c  0029d2c0  [heap] 
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda50  c0000000  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda54  000000da  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda58  43fcdb4c  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda5c  43eaeea8  
09-01 07:20:39.690: INFO/DEBUG(31):     43fcda60  43eaee90  
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda64  afd1413f  /system/lib/libc.so 
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda68  40098e88  /dev/ashmem/dalvik-heap (deleted) 
09-01 07:20:39.699: INFO/DEBUG(31):     43fcda6c  800680e3  /system/lib/libdvm.so 
09-01 07:20:40.800: DEBUG/Zygote(33): Process 339 terminated by signal (11) 
09-01 07:20:40.810: INFO/ActivityManager(61): Process mogoweb.browser.app (pid 339) has died.

从NDK r5b开始,增加了调试的支持,引入了ndk-gdb脚本,可以单步调试程序。在单步调试了hello-jni后,欣喜若狂,以为结束了之前用log调试代码的痛苦日子。但在浏览器项目中使用ndk-gdb,却死活无法调试,至今都不明白是因为程序太大,还是因为程序中有多线程的代码导致的。

NDK r6给我们带来了一个惊喜,那就是ndk-stack工具,其作用就是将上面的天书翻译成我们能懂的描述。下面就看看ndk-stack是如何使用的吧。

首先,要求动态链接库带调试信息(注:并不要求在模拟器/设备中的动态库带调式信息,放心的strip掉调试信息)。如果是用的ndk-build编译native代码,在$PROJECT_PATH/obj/local/<ab>下就有,<ab>代表设备的ABI(比如,缺省就是armeabi)。如果是用的cmake编译native代码,需要将CMAKE_BUILD_TYPE定义成Debug,判断是否编译了带调试信息的版本,可以检查最后的编译命令有没有带-g参数。编译出的so通常位于$PROJECT_PATH/libs/<ab>下。

接下来输入如下命令,指定带调式符号的so所在的路径(用$SYMBOL_SO_PATH指代):

adb logcat | ndk-stack –sym $SYMBOL_SO_PATH

下面就是之前的一段天书翻译出来的结果:

********** Crash dump: ********** 
Build fingerprint: ‘generic/sdk/generic:2.3.3/GRI34/101070:eng/test-keys’ 
pid: 339, tid: 347  >>> mogoweb.browser.app <<< 
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr bbadbeef 
Stack frame #00  pc 002d6ef0  /data/data/mogoweb.browser.app/lib/libmogowebcore.so: Routine Chrome in /home/alex/webkit/android2.3/src/third/WebKit/Source/WebCore/page/Chrome.cpp:67

对比当初调试浏览器代码,为了定位程序崩溃的位置,从代码入口开始一路printf,这无疑是一个重大的进步。

分类: Android NDK 标签:

使用CMake进行android native开发

2011年8月2日 alex 2 条评论

Android NDK中提供了ndk-build脚本,以及若干mk文件,以简化ndk的开发,这对于开发一些小型应用来说足够了,但是对于一些大型项目,特别是涉及到很多第三方库时,管理起来就不是那么方便了(个人意见,Makefile写得好的人,可以无视)。在linux开源界,用得比较广泛的就是automake和cmake。本篇文章就是介绍如何使用cmake构建native程序的。

我之前写了一篇博客使用CMake构建android原生库,不过介绍的方法比较繁琐,最近在google code看到一个项目android-cmake,里面提供了脚本,这样使用起来就更方便了。下面就是介绍android-cmake的安装及使用方法。首先交代一下我的工作环境,ubuntu 10.10 32bit、Android NDK r6及Android SDK r12。接下来的步骤是:

1)下载android-cmake

    hg clone https://code.google.com/p/android-cmake/ $HOME/android/android-cmake

2)使用NDK创建单独的工具链

    export NDK=~/android/android-ndk-r6

    $NDK/build/tools/make-standalone-toolchain.sh –platform=android-5 –install-dir=$HOME/android/android-toolchain

3)将如下代码加入$HOME/.profile

    export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android/android-toolchain

    export ANDTOOLCHAIN=$HOME/android/android-cmake/toolchain/android.toolchain.cmake

    alias android-cmake=’cmake –DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN ’

android-cmake包含了若干示例,从helloworld到复杂的boost库,先从一个简单的hello-cmake开始吧。

    cd samples/hello-cmake

    mkdir androidbuild

    cd androidbuild

    android-cmake ..

    make

即可编译出libhello-cmake.so,位于libs/armeabi-v7a。可以使用cmake GUI来修改某些设置:

    cmake-gui ..

image 

注:这个例子只包含了java和jni的代码,并没有包括android工程,android工程在hello-android-cmake目录下。

在编译过程中,可能会出现如下错误:

– SWIG is not found 
– The C compiler identification is GNU 
– The CXX compiler identification is GNU 
– Check for working C compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-gcc 
– Check for working C compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-gcc — works 
– Detecting C compiler ABI info 
CMake Error: Could not COPY_FILE. 
  OutputFile: ” 
    copyFile: ‘/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_C.bin’ 
Unable to find executable for try_compile: tried "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Debug/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Development/cmTryCompileExec". 
– Detecting C compiler ABI info – done 
CMake Error at /usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake:40 (FILE): 
  file STRINGS file 
  "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_C.bin" 
  cannot be read. 
Call Stack (most recent call first): 
  /usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:71 (CMAKE_DETERMINE_COMPILER_ABI) 
  CMakeLists.txt:3 (project) 
– Check for working CXX compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-g++ 
– Check for working CXX compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-g++ — works 
– Detecting CXX compiler ABI info 
CMake Error: Could not COPY_FILE. 
  OutputFile: ” 
    copyFile: ‘/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin’ 
Unable to find executable for try_compile: tried "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Debug/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Development/cmTryCompileExec". 
– Detecting CXX compiler ABI info – done 
CMake Error at /usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake:40 (FILE): 
  file STRINGS file 
  "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin" 
  cannot be read. 
Call Stack (most recent call first): 
  /usr/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake:64 (CMAKE_DETERMINE_COMPILER_ABI) 
  CMakeLists.txt:3 (project) 
– Configuring incomplete, errors occurred!

原因在于在测试编译器时,链接后的程序默认放在bin/armeabi-v7a目录下,而测试代码在另外的目录下去查找生成文件,解决的方法是修改$ANDTOOLCHAIN文件,将

set( EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ARMEABI_NDK_NAME} CACHE PATH "Output directory for applications" FORCE)

改成 
set( EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH_ROOT} CACHE PATH "Output directory for applications" FORCE)

补充:

在使用cmake构建webkit android porting时,出现错误:

Could NOT find BISON (missing: BISON_EXECUTABLE)

原因在于$ANDTOOLCHAIN文件中修改了CMake系统变量:

set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )

解决的方法是将代码中这样的语句注释掉。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值