1

次のスタック トレースでアプリがクラッシュします。

Thread : Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x39dfa66a objc_release + 9
1  libobjc.A.dylib                0x39dfb0d7 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 358
2  CoreFoundation                 0x2f4a6c69 _CFAutoreleasePoolPop + 16
3  CoreFoundation                 0x2f53c1cb __CFRunLoopRun + 1306
4  CoreFoundation                 0x2f4a6f0f CFRunLoopRunSpecific + 522
5  CoreFoundation                 0x2f4a6cf3 CFRunLoopRunInMode + 106
6  GraphicsServices               0x343ff663 GSEventRunModal + 138
7  UIKit                          0x31df216d UIApplicationMain + 1136
8  Batted                         0x0009db07 main (main.m:16)

クラッシュは、Scheme の診断オプションでゾンビが有効になっていない場合に発生します。ただし、有効にすると、クラッシュは発生しません。

これに関する他の Q&A をいくつか読みましたが、いずれも、この動作が確認されたら、ゾンビを有効にして、シミュレーターでゾンビ プロファイル インストゥルメントを実行するようアドバイスしているようです。

私はそれを試しましたが、Instruments は何も問題を示していないようで、アプリは動作します。この問題の根本原因を突き止めるために、ここで他に何ができるかの手がかりはありますか? シミュレーターで iOS 7.1 で XCode 5.1 を使用しています。

更新 1

問題の原因となっている問題のあるコードが見つかりましたが、なぜそれが問題を引き起こしているのかはまだわかりません。私は CoreData を使用しており、NSManagedObject のサブクラスには -

- (void)willTurnIntoFault;
{
    [super willTurnIntoFault];

    if ([self observationInfo])
    {
        BNLogInfo(@"%@ has observers:\n%@", [self objectID], [self observationInfo]);
    }
}

上記のコードで[self observationInfo]は、問題のある行です。

アプリが起動すると、列挙ブロック内の NSManagedObjects のいくつかをループし、いくつかのプロパティを設定します。これにより、willTurnIntoFaultメソッドが起動されます。列挙ブロックが完了すると、クラッシュが発生します。

謎は、このメソッド内でクラッシュが発生しないことですが、このメソッドをサブクラス化しないと、すべて正常に動作します。

4

1 に答える 1

2

ゾンビはしばしばこの種のエラーを引き起こすため、Q&A はゾンビを有効にする (またはゾンビ インストルメントの下で実行する) ように言います。

しかし、それだけが原因ではありません。

プログラムがヒープを破損しています。ほとんどのisa場合、自動解放プールにあるオブジェクトのポインター (クラス ポインター) を上書きしているため、実行ループが自動解放プールを空にするときにobjc_release、偽のisaポインターを逆参照しようとしてクラッシュします。

ゾンビを有効にすると、このようなエラーを隠すことができます。これは、ゾンビを使用すると、ランタイムが実際にオブジェクトを解放しないためです。これは、(ゾンビにメッセージを送信しようとしない限り) ヒープの多くの部分が使用されないことを意味するため、それらを破損しても問題が発生することはありません。

この種のクラッシュはデバッグが非常に難しい場合がありますが、「guard malloc」と呼ばれるツールが役立つ場合があります。メニュー バーから、[製品] > [スキーム] > [スキームの編集] を選択します。左側のリストで実行アクションをクリックします。次に、[診断] タブをクリックします。「Guard Malloc を有効にする」オプションをオンにします。次に、クラッシュの再現を試みます。ガード malloc は、特定の種類のヒープの破損を即座に検出し、破損した命令でプログラムを停止します。

于 2014-06-12T22:58:34.263 に答える