利用NDK崩溃日志查找BUG

获取android的系统日志

假设你已经安装了 Android Develop Tools, 可以成功调用adb. 并打开android开发用机的调试模式, 连接到电脑.

打开命令行, 在命令行输入: adb logcat. 就可以看到满屏幕的日志啦.
输入adb logcat --help可以看到 logcat的用法提示.

这里有两个参数特别提醒一下, 比较常用:

  1. -v XXXX: 用来选择log输出样式, 一般建议 threadtime, 更加详细.
  2. -d: 让log一次性输出后马上完毕. 如果没有此命令, logcat 工具会一直输出, 即使更新在界面上.

如果需要保存log到文件, 方便以后查看. 可输入命令:
adb logcat -v threadtime -d > log.txt

理解NDK的crash log

如果你用c++开发的android应用在运行过程中, c++代码发生错误导致程序崩溃, 系统就会记录 crash log到上述的系统日志中.

06-20 15:54:35.331 23889 23889 I DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-20 15:54:35.331 23889 23889 I DEBUG   : Build fingerprint: 'google/razorg/deb:4.4.2/KOT49H/937116:user/release-keys'
06-20 15:54:35.331 23889 23889 I DEBUG   : Revision: '0'
06-20 15:54:35.331 23889 23889 I DEBUG   : pid: 1981, tid: 2020, name: Thread-3399  >>> com.guangyou.ddgame <<<
06-20 15:54:35.331 23889 23889 I DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000028
06-20 15:54:35.431   187   710 D audio_hw_primary: out_set_parameters: enter: usecase(0: deep-buffer-playback) kvpairs: routing=2
06-20 15:54:35.511 23889 23889 I DEBUG   :     r0 76d94458  r1 00000000  r2 00000000  r3 00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     r4 760c1a48  r5 751e2440  r6 00000001  r7 760c1a48
06-20 15:54:35.511 23889 23889 I DEBUG   :     r8 00000001  r9 76c96f3c  sl 76c861c0  fp 76d94444
06-20 15:54:35.511 23889 23889 I DEBUG   :     ip 00000001  sp 76d94430  lr 75a81bd8  pc 75a81bdc  cpsr 600f0010
06-20 15:54:35.511 23889 23889 I DEBUG   :     d0  746968775f327865  d1  6a6e6169642f675f
06-20 15:54:35.511 23889 23889 I DEBUG   :     d2  5f6f616978757169  d3  676e702e6e776f6d
06-20 15:54:35.511 23889 23889 I DEBUG   :     d4  0000000009000000  d5  0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d6  0000000000000000  d7  0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d8  0000000000000000  d9  0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d10 0000000000000000  d11 0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d12 0000000000000000  d13 0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d14 0000000000000000  d15 0000000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d16 c3c3c3c3c3c3c3c3  d17 c3c3c3c3c3c3c3c3
06-20 15:54:35.511 23889 23889 I DEBUG   :     d18 41c7ddc227000000  d19 3ff0000000000000
06-20 15:54:35.511 23889 23889 I DEBUG   :     d20 3f811110896efbb2  d21 3fd7096611460fdb
06-20 15:54:35.511 23889 23889 I DEBUG   :     d22 c0176a8ee0000000  d23 bfc5230c760b0605
06-20 15:54:35.511 23889 23889 I DEBUG   :     d24 0000000000000000  d25 3fc7922925a107e2
06-20 15:54:35.511 23889 23889 I DEBUG   :     d26 3fdaa0f8fab43e33  d27 3fb43ad076b251ab
06-20 15:54:35.511 23889 23889 I DEBUG   :     d28 3fa15cb6bdc3c156  d29 3ec6cd878c3b46a7
06-20 15:54:35.511 23889 23889 I DEBUG   :     d30 3f65f3b6b9b97e01  d31 3ef99342e0ee5069
06-20 15:54:35.511 23889 23889 I DEBUG   :     scr 20000012
06-20 15:54:35.511 23889 23889 I DEBUG   :
06-20 15:54:35.511 23889 23889 I DEBUG   : backtrace:
06-20 15:54:35.511 23889 23889 I DEBUG   :     #00  pc 0089cbdc  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::Texture2D::getContentSize() const+32)
06-20 15:54:35.511 23889 23889 I DEBUG   :     #01  pc 0088f8dc  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::Sprite::setTexture(std::string const&)+128)
06-20 15:54:35.511 23889 23889 I DEBUG   :     #02  pc 007863dc  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::ui::Button::loadTextureDisabled(std::string const&, cocos2d::ui::Widget::TextureResType)+336)
06-20 15:54:35.511 23889 23889 I DEBUG   :
06-20 15:54:35.511 23889 23889 I DEBUG   : stack:
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d943f0  00000001
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d943f4  4006bc0d  /system/lib/libc.so (free+12)
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d943f8  76a72c54
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d943fc  75eca614  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94400  751c23c8  [anon:libc_malloc]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94404  751c23c8  [anon:libc_malloc]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94408  751c23c8  [anon:libc_malloc]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9440c  75a749b4  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::Sprite::setTexture(cocos2d::Texture2D*)+128)
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94410  0000003d
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94414  00e8efc8
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94418  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9441c  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94420  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94424  76d94458  [stack:2020]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94428  00000020
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9442c  76d94444  [stack:2020]
06-20 15:54:35.511 23889 23889 I DEBUG   :     #00  76d94430  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94434  76d94458  [stack:2020]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94438  76a66184
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9443c  760c1a48  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94440  76d9447c  [stack:2020]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94444  75a748e0  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::Sprite::setTexture(std::string const&)+132)
06-20 15:54:35.511 23889 23889 I DEBUG   :     #01  76d94448  76d944ec  [stack:2020]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9444c  793ff0e8  [anon:libc_malloc]
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94450  76a72c54
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94454  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94458  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9445c  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94460  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94464  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d94468  00000000
06-20 15:54:35.511 23889 23889 I DEBUG   :          76d9446c  00000000
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94470  7b91dcf8  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94474  78ce6c50  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94478  76d944b4  [stack:2020]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d9447c  7596b3e0  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocos2d::ui::Button::loadTextureDisabled(std::string const&, cocos2d::ui::Widget::TextureResType)+340)
06-20 15:54:35.521 23889 23889 I DEBUG   :     #02  76d94480  00000001
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94484  00000000
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94488  76d944ec  [stack:2020]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d9448c  793fe780  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94490  76d944f0  [stack:2020]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94494  793ff0e8  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d94498  00000001
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d9449c  4006bc0d  /system/lib/libc.so (free+12)
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944a0  76a72c54
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944a4  75eca614  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944a8  78ce6c50  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944ac  78ce6c50  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944b0  76d9455c  [stack:2020]
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944b4  75924e54  /data/app-lib/com.guangyou.ddgame-1/libcocos2dcpp.so (cocostudio::ButtonReader::setPropsFromJsonDictionary(cocos2d::ui::Widget*, rapidjson::GenericValue<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> > const&)+752)
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944b8  00000000
06-20 15:54:35.521 23889 23889 I DEBUG   :          76d944bc  78ce6c50  [anon:libc_malloc]
06-20 15:54:35.521 23889 23889 I DEBUG   :
06-20 15:54:35.521 23889 23889 I DEBUG   : memory near r0:
06-20 15:54:35.521 23889 23889 I DEBUG   :     76d94438 76a66184 760c1a48 76d9447c 75a748e0
06-20 15:54:35.521 23889 23889 I DEBUG   :     76d94448 76d944ec 793ff0e8 76a72c54 00000000
...
06-20 15:54:35.521 23889 23889 I DEBUG   :
06-20 15:54:35.521 23889 23889 I DEBUG   : memory near r4:
06-20 15:54:35.521 23889 23889 I DEBUG   :     760c1a28 760811c8 75ee318c 75ee3194 75ee319c
06-20 15:54:35.521 23889 23889 I DEBUG   :     760c1a38 4006d091 75f9a1f4 75f4ee5c 75e8ea0c
...

下面来逐行解读:

1. ndk crash log以*** *** *** *** ***开始.
2. 第一行Build fingerprint: 'google/razorg/deb:4.4.2/KOT49H/937116:user/release-keys' 指明了运行的Android版本, 如果您有多份crash dump的话这个信息就比较有用了.
3. 接着一行显示的是当前的线程id(pid)和进程id(tid). 如果当前崩溃的线程是主线程的话, pid和tid会是一样的~
4. 第四行, 显示的是unix信号. 这里的signal 11, 即SIGSEGV, 表示段错误, 是最常见的信号.(什么是unix信号, 什么是SIGSEGV)
5. 接下来的部分是系统寄存器的dump信息.

符号 解释
rX(X=[0~9]) 代表整数寄存器
dX(X=[0~31]) 是浮点指针寄存器
fp (or r11) 指向当前正在执行的函数的堆栈底.
ip (or r12) 中断优先寄存器
sp (or r13) 当前正在执行的函数的堆栈顶.(跟fp相对应)
lr (or r14) 简单来说, 当当前指令执行完了, 就会从这个寄存器获取地址, 来知道需要返回到哪里继续执行.
pc (or r15) program counter. 存放下一条指令的地址
cpsr Current Program Status Register. 表示当前运行环境和状态的一些字节位.

6. Crash dump还包含PC之前和之后的一些内存字段.
7. 最后, 是崩溃时的调用堆栈. 如果你执行的是debug版本, 还能还原一些c++代码.

Android NDK开发Crash错误定位

NDK安装包中提供了三个调试工具:addr2line、objdump和ndk-stack。其中ndk-stack放在$NDK_HOME目录下,与ndk-build同级目录。

addr2line和objdump在ndk的交叉编译器工具链目录下,NDK针对不同的CPU架构实现了多套相同的工具。所以在选择addr2line和objdump工具的时候,要根据你目标机器的CPU架构来选择。

(1)如果是arm架构,选择arm-linux-androidabi-4.6/4.8(一般选择高版本)。
32位: arm-linux-androideabi-addr2line
64位: aarch64-linux-android-addr2line

(2)x86架构,选择x86-4.6/4.8。mipsel架构,选择mipsel-linux-android-4.6/4.8。

(3)如果不知道目标机器的CPU架构,把手机连上电脑,用adb shell cat /proc/cpuinfo可以查看手机的CPU信息。

以下以armv7架构为例 !!!

addr2line : 定位出错位置

32位:
~/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line  -C  -s -f -e  ./app/build/intermediates/cmake/debug/obj/armeabi-v7a/libapm-audio-lib.so 00003dd7 
/Users/beck/Desktop/Audio-Self-Record/app/src/main/cpp/audio-lib.cpp:58

64位:

 ~/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-addr2line  -C  -s -f -e libagora-rtc-sdk-jni.sym 0x0000000000147e28

objdump : 定位出错的函数信息

arm-linux-androideabi-objdump -S -D ~/Documents/devToos/java/android-ndk-r9d/samples/hello-jni/obj/local/armeabi-v7a/libhello-jni.so > ~Desktop/dump.log

在生成的asm文件中,找出我们根据Crash日志定位到出错的汇编指令地址。 进而得到出错的指针地址分别位于哪个函数中。

ndk-stack : 直接定位到代码出错的位置

Android NDK自从版本R6开始, 提供了一个工具ndk-stack( 在目录{ndk_root}/中 ). 这个工具能自动分析dump下来的crash log, 将崩溃时的调用内存地址和c++代码一行一行对应起来.

我们先看一下用法, 执行命令ndk-stack --help

Usage:
   ndk-stack -sym <path> [-dump <path>]

      -sym  Contains full path to the root directory for symbols.
      -dump Contains full path to the file containing the crash dump.
            This is an optional parameter. If ommited, ndk-stack will
            read input data from stdin

-dump参数很容易理解, 即dump下来的log文本文件. ndk-stack会分析此文件.
-sym参数就是你android项目下,编译成功之后,obj目录下的文件.
下面我们就来示范一下:

$ adb logcat | ndk-stack -sym ./obj/local/armeabi
********** Crash dump: **********
Build fingerprint: 'htc_wwe/htc_bravo/bravo:2.3.3/
GRI40/96875.1:user/release-keys'
pid: 1723, tid: 1743  >>> com.packtpub.droidblaster <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0000000c
Stack frame #00  pc 00010a2c  /data/data/com.packtpub.droidblaster/lib/libdroidblaster.so: Routine update in /home/packt/Project/Chapter11/DroidBlaster_Part11/jni/TimeService.cpp:25
Stack frame #01  pc 00009fcc  /data/data/com.packtpub.droidblaster/lib/libdroidblaster.so: Routine onStep in /home/packt/Project/Chapter11/DroidBlaster_Part11/jni/DroidBlaster.cpp:53
Stack frame #02  pc 0000a348  /data/data/com.packtpub.droidblaster/lib/libdroidblaster.so: Routine run in /home/packt/Project/Chapter11/DroidBlaster_Part11/jni/EventLoop.cpp:49
Stack frame #03  pc 0000f994  /data/data/com.packtpub.droidblaster/lib/libdroidblaster.so: Routine android_main in /home/packt/Project/Chapter11/DroidBlaster_Part11/jni/Main.cpp:31
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343