【教程分享】如何使用NDK-STACK tool来恢复Cocos2d-x安卓错误堆栈信息

很多童鞋在纠结在Cocos2d-x中安卓项目如何调试JNI部分的C++代码,版主在吃完2个茶叶蛋后决定放大招。。。

本文翻译自:http://www.cocos2d-x.org/forums/6/topics/46225

1.安卓 NDK-STACK tool
NDK-Stack 是一个非常易用的工具,它通过将信息显示到adb logcat中来辅助你分析堆栈追踪,然后用相应的值(哪篇源码的哪一行)来替代静态链接库中的地址。
在adb logcat的输出区,你可以看到类似下面的信息,但是在此之前我们必须先先对它进行解析。

I/DEBUG   (   31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (   31): Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
I/DEBUG   (   31): pid: 351, tid: 351  %gt;%gt;%gt; /data/local/ndk-tests/crasher <<<
I/DEBUG   (   31): signal 11 (SIGSEGV), fault addr 0d9f00d8
I/DEBUG   (   31):  r0 0000af88  r1 0000a008  r2 baadf00d  r3 0d9f00d8
I/DEBUG   (   31):  r4 00000004  r5 0000a008  r6 0000af88  r7 00013c44
I/DEBUG   (   31):  r8 00000000  r9 00000000  10 00000000  fp 00000000
I/DEBUG   (   31):  ip 0000959c  sp be956cc8  lr 00008403  pc 0000841e  cpsr 60000030
I/DEBUG   (   31):          #00  pc 0000841e  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #01  pc 000083fe  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #02  pc 000083f6  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #03  pc 000191ac  /system/lib/libc.so
I/DEBUG   (   31):          #04  pc 000083ea  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #05  pc 00008458  /data/local/ndk-tests/crasher
I/DEBUG   (   31):          #06  pc 0000d362  /system/lib/libc.so
I/DEBUG   (   31):

2.如何使用这个工具?
如果你成功地编译了一个Cocos2d-x安卓项目,它将会在$PROJECT_PATH/obj/local/目录下生产一个静态链接库,这里的代表你的设备的ABI(比如,默认为armeabi)。
你可以将输出结果作为输入,就像下面这样:

adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi

或者你也可以使用 -dump选项将指定logcat保存为文件作为输入,就像下面这样:

adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi -dump foo.txt

最后,你就可以得到更多有效可读的输出信息:

********** Crash dump: **********
Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
pid: 351, tid: 351  >>> /data/local/ndk-tests/crasher <<<
signal 11 (SIGSEGV), fault addr 0d9f00d8
Stack frame #00  pc 0000841e  /data/local/ndk-tests/crasher : Routine zoo in /tmp/foo/crasher/jni/zoo.c:13
Stack frame #01  pc 000083fe  /data/local/ndk-tests/crasher : Routine bar in /tmp/foo/crasher/jni/bar.c:5
Stack frame #02  pc 000083f6  /data/local/ndk-tests/crasher : Routine my_comparison in /tmp/foo/crasher/jni/foo.c:9
Stack frame #03  pc 000191ac  /system/lib/libc.so
Stack frame #04  pc 000083ea  /data/local/ndk-tests/crasher : Routine foo in /tmp/foo/crasher/jni/foo.c:14
Stack frame #05  pc 00008458  /data/local/ndk-tests/crasher : Routine main in /tmp/foo/crasher/jni/main.c:19
Stack frame #06  pc 0000d362  /system/lib/libc.so

3.重要提示
NDK-STACK tool的logcat输出需要有一个初始化行,比如像下面这样:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

当复制/粘帖追踪信息时,不要忘记把这个初始化行也给带上,否则NDK-STACK tool将不会正常的工作。
目前对各平台(linux/windows/mac)的NDK(可见http://developer.android.com/tools/sdk/ndk/index.html),NDK-STACK都是有效的。

4.参考文档
$NDK_ROOT/docs/NDK-STACK.html

吃完两个茶叶蛋来放大招啊:7: :7: :7: :7:

:3::3:
不明所以然。
看不懂。好像很历害的样子。还是顶一下

这可是个好东西啊。哈哈,如果有什么解释不清楚的或者不理解的可以提出来哦亲。。。 :877:

多谢,这个不能算作调试吧,是错误信息的堆栈信息复原。

专业教程啊, 楼主好棒:867::867::867::867:

嗯,感谢纠正,这个确是算恢复错误堆栈信息,用调试不准确,标题已改。

小白android不是很懂,第一种办法 日志在哪里输入啊 又在输出在哪里;

第二种 是把 eclipse里面 logcat的日志保存 成txt, 然后

adb logcat > C:\Users\hp\Desktop\log.txt E:\tools\NDK\ndk-stack -sym E:\cocos2d-x-3.0rc0\projects\test\proj.android\obj\local\armeabi -dump log.txt

$NDK $PROJECT_PATH 这个可以写成绝对路径吧, 然后貌似没成功:5:

log 变成一堆提示了

Invalid filter expression ‘E:\tools\NDK\ndk-stack’

Usage: logcat

options include:

-s Set default filter to silent.

              Like specifying filterspec '*:s'

-f Log to file. Default to stdout

-r ] Rotate log every kbytes. (16 if unspecified). Requires -f

-n Sets max number of rotated logs to , default 4

-v Sets the log print format, where is one of:

              brief process tag thread raw time threadtime long

-c clear (flush) the entire log and exit

-d dump the log and then exit (don’t block)

-t print only the most recent lines (implies -d)

-g get the size of the log’s ring buffer and exit

-b Request alternate ring buffer, ‘main’, ‘system’, ‘radio’

              or 'events'. Multiple -b parameters are allowed and the

              results are interleaved. The default is -b main -b system.

-B output the log in binary

filterspecs are a series of

:priority]

where is a log component tag (or * for all) and priority is:

V Verbose

D Debug

I Info

W Warn

E Error

F Fatal

S Silent (supress all output)

’ means ':d’ and by itself means :v

楼上那个显然是没配置好啊

牛逼, 一次吃两个茶叶蛋…

膜拜土豪…

需要配置什么?:12:

这个比google 的breakpad好用吗?

mark,给力

:3::3:

不明所以然。
看不懂。好像很历害的样子。还是顶一下

什么意思?这是windows版本的?mac版本的怎么弄啊:2::2::2::2:

每次就显示这样一点信息
********** Crash dump: **********
Build fingerprint: ‘samsung/GT-I9100/GT-I9100:4.0.4/IMM76L/eng.build.20130311.12
2614:eng/release-keys’
pid: 3074, tid: 3111 >>> com.pinyoush.ddz3 <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr fffffffc

感谢分享 解决了我的问题

我想请问,为什么我的logcat出来的东西 前面不是 I/DEBUG ??? 下边是log的部分展示,还请指导下!

W/HDCP ( 99): Device not support HDCP, just exit.

I/HDCP ( 99): HDCP exiting

D/ScreenScaleManager( 99): i is 0

D/ScreenScaleManager( 99): i is 1

D/ScreenScaleManager( 99): i is 2

D/ScreenScaleManager( 99): i is 3

D/ScreenScaleManager( 99): i is 4

D/ScreenScaleManager( 99): MainDisplaySysNode is /sys/class/graphics/fb2/scale

D/ScreenScaleManager( 99): AuxDisplaySysNode is /sys/class/graphics/fb0/scale

D/ScreenScaleManager( 99): display 0, rate 95

--------- beginning of /dev/log/system

I/Vold ( 98): Vold 2.1 (the revenge) firing up

I/RegionTag( 109): ----------------running drmservice---------------

I/RegionTag( 109): ret=0, sn length=0

I/RegionTag( 109): SN Buffer=

I/RegionTag( 109): serialno in nand.

I/Netd ( 100): Netd 1.0 starting

W/InterfaceController( 100): Warning (Cannot load library: load_library(linker.cpp:745): library “/system/lib/libnetcmdiface.so” not found) while opening the net interface command library

I/RegionTag( 109): 0, , 30SWI23EKJ

I/RegionTag( 109): drm keybox disable!!

I/RegionTag( 109): detect keybox disabled

I/RegionTag( 109): unknown wifi chip , get it !!!. time=0

I/DEBUG ( 101): debuggerd: Sep 19 2014 00:37:12

D/InputEventConsistencyVerifier( 768): 1: sent at 251300000000, KeyEvent { action=ACTION_UP, keyCode=KEYCODE_MENU, scanCode=141, metaState=0, flags=0x8, repeatCount=0, eventTime=251300, downTime=251200, deviceId=0, source=0x101 }

D/InputEventConsistencyVerifier( 768): 2: sent at 251200000000, KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_MENU, scanCode=141, metaState=0, flags=0x8, repeatCount=0, eventTime=251200, downTime=251200, deviceId=0, source=0x101 }

D/InputEventConsistencyVerifier( 768): 3: sent at 204318107000, MotionEvent { action=ACTION_UP, id=0, x=653.125, y=516.09375, toolType=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=204318, downTime=203176, deviceId=2, source=0x1002 }

D/InputEventConsistencyVerifier( 768): 4: sent at 204308070000, MotionEvent { action=ACTION_MOVE, id=0, x=653.125, y=516.09375, toolType=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=1, eventTime=204308, downTime=203176, deviceId=2, source=0x1002 }

D/InputEventConsistencyVerifier( 768): 5: sent at 204261011000, MotionEvent { action=ACTION_MOVE, id=0, x=653.125, y=516.09375, toolType=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=1, eventTime=204261, downTime=203176, deviceId=2, source=0x1002 }

V/TabletStatusBar( 460): setLightsOn(true)

D/dalvikvm( 1220): GC_EXPLICIT freed 70K, 1% free 12713K/12824K, paused 5ms+11ms, total 75ms

D/MediaPlayerFactory( 106): FILE:(/system/vendor/Game.apk) get STAGEFRIGHT_PLAYER

D/MediaPlayerFactory( 106): createPlayer:playerType=3

虽然我很想现在就试试 但还是等过几天项目正式版出了再搞吧

赶脚项目临近结束的时候提交代码的时候
都有强迫症了有没有:10::10::10: