NSDictionary allKeys崩溃 - 无法理解崩溃报告的情况

时间:2012-03-06 18:06:27

标签: objective-c ios crash crash-reports

我有以下代码:

- (Item *) getRandomItem {
    if (itemIDs == nil) {
        [self parse];
    }
    NSArray * allKeys = [allItems allKeys];
    int seed = arc4random()%[allKeys count];
    return [self getItemByID:[allKeys objectAtIndex:seed]];
}

它有时在实时应用程序崩溃,但我们无法重现崩溃。我一直试图分析报告并了解可能导致崩溃的原因,但我还没有成功。我试图篡改allItems对象以产生崩溃的任何方式导致与此处报告的错误不同的错误。

我想帮助了解在什么情况下会发生以下崩溃:

Hardware Model:      iPhone3,1
Code Type:       ARM (Native)
Parent Process:  launchd [1]
OS Version:      iPhone OS 5.0.1 (9A405)
Report Version:  104
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00000010
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x3427eb30 _class_isInitialized
1   libobjc.A.dylib                 0x3427e8d6 _class_initialize
2   libobjc.A.dylib                 0x3427e88e prepareForMethodLookup
3   libobjc.A.dylib                 0x3427e76a lookUpMethod
4   libobjc.A.dylib                 0x3427e008 objc_msgSend_uncached
5   CoreFoundation                  0x33f7c020 CFRetain
6   CoreFoundation                  0x33f85bac +[__NSArrayI __new::]
7   CoreFoundation                  0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:]
8   CoreFoundation                  0x33f85806 +[NSArray arrayWithObjects:count:]
9   CoreFoundation                  0x33fa0e92 -[NSDictionary allKeys]
10  AClockworkBrain                 0x0008f46e -[ItemManager getRandomItem] (ItemManager.m:360)
......

谢谢。

2 个答案:

答案 0 :(得分:9)

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x3427eb30 _class_isInitialized
1   libobjc.A.dylib                 0x3427e8d6 _class_initialize
2   libobjc.A.dylib                 0x3427e88e prepareForMethodLookup
3   libobjc.A.dylib                 0x3427e76a lookUpMethod
4   libobjc.A.dylib                 0x3427e008 objc_msgSend_uncached
5   CoreFoundation                  0x33f7c020 CFRetain
6   CoreFoundation                  0x33f85bac +[__NSArrayI __new::]
7   CoreFoundation                  0x33f85ac6 -[__NSPlaceholderArray initWithObjects:count:]

此崩溃是过度释放或损坏的签名。具体来说,词典中的一个键已被过度释放和/或损坏。特别是,isa指针现在指向垃圾。

allKeys尝试创建所有键的临时数组时,它会尝试保留损坏的对象(通过CFRetain,但将其视为对retain的调用)。运行时不会将isa指针识别为初始化类(因为它指向垃圾)并且它尝试在该“类”上调用initialize,从而导致崩溃。

现在,碰巧损坏的isa可能是一个指向可读但是垃圾,菜单的值,这会导致运行时深层次崩溃。最常见的是,这是因为对象被过度释放,然后一些结构恰好是malloc()在同一位置,并且该结构碰巧有一个指针作为第一个条目,这是一个完全常见的结构模式。

要解决?

首先,运行分析器并修复它抱怨的任何问题。

接下来,检查该字典中键的对象的所有用法。看看你是否能找到可能发生过度释放的地方。

最后,尝试打开僵尸并查看是否可以重现崩溃。

答案 1 :(得分:-2)

如果你这样做会有帮助吗?

NSArray * allKeys = [NSArray arrayWithArray:[allItems allKeys]];