cocos2d-xの開発は基本Xcodeとシミュレータで行い、androidはたまに動作確認するといったスタンスでの開発になると思いますが、いざandroidでアプリが落ちた時にデバッガと繋がっていなくて困ることが多いと思います。
実はandroidではアプリがクラッシュした時に、logcatにtombstoneという以下の様なコアダンプを吐いています。
I/DEBUG ( 219): debuggerd: 2014-06-11 18:19:57
I/DEBUG ( 219): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 219): Build fingerprint: 'xxx'
I/DEBUG ( 219): pid: 15992, tid: 16012, name: Thread-27308 >>> xxx <<<
I/DEBUG ( 219): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004
I/DEBUG ( 219): r0 00000000 r1 00000001 r2 00000001 r3 00000000
I/DEBUG ( 219): r4 60eb1b84 r5 60af4364 r6 62b93e68 r7 5e097f30
I/DEBUG ( 219): r8 60788c50 r9 5e097f28 sl 40478510 fp 60788b54
I/DEBUG ( 219): ip 00000000 sp 60788b40 lr 609fe144 pc 60b87d18 cpsr 60000010
I/DEBUG ( 219): d0 6f50726564616853 d1 65546e6f69746973
I/DEBUG ( 219): d2 6c6f436572757478 d3 50564d6f6e5f726f
I/DEBUG ( 219): d4 ff04091aff01081e d5 ff020a21ff050a1c
I/DEBUG ( 219): d6 ee070b1cee03091f d7 ee030c24ee070c1e
I/DEBUG ( 219): d8 0000000000000000 d9 0000000000000000
I/DEBUG ( 219): d10 0000000000000000 d11 0000000000000000
I/DEBUG ( 219): d12 0000000000000000 d13 0000000000000000
I/DEBUG ( 219): d14 0000000000000000 d15 0000000000000000
I/DEBUG ( 219): d16 6f50726564616853 d17 65546e6f69746973
I/DEBUG ( 219): d18 0000000000000000 d19 0000000000000000
I/DEBUG ( 219): d20 0000000000000000 d21 0000000000000000
I/DEBUG ( 219): d22 0000000000000000 d23 0000000000000000
I/DEBUG ( 219): d24 0000000000000000 d25 0000000000000000
I/DEBUG ( 219): d26 0000000000000000 d27 0000000000000000
I/DEBUG ( 219): d28 0100010001000100 d29 0100010001000100
I/DEBUG ( 219): d30 0000000000000000 d31 0000000000000000
I/DEBUG ( 219): scr 6000001a
I/DEBUG ( 219):
I/DEBUG ( 219): backtrace:
I/DEBUG ( 219): #00 pc 003fed18 /data/data/xxx/lib/libcocos2dcpp.so (cocos2d::Ref::retain()+20)
I/DEBUG ( 219): #01 pc 00275140 /data/data/xxx/lib/libcocos2dcpp.so (SplashScene::init()+192)
I/DEBUG ( 219):
I/DEBUG ( 219): stack:
I/DEBUG ( 219): 60788b00 60788b14 [stack:16012]
I/DEBUG ( 219): 60788b04 00000000
I/DEBUG ( 219): 60788b08 00000001
I/DEBUG ( 219): 60788b0c 647af210
I/DEBUG ( 219): 60788b10 60788b3c [stack:16012]
I/DEBUG ( 219): 60788b14 60abad30 /data/data/xxx/lib/libcocos2dcpp.so (cocos2d::Node::addChild(cocos2d::Node*, int, int)+324)
I/DEBUG ( 219): 60788b18 43a00000 /dev/ashmem/dalvik-heap (deleted)
I/DEBUG ( 219): 60788b1c 647af234
I/DEBUG ( 219): 60788b20 ffffffff
I/DEBUG ( 219): 60788b24 00000000
I/DEBUG ( 219): 60788b28 647af210
I/DEBUG ( 219): 60788b2c 647af040
I/DEBUG ( 219): 60788b30 60788b44 [stack:16012]
I/DEBUG ( 219): 60788b34 60eb1b84 /data/data/xxx/lib/libcocos2dcpp.so
I/DEBUG ( 219): 60788b38 df0027ad
I/DEBUG ( 219): 60788b3c 00000000
I/DEBUG ( 219): #00 60788b40 60788b54 [stack:16012]
I/DEBUG ( 219): ........ ........
I/DEBUG ( 219): #01 60788b40 60788b54 [stack:16012]
I/DEBUG ( 219): 60788b44 60af4388 /data/data/xxx/lib/libcocos2dcpp.so (cocos2d::Sprite::setPosition(cocos2d::Point const&)+36)
I/DEBUG ( 219): 60788b48 647af210
I/DEBUG ( 219): 60788b4c 00000000
I/DEBUG ( 219): 60788b50 60788b94 [stack:16012]
I/DEBUG ( 219): 60788b54 609fe144 /data/data/xxx/lib/libcocos2dcpp.so (SplashScene::init()+196)
I/DEBUG ( 219): 60788b58 60788b7c [stack:16012]
I/DEBUG ( 219): 60788b5c 647af040
I/DEBUG ( 219): 60788b60 00000000
I/DEBUG ( 219): 60788b64 43a00000 /dev/ashmem/dalvik-heap (deleted)
I/DEBUG ( 219): 60788b68 440e0000 /dev/ashmem/dalvik-heap (deleted)
・・・
レジスタの状態、バックトレース、スタックなどが表示されるのですが、レジスタはもとよりバックトレースやスタックも一部の情報しかありません。
この場合、SplashScene::init()の中で死んだんだろうなーということが分かりますが、ここまで出ることもあまり多くなく、このままではデバッグで死ぬことになります。
そこで ndk-stack
を使うと、以下のように実際のソースコードにおける場所をバックトレースに表示してくれます。
$ ndk-stack -sym proj.android/obj/local/armeabi/ -dump logcat2
********** Crash dump: **********
Build fingerprint: 'xxx'
pid: 15992, tid: 16012, name: Thread-27308 >>> xxx <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004
Stack frame #00 pc 003fed18 /data/data/xxx/lib/libcocos2dcpp.so (cocos2d::Ref::retain()+20): Routine cocos2d::Ref::retain() at /${PROJECT_ROOT}/proj.android/../cocos2d/cocos/2d/../base/CCRef.cpp:64
Stack frame #01 pc 00275140 /data/data/xxx/lib/libcocos2dcpp.so (SplashScene::init()+192): Routine SplashScene::init() at /${PROJECT_ROOT}/proj.android/jni/../../Classes/Scene/SplashScene.cpp:38
無事バックトレースにソースコードの行番号が表示されました。
ndk-stack
ndk-stack
は、 android NDK
についてくるツールの一つです。
使い方はおもに以下の2通りぐらいです。
logcatから直接使う場合
$ adb logcat | ndk-stack -sym proj.android/obj/local/armeabi/
保存してあるlogcatを読み込む場合
$ ndk-stack -sym proj.android/obj/local/armeabi/ -dump logcat.log
ポイント
カレントディレクトリはプロジェクトルート(proj.android)があるフォルダでないと、失敗すると思います。