2012-03-06 2 views
5

ho il seguente codice:NSDictionary allKeys crash - non può capire le circostanze relazione crash

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

A volte si blocca su App dal vivo, ma non siamo in grado di riprodurre l'incidente. Ho cercato di analizzare il report e capire quale potrebbe essere la causa del crash, ma non ho avuto successo. Qualsiasi modo in cui provo a manomettere l'oggetto allItems per produrre un arresto anomalo, si traduce in un errore diverso da quello riportato qui.

Vorrei un aiuto capire in quali circostanze si sarebbe verificato l'incidente seguente:

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

Grazie.

+0

Stai usando ARC o no? Questo sembra essere un errore relativo alla memoria. –

+1

Aspetta, stai cercando di aggiungere un intero crudo al tuo dizionario? Stai tentando di inviare un messaggio a un oggetto alla memoria 0x10, che sembra qualcosa che sarebbe un normale numero intero nella tua applicazione. –

+0

Richard, non stiamo usando ARC. – dimitrios

risposta

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

Questo incidente è la firma di un rilascio eccessivo o di corruzione. In particolare, una delle chiavi del dizionario è stata sovrascritta e/o danneggiata. In particolare, il puntatore isa ora punta alla spazzatura.

Quando allKeys tenta di creare un array temporaneo di tutte le chiavi, si cerca di mantenere l'oggetto danneggiato (via CFRetain, ma trattarlo come una chiamata a retain). Il runtime non riconosce il puntatore isa come una classe inizializzata (perché punta alla spazzatura) e tenta di chiamare initialize su quella "classe", causando l'arresto anomalo.

Ora, succede che il file corrotto isa sia probabilmente un valore che punta a leggibile, ma garbage, menu e che porta a un arresto anomalo alcuni livelli in profondità nel runtime. Più comunemente, è perché l'oggetto è stato sovrascritto e quindi una struttura si è verificata per essere malloc() nella stessa posizione e quella struttura ha un puntatore come prima voce, che è un modello completamente comune per le strutture.

Da riparare?

In primo luogo, eseguire l'analizzatore e risolvere gli eventuali problemi che si lamenta.

Avanti, ispezionare tutti gli usi degli oggetti che sono chiavi in ​​quel dizionario. Vedi se riesci a trovare dove può verificarsi una sovra-pubblicazione.

Infine, cercare di accendere zombie e vedere se è possibile riprodurre il crash.

+0

bbum grazie per una risposta così dettagliata. Non ho conoscenza di tutte queste informazioni di basso livello, ma sembra davvero che tu lo faccia. Lo studieremo attentamente. Grazie ancora! – dimitrios

+1

Questo incidente mi è successo perché ho chiamato '[myDict allKeys]' su un thread diverso da quello in cui gli oggetti venivano gestiti. Come dice questa risposta, erano i puntatori agli oggetti deallocati. – stevel

-2

aiuta se lo fai?

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

Perché questo aiuto? – Chuck

+0

Non sarebbe d'aiuto. – bbum

+0

Non avrei dovuto rispondere in fretta. Avrei dovuto aggiungerlo nel commento, mio ​​male! –