これまでのところ、ログ スニペットをクラッシュ ログに追加することはうまくいったので、これを回答として追加します。(より良い答えは大歓迎です:-))
準備:
ソース コードの関連する場所に callStackSymbols ロギングを追加します。
NSLog(@"call stack:\n%@", [NSThread callStackSymbols]);
アプリをクラッシュさせます (たとえば、特定の画面を開いたとき):
strcpy(0, "000");
ログ出力をファイルにリダイレクトします。
FILE *logfile = freopen([pathForLog cStringUsingEncoding:NSASCIIStringEncoding], "a+", stderr);
実行:
Xcode でアプリを 1 回実行すると、アプリがデバイスにインストールされてから停止します。次に、デバイスでアプリを直接起動して、Xcode がクラッシュをキャッチしないようにします。
アプリを使用して、コール スタックがログに記録されるようにします (何度でも可能です)。
最終的にアプリをクラッシュさせます (私の場合、悪い strcpy を呼び出す特定の画面を開きます)。
ファイルの取得:
Xcode で「ウィンドウ -> デバイス」を開き、デバイスを選択し、アプリを選択してアプリ コンテナーをダウンロードすると、ログ ファイルを抽出できるようになります。
同じ画面でデバイス ログを開き、クラッシュ ログをエクスポートします。
Xcode で [ウィンドウ -> プロジェクト] を開き、プロジェクトを選択して、派生データ フォルダーを Finder に表示します (派生データ パスの右側にある小さな矢印ボタン)。派生データ フォルダーで、"Build/Products/Debug-iphoneos/" に移動し、MyApp.app と MyApp.app.dSYM をコピーします。
クラッシュ ログを調整します。
私にとっては、「バイナリ イメージ:」の直前に余分なスレッド セクションを追加することでうまくいきました。「Binary Images:」の場所を見つけます。「Thread 9999:」という行を挿入します。コール スタック ダンプをコピーして貼り付け、先頭の空白列を削除して、次のようにします。
2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999:
0 MyApp 0x00000001001d95f8 -[MyClass myMethod:] + 100
1 UIKit 0x000000018a5fc2ac <redacted> + 172
2 UIKit 0x000000018a5d5ca4 <redacted> + 88
3 UIKit 0x000000018a5d5b8c <redacted> + 460
4 UIKit 0x000000018a5d5cc0 <redacted> + 116
5 UIKit 0x000000018a5d5b8c <redacted> + 460
6 UIKit 0x000000018a5d5cc0 <redacted> + 116
7 UIKit 0x000000018a5d5b8c <redacted> + 460
8 UIKit 0x000000018a8e85ac <redacted> + 460
9 UIKit 0x000000018a5d4abc <redacted> + 96
10 UIKit 0x000000018a935b7c <redacted> + 344
11 UIKit 0x000000018a9306f8 <redacted> + 124
12 UIKit 0x000000018aa584d8 <redacted> + 44
13 UIKit 0x000000018a933d9c <redacted> + 188
14 UIKit 0x000000018a70b668 <redacted> + 116
15 UIKit 0x000000018a70b454 <redacted> + 252
16 UIKit 0x000000018a70af38 <redacted> + 1404
17 UIKit 0x000000018a70a9a8 <redacted> + 124
18 UIKit 0x000000018a616d3c <redacted> + 312
19 UIKit 0x000000018a616bc4 <redacted> + 108
20 QuartzCore 0x0000000189dddc2c <redacted> + 284
21 libdispatch.dylib 0x000000019a3a96a8 <redacted> + 16
22 libdispatch.dylib 0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844
23 CoreFoundation 0x00000001850001f8 <redacted> + 12
24 CoreFoundation 0x0000000184ffe060 <redacted> + 1628
25 CoreFoundation 0x0000000184f2cca0 CFRunLoopRunSpecific + 384
26 GraphicsServices 0x000000018ff94088 GSEventRunModal + 180
27 UIKit 0x000000018a644ffc UIApplicationMain + 204
28 MyApp 0x0000000100093918 main + 124
29 libdyld.dylib 0x000000019a3da8b8 <redacted> + 4
Binary Images:
...
「Thread 9999:」行により、symbolicatecrash
スクリプトは次の行を記号化する必要があります。私は 9999 を選択したので、これらが追加されたセクションであることがわかります。
シンボリケーションを実行します。
symbolicatecrash
スクリプトを見つけます。
$ find /Applications/Xcode.app -name symbolicatecrash -type f
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash
$
シンボリック コマンドは、次のようになります。
$ symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash
DEVELOPER_DIR を設定し、スクリプトへのパスを追加する必要があるため、最終的には次のようになります。
$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash
または、見やすくするためにラップします。
$ DEVELOPER_DIR='/Applications/Xcode.app/Contents/Developer' ...
/Applications/Xcode.app/Contents/SharedFrameworks/ ...
DTDeviceKitBase.framework/Versions/A/Resources/ ...
symbolicatecrash myapp.crash MyApp.app.dSYM > myapp-sym.crash
結果:
シンボリック スニペットは次のようになります。
2015-12-09 15:28:58.971 MyApp[21376:3050653] call tree (
Thread 9999:
0 MyApp 0x00000001001d95f8 -[MyClass myMethod:] (MyFile.m:15)
1 UIKit 0x000000018a5fc2ac -[UIScrollView _willMoveToWindow:] + 172
2 UIKit 0x000000018a5d5ca4 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 88
3 UIKit 0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460
4 UIKit 0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116
5 UIKit 0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460
6 UIKit 0x000000018a5d5cc0 __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke + 116
7 UIKit 0x000000018a5d5b8c -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:] + 460
8 UIKit 0x000000018a8e85ac __UIViewWillBeRemovedFromSuperview + 460
9 UIKit 0x000000018a5d4abc -[UIView(Hierarchy) removeFromSuperview] + 96
10 UIKit 0x000000018a935b7c __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke596 + 344
11 UIKit 0x000000018a9306f8 -[UIPresentationController transitionDidFinish:] + 124
12 UIKit 0x000000018aa584d8 -[_UICurrentContextPresentationController transitionDidFinish:] + 44
13 UIKit 0x000000018a933d9c __56-[UIPresentationController runTransitionForCurrentState]_block_invoke_2 + 188
14 UIKit 0x000000018a70b668 -[_UIViewControllerTransitionContext completeTransition:] + 116
15 UIKit 0x000000018a70b454 -[UITransitionView notifyDidCompleteTransition:] + 252
16 UIKit 0x000000018a70af38 -[UITransitionView _didCompleteTransition:] + 1404
17 UIKit 0x000000018a70a9a8 -[UITransitionView _transitionDidStop:finished:] + 124
18 UIKit 0x000000018a616d3c -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
19 UIKit 0x000000018a616bc4 -[UIViewAnimationState animationDidStop:finished:] + 108
20 QuartzCore 0x0000000189dddc2c CA::Layer::run_animation_callbacks(void*) + 284
21 libdispatch.dylib 0x000000019a3a96a8 _dispatch_client_callout + 16
22 libdispatch.dylib 0x000000019a3aedb0 _dispatch_main_queue_callback_4CF + 1844
23 CoreFoundation 0x00000001850001f8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
24 CoreFoundation 0x0000000184ffe060 __CFRunLoopRun + 1628
25 CoreFoundation 0x0000000184f2cca0 CFRunLoopRunSpecific + 384
26 GraphicsServices 0x000000018ff94088 GSEventRunModal + 180
27 UIKit 0x000000018a644ffc UIApplicationMain + 204
28 MyApp 0x0000000100093918 main (main.m:16)
29 libdyld.dylib 0x000000019a3da8b8 <redacted> + 4
Binary Images:
...
もっと簡単なアプローチが見つからない限り、これが今のところ私にとっての方法です。ログ ファイルからコール スタックを取得し、先頭の空白を削除してクラッシュ ログに挿入するスクリプトを作成すると便利な場合があります。