Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSDictionary allKeys crashes - Cannot understand crash report circumstances

I have the following code:

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

It sometimes crashes on the live app, but we cannot reproduce the crash. I've been trying to analyze the report and understand what might be the cause of the crash, but I haven't been successful. Any way I try to tamper the allItems object to produce a crash, results to a different error than the one reported here.

I would like some help understanding under what circumstances the following crash would occur:

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)
......

Thank you.

like image 771
dimitrios Avatar asked Mar 06 '12 18:03

dimitrios


1 Answers

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:]

This crash is the signature of an over-release or corruption. Specifically, one of the keys in your dictionary has been over-released and/or corrupted. In particular, the isa pointer now points to garbage.

When allKeys tries to create a temporary array of all the keys, it tries to retain the corrupt object (via CFRetain, but treat it like a call to retain). The runtime doesn't recognize the isa pointer as being an initialized class (because it is pointing to garbage) and it tries to call initialize on that "class", leading to the crash.

Now, it so happens that the corrupted isa is likely a value that points to readable, but garbage, menu and that leads to a crash a few layers deep in the runtime. Most commonly, it is because the object was over-released and then some structure happened to be malloc()'d at the same location and that structure happens to have a pointer as the first entry, which is a completely common pattern for structures.

To fix?

First, run the analyzer and fix any problems it complains about.

Next, inspect all uses of the objects that are keys in that dictionary. See if you can find where an over-release may happen.

Finally, try turning on zombies and seeing if you can reproduce the crash.

like image 119
bbum Avatar answered Sep 28 '22 10:09

bbum