2011年 10月 18日(火曜日) 14:56

iOSデバイスのクラッシュログを読むには

評価:
(1 Vote)

iOSでアプリがクラッシュしたときに出力されるログの読み方をまとめました。

1. クラッシュログファイルを探す

iOSアプリがデバイス上でクラッシュしたとき、デバイス上に自動でクラッシュログが生成されています。これを使えば、デバッガで接続していない状態でクラッシュした時でも、クラッシュの原因を調べることができます。

クラッシュログは、アプリがクラッシュしたデバイスを一度iTunesでMacかPCに接続して同期すると、デバイスから次の場所にコピーされます。

Macの場合:

~/Library/Logs/CrashReporter/MobileDevice

Windows Vista/7の場合:

C:\Users\<user_name>\AppData\Roaming\Apple computer\Logs\CrashReporter/MobileDevice

Windows XPの場合:

C:\Documents and Settings\<user_name>\Application Data\Apple computer\Logs\CrashReporter

これらの下に、デバイスごとのディレクトリがあり、その下に*.crashというファイルが生成されます。

(参照:iOS App Development Workflow Guide > Distributing Applications > Instructions for Application Testers

例えば私のつくっているSimpleWeightというアプリがiPod1というデバイスでクラッシュしたときのログはこんな感じ。

~/Library/Logs/CrashReporter/MobileDevice/iPod1/SimpleWeight_2011-10-17-234954_iPod1.crash

このファイルをテキストエディタで開いてみると、中身はこんな感じでした。

Incident Identifier: CAF9ED40-2D59-45EA-96B0-52BDA1115E9F
CrashReporter Key:   30af939d26f6ecc5f0d08653b2aaf47933ad8b8e
Process:         SimpleWeight [12506]
Path:            /var/mobile/Applications/60ACEDBC-600E-42AF-9252-42E32188A044/SimpleWeight.app/SimpleWeight
Identifier:      SimpleWeight
Version:         ??? (???)
Code Type:       ARM (Native)
Parent Process:  launchd [1]

Date/Time:       2011-10-17 23:15:41.678 +0900
OS Version:      iPhone OS 3.1.3 (7E18)
Report Version:  104

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000059
Crashed Thread:  0

Thread 0 Crashed:
0   UIKit                         	0x332b98d8 0x331b2000 + 1079512
1   UIKit                         	0x3321d1a8 0x331b2000 + 438696
2   UIKit                         	0x3321d028 0x331b2000 + 438312
3   UIKit                         	0x332b9628 0x331b2000 + 1078824
4   UIKit                         	0x33209d70 0x331b2000 + 359792
5   UIKit                         	0x33209c08 0x331b2000 + 359432
6   QuartzCore                    	0x324cc05c 0x324ae000 + 122972
7   QuartzCore                    	0x324cbe64 0x324ae000 + 122468
8   CoreFoundation                	0x3244f4bc 0x323f8000 + 357564
9   CoreFoundation                	0x3244ec18 0x323f8000 + 355352
10  GraphicsServices              	0x342e91c0 0x342e5000 + 16832
11  UIKit                         	0x331b5c28 0x331b2000 + 15400
12  UIKit                         	0x331b4228 0x331b2000 + 8744
13  SimpleWeight                  	0x00002c3a 0x1000 + 7226
14  SimpleWeight                  	0x00002c04 0x1000 + 7172


... (以下略)

デバイスの情報に加えて、クラッシュしたときのスレッド毎のスタックトレースが出力されているようですが、これだけではどこでクラッシュしたのか全くわからなくて役に立ちませんね。。。

2..dSYMファイルを探す

クラッシュしたアプリをXcodeでビルドしたときのビルドフォルダの下に、[アプリ名].app.dSMYというファイルがあり、ここにシンボルの情報が保存されていて、これを使うと、上のクラッシュログのシンボルを解決することができます。

Xcode 4のビルドフォルダは、デフォルトでは、

~/Library/Developer/Xcode/DerivedData

の下にあります。(実際の場所は、XcodeのPreferences... -> Locations -> LocationsのDerived Dataで確認できます。)

ちょっと探しにくいですが、DerivedDataフォルダの下で.dSYMを検索するのが早いかも。

% cd ~/Library/Developer/Xcode/DerivedData
% find . -name '*.dSYM'

または、XcodeのProductsの下にできるアプリの実行ファイルを右クリックして、"Show in Finder"で実行ファイルの場所を開き、そこから遡って探していくのもよいかも。

今回の例では、次の場所にありました。

~/Library/Developer/Xcode/DerivedData/SimpleWeight-aahmlrjpobenlsdvhjppcfqhogru/ArchiveIntermediates/SimpleWeight/BuildProductsPath/Release-iphoneos/SimpleWeight.app.dSYM

この*.dSYMファイルがないと、クラッシュログの解析が難しくなってしまいますので、特にリリースしたビルドの*.dSYMファイルは必ずとっておくようにするべきです。私はいつもAppStoreにサブミットするビルドの直後にスナップショットをとるようにしています。

3. "symbolicatecrash"スクリプトを実行して、シンボルを解決する

.dSYMファイルを使ってクラッシュログのシンボルを解決するスクリプト"symbolicatecrash"が、Xcodeに付属しています。

私の環境(Xcode 4.2)では、次の場所にありました。

/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash

この場所にパスが通っていない場合は、パスに追加しておくか、パスが通っている場所にスクリプトをコピーするかしておくとよろしいかと思います。

  • クラッシュログファイル(*.crash)
  • dSYMファイル
  • symbolicatecrashスクリプト

の3つがそろったら、ターミナルから次のコマンドを実行すると、シンボルを解決した結果がコンソールに出力されます。

% symbolicatecrash [クラッシュログファイル] [dSYMファイル]

例えば、上の例のクラッシュログは、

% symbolicatecrash SimpleWeight_2011-10-17-231541_iPod1.crash SimpleWeight.app.dSYM

を実行して、次のように解決されました。(結果が出力されるまでちょっと時間がかかるので、気長に待ちましょう。)

Thread 0 Crashed:
0   UIKit                         	0x332b98d8 -[UIWindowController transitionViewDidComplete:fromView:toView:] + 668
1   UIKit                         	0x3321d1a8 -[UITransitionView notifyDidCompleteTransition:] + 160
2   UIKit                         	0x3321d028 -[UITransitionView _didCompleteTransition:] + 704
3   UIKit                         	0x332b9628 -[UITransitionView _transitionDidStop:finished:] + 44
4   UIKit                         	0x33209d70 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 284
5   UIKit                         	0x33209c08 -[UIViewAnimationState animationDidStop:finished:] + 60
6   QuartzCore                    	0x324cc05c _ZL23run_animation_callbacksdPv + 440
7   QuartzCore                    	0x324cbe64 _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 156
8   CoreFoundation                	0x3244f4bc CFRunLoopRunSpecific + 2192
9   CoreFoundation                	0x3244ec18 CFRunLoopRunInMode + 44
10  GraphicsServices              	0x342e91c0 GSEventRunModal + 188
11  UIKit                         	0x331b5c28 -[UIApplication _run] + 552
12  UIKit                         	0x331b4228 UIApplicationMain + 960
13  SimpleWeight                  	0x00002c3a main (main.m:14)
14  SimpleWeight                  	0x00002c04 0x1000 + 7172

スタックトレースのメソッド名と行番号が解決されているのがわかります。

今回もこれでどこでクラッシュしたのかが特定でき、問題を解決することができました。

 

この方法で、Ad Hocビルドでテスターの方にテストしてもらったり、iTunes Connectに寄せられたクラッシュログを解析して、問題の修正に役立てることができます。特に、リリース後にユーザーの方から原因不明で「落ちる」と報告されたり、レビューに書かれたりして再現ができない時などには、クラッシュログが入手できると非常に有用です。

最終更新日: 2012年 4月 30日(月曜日) 12:19
くらち たかよし

くらち たかよし

モバイル・Webアプリ作家。最近は主にiPhoneアプリ制作を手がける。企画から、UIデザイン、設計、実装、テスト、多言語対応、ユーザーサポートまでを1人〜数人の個人で行う全人的開発手法の確立を目指している。

使う言語はObjective-C, C++, C#, Java, PHPなど。Web関連で使うものはCakePHP, MySQL, Joomla! CMSなど。デザインはシロウトながらPhotoshopとIllustratorをなんとかがんばって使う。

場所や時間に縛られない、インターネット時代の新しい働き方、自由な生き方を模索中。海外移住、低予算&低リスク起業、キャリアデザイン、心理学などにも興味あり。

Web: awaresoft.jp/