クラッシュログをシンボリケートする。

 

iPhoneでアプリがクラッシュすると、クラッシュログが生成されます。

クラッシュログは、iPhoneの設定アプリ -> 「プライバシー」 -> 「解析」→「解析データ」から取得できます。

中身はこんな感じですね


Date/Time:           2017-04-30 19:31:49.0245 -0500
Launch Time:         2017-04-30 19:31:28.9773 -0500
OS Version:          iPhone OS 10.3.1 (14E304)
Report Version:      104

Exception Type:  EXC_CRASH (SIGKILL)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d
Triggered by Thread:  0

Filtered syslog:
None found

Thread 0 name:  Dispatch queue: NSPersistentStoreCoordinator 0x174270780
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001881fb278 0x1881fa000 + 4728
1   libdispatch.dylib             	0x00000001880e96b4 0x1880d5000 + 83636
2   libdispatch.dylib             	0x00000001880e8c5c 0x1880d5000 + 80988
3   CoreData                      	0x000000018b54ed00 0x18b4da000 + 478464
4   CoreData                      	0x000000018b53af14 0x18b4da000 + 397076
:

 

クラッシュした時のスタックトレースが出力されていますが、モジュール名とアドレスが表示されているだけで、このままでは何が起きたのかわかりません。

 

symbolicatecrashを使う

 

そこで、symbolicatecrashというコマンドを使って、ログをシンボリケートしてもう少しわかりやすくします。

symbolicatecrashは、Xcodeについてくるツールなのですが、Xcodeのバージョンによって、置いてある場所が違ったりします。Xcode8の場合、以下にあります。

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

symbolicateを実行するには、クラッシュログの他に、dSYMファイルと呼ばれる、デバッグ用のシンボルを保持するファイルが必要になります。

dSYMファイルは、アプリケーションバッケージの中にあるので、オーガナイザーから該当のアプリのバイナリを右クリックして、「Show in Finder」を選びファインダーに表示し、

 

image_1.jpg

 

xcarchiveファイルを右クリックして、「パッケージの内容を表示」を選び、表示されたdSYMsディレクトリをそのまま、クラッシュログを置いたディレクトリへコピーしましよう。

 

image_2.jpg

 

image_3.jpg

 

この時注意しないといけないのは、クラッシュログを生成したアプリと同じバージョンのバイナリからdSYMSファイルを抽出する必要があるということです。

 

symbolicatecrashに実行パスを通すかフルパスで指定してもいいですが、クラッシュログのあるディレクトリーへコビーしてきたあと、ターミナルで以下のように指定して実行できます。


$ ./symbolicatecrash crash.log dSYMs/ > symbolicated.crash

引数で渡しているcrash.logがクラッシュログ、dSYMs/が先程抽出したdSYMsディレクトクリです。

もし、


Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.

といったエラーが出力される場合は、


export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer/

と、シェル変数に値を設定してから再実行します。

 

実行が終わると、シンボリケートされたファイルが生成されます。(上の場合は、symbolicated.crash)

中身を見ると次のようになっています。


Thread 0 name:  Dispatch queue: NSPersistentStoreCoordinator 0x174270780
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001881fb278 semaphore_timedwait_trap + 8
1   libdispatch.dylib             	0x00000001880e96b4 _os_semaphore_timedwait + 92
2   libdispatch.dylib             	0x00000001880e8c5c _dispatch_semaphore_wait_slow + 72
3   CoreData                      	0x000000018b54ed00 -[NSXPCStoreConnection sendMessage:fromContext:store:error:] + 272
4   CoreData                      	0x000000018b53af14 -[NSXPCStore sendMessage:fromContext:interrupts:error:] + 236
   :             :
31  Photos                        	0x000000019501b5c8 -[PHQuery executeQuery] + 52
32  Photos                        	0x0000000194fe93d4 +[PHAsset fetchAssetsInAssetCollection:options:] + 692
33  BatchResizer2                 	0x000000010011deac PhotoAlbumViewController.collectAlbums() -> () (PhotoAlbumViewController.swift:248)
34  BatchResizer2                 	0x000000010011e4f0 PhotoAlbumViewController.applicationDidBecomeActive(Notification) -> () (PhotoAlbumViewController.swift:358)
35  BatchResizer2                 	0x000000010011f50c @objc PhotoAlbumViewController.applicationDidEnterBackground(Notification) -> () + 68
36  CoreFoundation                	0x00000001891b95ec __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
37  CoreFoundation                	0x00000001891b8d00 _CFXRegistrationPost + 400
38  CoreFoundation                	0x00000001891b8a7c ___CFXNotificationPost_block_invoke + 60
   :             :

 

スタックトレースのアドレスが、該当メソッド名に置き換わり、アプリのソースファイル名と行番号も出力されています。これで原因調査がやりやすくなりました。

 

 

もっと簡単なやり方

 

実は、symbolicatecrashを使わなくても、クラッシュログを簡単にシンボリケートする方法があります。

Xcodeにデバイスを繋いだ状態で、「Window」->「Devices」を開き、デバイスを選択して、「View Device Logs」をクリックします。

 

image_4.jpg

 

表示されたデバイスログ画面にクラッシュログをドラッグ&ドロップするとログが追加されます。追加した直後はまだシンボリケートされていませんが、暫くすると自動的にシンボリケートされます。

 

image_5.jpg

 

暫くすると...

 

image_6.jpg

 

シンボリケートされたログが表示されました。

 

こちらのやり方の方が簡単ですね。