歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android- NDK編譯APK中native死機調試

以前在服務器編譯Android源碼在盒子上運行死機,可通過文章: android 動態庫死機調試方法 ,我們這裡說的是利用eclipse+NDK編譯apk的native代碼如何調試 http://www.linuxidc.com/Linux/2012-06/63026.htm

眾所周知,調試android java程序可以直接在eclipse上進行單步調試,但是調試android jni函數卻無法進行單步跟蹤而只能加打印進行調試,這樣子效率將會大大降低。而程序崩潰無疑是程序員最頭疼的事情,而android native程序崩潰簡直是令程序員崩潰。

Android java程序在異常之前還打印出代碼調用棧,讓程序員有跡可尋,結合單步調試,定位問題相對容易些。

請看一斷死機的logcat 打印,你能否找到死機哪個函數呢?而這就是我們需要解決的問題

I/DEBUG   (  669): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  669): Build fingerprint: 'generic/generic/generic:2.3.1/GRH78/eng.root.20120613.153206:eng/test-keys'
I/DEBUG   (  669): pid: 1140, tid: 1150  >>> com.ipanel.portal <<<
I/DEBUG   (  669): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00241000
I/DEBUG   (  669):  r0 00241000  r1 00000000  r2 000da324  r3 00000000
I/DEBUG   (  669):  r4 00000000  r5 00000000  r6 00000000  r7 00000000
I/DEBUG   (  669):  r8 00000280  r9 8484e2d8  10 000001e0  fp 0012d184
I/DEBUG   (  669):  ip 00000000  sp 48af05e8  lr 00000000  pc afd1195c  cpsr 20000010
I/DEBUG   (  669):          #00  pc 0001195c  /system/lib/libc.so
I/DEBUG   (  669):          #01  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so
I/DEBUG   (  669):          #02  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so
I/DEBUG   (  669):          #03  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so
I/DEBUG   (  669):          #04  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so
I/DEBUG   (  669):          #05  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so

從NDK r5b開始,增加了調試的支持,引入了ndk-gdb腳本,可以單步調試程序。
而NDK r6給我們帶來了一個驚喜,那就是ndk-stack工具,其作用就是將上面的棧打印翻譯成我們能懂的描述。

下面就看看ndk-stack是如何使用的吧。
首先,要求動態鏈接庫帶調試信息,如果是用的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

ARM平台調式命令:
a、將C:\NDK\android-ndk-r6b添加到windows的path環境變量中
b、adb connect ip(xx.xx.xx.xx)
c、adb logcat > 1.log
d、cat 1.log |  ndk-stack -sym $(project_loc)\obj\local\armeabi
輸出:
D:\hisi-tools\sdk-tools>cat 1.log |  ndk-stack -sym E:\svnhome\apptv\r23-jilin\p
ackages\iPanel30Portal\obj\local\armeabi
********** Crash dump: **********
Build fingerprint: 'generic/generic/generic:2.3.1/GRH78/eng.root.20120613.153206
:eng/test-keys'
pid: 1140, tid: 1150  >>> com.ipanel.portal <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00241000
Stack frame #00  pc 0001195c  /system/lib/libc.so
Stack frame #01  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so:
 Routine ipanel_nvram_task_burn in ../../src/sdk/jilin_2011/proj-sdk/include/../
lib_ffs/ffs_task.c:416
Stack frame #02  pc 00301874  /data/data/com.ipanel.portal/lib/libportal_jni.so:
 Routine ipanel_nvram_task_burn in ../../src/sdk/jilin_2011/proj-sdk/include/../
lib_ffs/ffs_task.c:416

ok,即可定位程序崩潰的位置

對於mips平台來說,使用的命令稍微有些不同,只能使用mipsxx-address2linx工具

Copyright © Linux教程網 All Rights Reserved