2015-02-22 9 views
5

Ho un problema molto particolare.iOS 64bit @try {...} @catch {...} non funziona

Recentemente ho aggiunto il supporto a 64 bit al mio progetto iOS (arm64), da quando ho iniziato a ricevere eccezioni non rilevate per segmenti del mio codice all'interno di @[email protected] (utilizzo Crashlytics per la segnalazione di arresti anomali). Sono riuscito a riprodurre il problema con le seguenti righe di codice da nessuna parte nella mia app (li ho scritto dentro init di uno dei miei controller di vista):

@try { 
    NSMutableDictionary *m = [[NSMutableDictionary alloc] init]; 
    NSString *s; 
    m[s] = @"poop"; 
} @catch (NSException *e) { 
    NSLog(@"POOP"); 
} 

L'eccezione viene catturato dalla UncaughtExceptionHandler al posto della clausola @catch. Sono confuso su cosa può causare questo. L'output nella console:

2015-02-22 19:19:53.525 [391:30650] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil' 
*** First throw call stack: 
(0x18823a59c 0x1989400e4 0x1881251f8 0x10011e2f4 0x10011e068 0x10010e480 0x10010db78 0x10010d944 0x1000a8050 0x100075d88 0x100075160 0x100142044 0x100141f6c 0x18c9ecaa0 0x18caa1fb4 0x18caa1eb0 0x18caa134c 0x18caa0ff8 0x18caa0d18 0x18caa0c98 0x18c9e9648 0x18c341994 0x18c33c564 0x18c33c408 0x18c33bc08 0x18c33b98c 0x18cc76dbc 0x18cc77c68 0x18cc75dec 0x1904b162c 0x1881f2a28 0x1881f1b30 0x1881efd30 0x18811d0a4 0x18ca573c8 0x18ca523c0 0x1000747d8 0x198faea08) 
libc++abi.dylib: terminating with uncaught exception of type NSException 

Ho provato a rimuovere il gestore di eccezioni personalizzato che ho e invalidante Crashlytics, ancora senza successo.

Non appena rimuovo arm64 da ARCHS e VALID_ARCHS il codice funziona e l'eccezione viene rilevata come previsto.

Qualsiasi informazione sarà apprezzata!


Piccolo aggiornamento - i nostri XCTests anche iniziato a non intercettare le eccezioni, fino ad ora il comportamento è accaduto solo su telefoni a 64 bit fisici.

+0

gestione delle eccezioni cambiato semantica tra 32 bit e 64 bit. Potrebbe, tecnicamente, funzionare ancora, probabilmente. Si potrebbe "aggiustarlo" usando '@catch (id e)'. Ma non farlo; usare le eccezioni per il controllo del flusso - per provare a recuperare dagli errori - non è un modello accettabile in iOS. – bbum

+1

@bbum Non sto usando le eccezioni per il controllo del flusso, questa è una domanda sulla differenza tra 32 bit e 64 bit e perché il comportamento di @try .. @ catch è diverso. usare '@catch (id e)' o '@catch (...)' non funziona. –

+0

Ok - dispari, allora. @gparker lo saprebbe. – bbum

risposta

4

Dopo una lunga sessione di git-bisettrice il colpevole era il seguente bandiera linker

-no_compact_unwind

ho usato BlocksKit v2.2.0 che aveva ancora quella bandiera, anche se ha smesso di usare libffi (ultima versione di BlocksKit rimosso quella bandiera non necessaria). Appena ho rimosso quel flag di linker 64 bit @[email protected] i blocchi hanno iniziato a funzionare di nuovo.

Ancora non ho una completa comprensione del motivo per cui questo comportamento si verifica, ma ho intenzione di scavare un po 'di più e aggiornare questo thread se trovo qualcosa di interessante.

phew

+0

puoi spiegare in dettaglio? Dove aggiungere/rimuovere la bandiera sopra? Come ho provato in "Other Linker Flags" ma non funziona.Pls help – milanpanchal

+1

@milanpanchal la bandiera è stata aggiunta da 'libffi', penso di aver rimosso manualmente quel flag dal progetto pod di' libffi' ma oggi 'BlocksKit' non richiede' libffi' quindi non dovresti avere problemi. Prova a fare 'git grep no_compact_unwind' per trovare dove lo usi –

+0

grazie! BTW. Qual è la ragione profonda di questo problema? – kimimaro

1

Su iOS e Objective-C Le eccezioni devono essere utilizzate solo per errori di programmazione non recuperabili, non per il controllo di esecuzione del programma.

In particolare, non gestiscono le catture su frame di stack nelle API.

+4

Non sto usando eccezioni per il controllo di esecuzione/flusso. Questa è una domanda sul cambio di comportamento tra 32 bit e 64 bit. –