posts - 189,comments - 115,trackbacks - 0

          利用NDK崩潰日志查找BUG 

          [cocos2dx]利用NDK崩潰日志查找BUG - 知明所以

          摘要: 在android上開發c++應用, crash日志都是匯編碼, 很難對應到c++代碼中去. 通過此文, 你可以定位到程序崩潰時的C++代碼, 精確查找問題.



          背景介紹

          1. 本文主要內容: 利用android的crash log來對c++開發的android應用進行錯誤定位.

          2. 容易穩定復現的BUG, 一般可以通過斷點調試來解決. 如果測試人員也無法穩定復現, log就成了程序吊定位問題的救命稻草 .

          3. 通用操作系統都有自己的日志系統, android也不例外. 救命稻草已經給你了~ ()

          4. 但是, android的系統日志在c++代碼崩潰時, 打印的都是內存地址和寄存器. 比如, 這樣:

          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

          這密密麻麻的都是些神馬, 是人看的么?

          餓. 這個麻… 誰讓你當程序猿! 讓你當! 活該要看天書!

          硬著頭皮也要來, 我們就來講講怎么消化天書吧~

          怎樣獲取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到上述的系統日志中.

          下面是我正在開發的游戲一次崩潰后, 截取的日志( 插個廣告, 全名斗地主下載地址: http://sj.ddwan.com )

          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) : link register . 簡單來說, 當當前指令執行完了, 就會從這個寄存器獲取地址, 來知道需要返回到哪里繼續執行.
          • pc (or r15) : program counter. 存放下一條指令的地址.
          • cpsr : Current Program Status Register. 表示當前運行環境和狀態的一些字節位.

            1. Crash dump還包含PC之前和之后的一些內存字段.
            2. 最后, 是崩潰時的調用堆棧. 如果你執行的是debug版本, 還能還原一些c++代碼.

          利用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
          ...
          posted on 2015-03-31 16:17 MEYE 閱讀(339) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 隆化县| 拉萨市| 柳州市| 夏邑县| 湖北省| 宁国市| 缙云县| 马龙县| 阿瓦提县| 和顺县| 沂水县| 邢台市| 沈阳市| 咸宁市| 右玉县| 平泉县| 台州市| 许昌县| 长沙市| 新昌县| 中卫市| 乌兰浩特市| 青州市| 弋阳县| 金湖县| 收藏| 永登县| 西昌市| 麟游县| 黎川县| 新丰县| 铁岭县| 仙居县| 花垣县| 阿坝| 达拉特旗| 布尔津县| 科技| 河津市| 龙海市| 仙桃市|