使用ndk-stack追踪程序崩溃
来源:互联网 发布:洛天依软件百度云 编辑:程序博客网 时间:2024/05/21 22:43
http://mogoweb.net/categories/android-ndk
程序崩溃无疑是程序员最头疼的事情,而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,这无疑是一个重大的进步。
使用CMake进行android native开发
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 ..
注:这个例子只包含了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 )
解决的方法是将代码中这样的语句注释掉。
- 使用ndk-stack追踪程序崩溃
- Android 使用ndk-stack追踪程序崩溃
- android开发使用 ndk-stack 打印崩溃日志
- ndk-stack 调试NDK程序
- ndk-stack 学习使用
- android ndk stack 使用
- ndk-stack使用
- ndk-stack 学习使用
- ndk-stack的使用
- ndk-stack的使用
- ndk-stack的使用
- ndk-stack的使用
- ndk-stack 的使用
- ndk-stack的使用
- ndk-stack使用
- ndk-stack 学习使用
- 使用 ndk-stack 寻找Android程序Crash的原因
- cocos2d-x使用ndk-stack
- iSCSI 相关 --Multipath
- VirtualBox、VMWare Workstation作为开发环境的一些比较
- PCB拼板
- PHP最简单写文件记日志当前时间
- activity的启动方式(launch mode)
- 使用ndk-stack追踪程序崩溃
- windows组件向导里没有internet 信息服务(iis) 的解决办法
- 用Visual C++打造自己的资源管理器
- 网络编程知识要点
- Java【多线程知识总结(1)】用Thread类创建线程
- Oracle sql 性能优化调整
- 第13天上(XML2)
- joj 1184
- .c/.cpp文件编译成exe .mdp文件