クラッシュ時のスタックトレース取得方法

iOS開発において、クラッシュした場所の検討がつかない場合がありました。
いろいろ調べてみると、NSSetUncaughtExceptionHandlerにハンドラ関数のポインタを渡すと、クラッシュ時のスタックトレースが取得できるようです。 以下のコードはその実装例。
@implementation AppDelegate

void exceptionHandler(NSException *exception) {
    NSLog(@"Exception: %@", exception);
    NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSSetUncaughtExceptionHandler(&exceptionHandler);
    return YES;
}

@end

以下のコードで無理やりExceptionを発生してみました。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSSetUncaughtExceptionHandler(&exceptionHandler);

    //無理やりEcxeptionを発生させる。
    NSArray *array = [NSArray array];
    [array objectAtIndex:1];

    return YES;
}

出力結果は以下。

2013-07-15 19:21:45.415 ExceptionSample[27437:c07] Exception: *** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds for empty array
2013-07-15 19:21:45.417 ExceptionSample[27437:c07] Stack Trace: (
 0   CoreFoundation                      0x01c9002e __exceptionPreprocess + 206
 1   libobjc.A.dylib                     0x010cde7e objc_exception_throw + 44
 2   CoreFoundation                      0x01c45b44 -[__NSArrayI objectAtIndex:] + 196
 3   ExceptionSample                     0x00001f5f -[AppDelegate application:didFinishLaunchingWithOptions:] + 159
 4   UIKit                               0x0000f157 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 266
 5   UIKit                               0x0000f747 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1248
 6   UIKit                               0x0001094b -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 805
 7   UIKit                               0x00021cb5 -[UIApplication handleEvent:withNewEvent:] + 1022
 8   UIKit                               0x00022beb -[UIApplication sendEvent:] + 85
 9   UIKit                               0x00014698 _UIApplicationHandleEvent + 9874
 10  GraphicsServices                    0x01bebdf9 _PurpleEventCallback + 339
 11  GraphicsServices                    0x01bebad0 PurpleEventCallback + 46
 12  CoreFoundation                      0x01c05bf5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
 13  CoreFoundation                      0x01c05962 __CFRunLoopDoSource1 + 146
 14  CoreFoundation                      0x01c36bb6 __CFRunLoopRun + 2118
 15  CoreFoundation                      0x01c35f44 CFRunLoopRunSpecific + 276
 16  CoreFoundation                      0x01c35e1b CFRunLoopRunInMode + 123
 17  UIKit                               0x0001017a -[UIApplication _run] + 774
 18  UIKit                               0x00011ffc UIApplicationMain + 1211
 19  ExceptionSample                     0x00001ded main + 141
 20  ExceptionSample                     0x00001d15 start + 53
)
2013-07-15 19:21:45.426 ExceptionSample[27437:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 1 beyond bounds for empty array'
*** First throw call stack:
(0x1c90012 0x10cde7e 0x1c45b44 0x1f5f 0xf157 0xf747 0x1094b 0x21cb5 0x22beb 0x14698 0x1bebdf9 0x1bebad0 0x1c05bf5 0x1c05962 0x1c36bb6 0x1c35f44 0x1c35e1b 0x1017a 0x11ffc 0x1ded 0x1d15)

吐き出されたスタックトレースをみると、AppDelegate application:didFinishLaunchingWithOptions:のobjectAtIndexあたりでクラッシュしたことが確認できそうです。

コメント

このブログの人気の投稿

HealKit HKObjectType 一覧

Undefined symbols for architecture arm64