Xcode non mostra la linea che causa un arresto anomalo


126

Ogni volta che la mia app si arresta in modo anomalo, Xcode evidenzia la chiamata UIApicationMain () nella funzione main () come linea che ha causato l'incidente. In alcuni casi ciò era normale (ad esempio un errore di segmentazione), ma l'incidente che sto cercando di gestire è un semplice SIGABRT con informazioni dettagliate registrate nella console:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'

Xcode usato per mostrare la linea giusta con SDK più vecchi, ma da quando ho aggiornato a Xocde 4.2 che è cambiato. È abbastanza ovvio che Xcode sa esattamente cosa ha causato l'incidente (o potrebbe saperlo), ma non mostra ancora la riga effettiva. C'è qualche soluzione o soluzione per questo?


2
Stai compilando per Release? In tal caso, prova a impostare lo schema su Debug.
epatel,

Potrebbe anche essere che alcuni xib non funzionino correttamente causando l'arresto anomalo del programma in un punto fuori dal proprio codice sorgente, quindi non mostrando alcun file. L'errore descrive un problema per una chiave del dizionario denominata "Date"
epatel

1
Apple dovrebbe assumere più tester;)
Amr Lotfy,

Risposte:


301

È inoltre necessario assicurarsi che siano impostati i punti di interruzione per tutte le eccezioni. Ciò causerà l'arresto di Xcode sulla riga in cui si verifica l'eccezione. Effettuate le seguenti operazioni [in Xcode 4]:

  1. Nel Project Navigator sul lato sinistro di Xcode, fai clic sul navigatore breakpoint (quasi fino al lato destro della barra dei pulsanti in alto. L'icona appare come una grossa freccia destra).

  2. Nella parte inferiore del navigatore, fai clic sul pulsante "+".

  3. Fai clic su "Aggiungi punto di interruzione eccezione".

  4. Verrà creato un nuovo punto di interruzione. Dovrebbe essere configurato come necessario ma è possibile modificarne il comportamento.

  5. Esegui il tuo progetto e riproduci l'eccezione.

Hai anche detto che ti sei collegato ad alcune librerie / framework di terze parti. Se l'eccezione si sta verificando all'interno di tali framework, allora avrai difficoltà poiché il codice viene compilato e Xcode non può effettivamente mostrarti la riga che ha causato l'eccezione. In tal caso e si è certi di utilizzare correttamente le librerie, è necessario presentare una segnalazione di bug ai manutentori di tali librerie.


4
Sono un noob e sviluppato quasi un mese senza questo ... questo mi cambia la vita.
Jonny Burger,

4
Il mio amico ha registrato un account SO solo per votare questo post.
Alex Spencer,

1
questo è chiamato metà del culo sulla parte delle mele nel mio libro
ChuckKelly,

1
Ha fatto questo, ma ancora non riesco a trovare dove ha chiamato lunghezza su un null :(
Shereef Marzouk,

1
Funziona, ma il rovescio della medaglia è che non genera più i dettagli dell'eccezione nella console di debug. Quindi posso disattivare questo punto di interruzione e vedere i dettagli e la traccia dell'eccezione ma non DOVE è accaduto, oppure attivarlo per vedere dove è successo, ma senza PERCHÉ. Qualcuno sa come avere entrambi?
Gabriel Jensen,

27

Segui semplicemente le istruzioni su questa risposta StackOverflow:

Abilita gli zombi

Fondamentalmente, devi solo "Abilitare gli zombi". Quindi Xcode dovrebbe rompersi in qualunque riga abbia causato il problema.

inserisci qui la descrizione dell'immagine

(È assolutamente scioccante che, anche nel 2017, Xcode sia ancora disattivato per impostazione predefinita. Perché non dovresti vedere la linea che ha causato il problema? E " Abilita oggetti zombi "?! Davvero?! Gli autori di Xcode fanno davvero credi che questo sia un nome utile, che avrebbe qualche tipo di senso per i nuovi sviluppatori? È deprimente la scarsa valutazione di Xcode, anno dopo anno, nell'App Store. Nessuno sta ascoltando ...)


6
Xcode è il peggior ambiente di programmazione che ho usato finora.
Studente

Quello che trovo interessante (come sviluppatore di Visual Studio) è il numero di sviluppatori Xcode che ho incontrato, che insistono sul fatto che Xcode sia l'ambiente migliore che abbiano mai usato. Logico, gentile e disponibile .. ma con alcune stranezze. Anche ora, a novembre 2019, Xcode ha una valutazione di App Store di 3,1, con la maggior parte delle persone che gli ha assegnato 5 stelle o 1 stella. Nessuno sta ascoltando ....
Mike Gledhill,

9

Modifica del regime attuale e attivare NSZombieEnabled, MallocStackLogginge guard malloc. Quindi, quando l'app si arresta in modo anomalo, digita questo nella console gdb:

(gdb) info malloc-history 0x543216

Sostituisci 0x543216con l'indirizzo dell'oggetto che ha causato il NSInvalidArgumentExceptione dovrebbe darti una traccia dello stack molto più utile, mostrando le linee del tuo codice che stanno causando il crash.


1
Ho provato questo, e mi è stato lanciato l'errore: 'info' non è un comando valido. Qualche consiglio?
achi

@EliGregory assicurati che il tuo debugger sia impostato su gdb e non su lldb predefinito. Puoi cambiarlo nel menu Modifica schema nella sezione Esegui.
vestito

2

Ho visto questo comportamento in un codice fortemente ottimizzato; il controllo, l'ottimizzazione del livello di ottimizzazione del target e quelli delle librerie di terze parti possono aiutare. (Impostazione del livello di ottimizzazione LLVM 3.0)

Stai generando simboli di debug?


Concordato. Se stai tentando di eseguire il debug, il livello di ottimizzazione deve essere impostato su 0 (Nessuna ottimizzazione) nelle impostazioni di compilazione.
Carter,

1

Ho scritto codice per generare un arresto anomalo dell'indice fuori limite. Segue l'eccezione generata.

2017-01-07 04:02:57.606 testABC[1694:52966] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e85cd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010e2be21e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111
    3   testABC                             0x000000010dce962d -[ViewController ComplexFunction] + 61
    4   testABC                             0x000000010dce95db -[ViewController thirdFunction] + 43
    5   testABC                             0x000000010dce959b -[ViewController secondFunction] + 43
    6   testABC                             0x000000010dce955b -[ViewController firstFinction] + 43
    7   testABC                             0x000000010dce96c2 -[ViewController viewDidAppear:] + 50
    8   UIKit                               0x000000010ee28a6c -[UIViewController _setViewAppearState:isAnimating:] + 945
    9   UIKit                               0x000000010ee2b7da __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42
    10  UIKit                               0x000000010ee29ac4 -[UIViewController _executeAfterAppearanceBlock] + 86
    11  UIKit                               0x000000010ec8d77c _runAfterCACommitDeferredBlocks + 653
    12  UIKit                               0x000000010ec7a273 _cleanUpAfterCAFlushAndRunDeferredBlocks + 566
    13  UIKit                               0x000000010ec9d757 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke_2 + 194
    14  CoreFoundation                      0x000000010e8016ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    15  CoreFoundation                      0x000000010e7e66f4 __CFRunLoopDoBlocks + 356
    16  CoreFoundation                      0x000000010e7e5e65 __CFRunLoopRun + 901
    17  CoreFoundation                      0x000000010e7e5884 CFRunLoopRunSpecific + 420
    18  GraphicsServices                    0x00000001126d9a6f GSEventRunModal + 161
    19  UIKit                               0x000000010ec80c68 UIApplicationMain + 159
    20  testABC                             0x000000010dce99df main + 111
    21  libdyld.dylib                       0x000000011174968d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Se leggi attentamente il First Throw call stack

0   CoreFoundation              0x000000010e85cd4b __exceptionPreprocess + 171
1   libobjc.A.dylib             0x000000010e2be21e objc_exception_throw + 48

0 and 1 sono i processi di sistema dopo l'incidente.

 2   CoreFoundation             0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111

2 è la linea che ha causato l'eccezione.

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3indica il nome della classe ( ViewController) e la funzione naem ( ComplexFunction) in cui è stata generata l'eccezione.


4
Errr, ok. Hai assolutamente ragione, ma è amichevole? In qualsiasi ambiente di sviluppo moderno (dagli anni '90 in poi), quando si verifica un'eccezione, si viene portati alla linea che ha causato il problema. Considerando che Xcode ... beh ... ti dà una traccia dello stack come questa. Anche Turbo Pascal non era così obsoleto !!!
Mike Gledhill,

4
È ridicolo che la società presumibilmente conosciuta per la "migliore esperienza utente" non si renda conto che tutti gli sviluppatori negli ultimi 20 anni sono abituati a vedere il numero di riga in cui viene generata un'eccezione e NON IN ASSEMBLORE. Sto impazzendo? Ogni lingua con cui ho mai lavorato per tutta la vita fornisce numeri di riga. Perfino C o C ++.
mylovemhz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.