web-dev-qa-db-ja.com

Xcode 4.2 / iOS 5のコンソールに例外スタックトレースはありませんか?

Xcode 3.xとiOS 4では、未処理の例外がエミュレーターで通知された場合、コンソール出力に例外スタックトレース(Javaに類似)が生成されます。

Xcode 4.2のiOS 5で未処理の例外を発生させ、まったく同じアプリコードを実行すると、スタックトレースが発生しません。 (私は例外ブレークポイントを設定する方法を理解しましたが、それはコンソールにトレースバックを生成しません。)

これは、どこかで作成する必要があるXcode設定ですか、それともXcode 4/iOS 5の「機能」ですか?このビットの機能を復元する方法はありますか?

更新

残念ながら、uncaughtExceptionHandlerを追加しても機能しません。ここにハンドラがあります:

void uncaughtExceptionHandler(NSException *exception) {
    NSLog(@"uncaughtExceptionHnadler -- Exception %@", [exception description]);
    // Because iOS 5 doesn't provide a traceback, provide one here
    NSLog(@"Stack trace: %@", [exception callStackSymbols]);
    // Let Flurry look at the error
    [FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}                                               

(Flurryを実行するために、既に存在していたことが判明したので、スタックトレースを追加しました。)

これが有効化されている場所です(ハンドラーが宣言されている場所のほんの数行下)。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // Enable uncaught exception handler to dump stack and let Flurry log the exception
    NSUncaughtExceptionHandler* hdlr = NSGetUncaughtExceptionHandler();
    NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
    NSUncaughtExceptionHandler* newHdlr = NSGetUncaughtExceptionHandler();

    // TODO: Test
    NSException* ex = [NSException exceptionWithName:@"AssertionFailure" reason:@"Test" userInfo:nil]; 
    @throw ex; 

取得した2つのハンドラー値をチェックできるように、ブレークポイントを設定しました。最初のものはnilで、2番目は明らかに有効なアドレスです。ただし、テスト例外がスローされると、ハンドラー(iOS 5シミュレーター内)が制御を取得することはありません。 (ただし、iOS 4.2シミュレーターで実行すると、制御を取得します。)

IPhoneではNSExceptionHandlingMaskを設定することはできません。前提条件ExceptionHandling.framework 利用できません。

アップデート2

これは機能します:

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = -1;
    @try {
        retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch (NSException* exception) {
        NSLog(@"Uncaught exception: %@", exception.description);
        NSLog(@"Stack trace: %@", [exception callStackSymbols]);
    }
    [pool release];
    return retVal;
}
48
Hot Licks

これは機能します:

int main(int argc, char *argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = -1;
    @try {
        retVal = UIApplicationMain(argc, argv, nil, nil);
    }
    @catch (NSException* exception) {
        NSLog(@"Uncaught exception: %@", exception.description);
        NSLog(@"Stack trace: %@", [exception callStackSymbols]);
    }
    [pool release];
    return retVal;
}

ARCの場合:

int main(int argc, char *argv[]) {

    int retVal = -1;
    @autoreleasepool {
        @try {
            retVal = UIApplicationMain(argc, argv, nil, nil);
        }
        @catch (NSException* exception) {
            NSLog(@"Uncaught exception: %@", exception.description);
            NSLog(@"Stack trace: %@", [exception callStackSymbols]);
        }
    }
    return retVal;
}

デフォルトのダンプが機能しなくなった理由や、(さらに深刻な)uncaughtExceptionHandlerが機能しない理由について、何らかの説明を待っています。ただし、明らかにこの問題はエミュレータにのみ影響します。

更新:

製品->スキーム->スキームの編集に移動し、「実行(デバッグ)」を選択し、「診断」タブを選択し、「例外のログ」をクリックすると、不足しているXcodeのデフォルトの例外ログが復元されることが指摘されています。 、おそらく(私はまだ試していません)上記のハックの必要性を排除します。

36
Hot Licks

これは既知の問題です...回避策については here および here を参照してください。

別のオプションは

defaults write NSGlobalDomain NSExceptionHandlingMask 63

これは通常OSX向けですが、エミュレータを使用するときに役立つ場合があります-私は今は試すことができません:-(

2
Yahia

同じ問題がありましたが、「Compile for Thumb」を有効に戻しました。注:明らかな理由により、デバッグ構成に対してのみオンに戻しました。

1
Bradweiser86