web-dev-qa-db-fra.com

Xcode ne montre pas la ligne qui cause un crash

Chaque fois que mon application plante, Xcode met en surbrillance l'appel UIApicationMain () dans la fonction main () en tant que ligne ayant provoqué le blocage. Dans certains cas, cela était normal (erreur de segmentation par exemple), mais le crash que je tente de traiter est un simple SIGABRT avec des informations détaillées consignées dans la console:

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

Xcode affichait parfaitement la ligne avec les anciens SDK, mais depuis je suis passé à Xocde 4.2, cela a changé. Il est assez évident que Xcode sait exactement ce qui a causé le crash (ou pourrait le savoir), mais ne montre toujours pas la ligne réelle. Y at-il une solution ou une solution de contournement pour cela?

114
JonasG

Vous devez également vous assurer que des points d'arrêt sont définis pour toutes les exceptions. Cela provoquera l'arrêt de Xcode sur la ligne où l'exception se produit. Procédez comme suit [dans Xcode 4]:

  1. Dans le navigateur de projet situé à gauche de Xcode, cliquez sur le navigateur de point d'arrêt (presque tout à fait à droite de la barre de boutons supérieure. L'icône ressemble à une grosse flèche droite).

  2. Au bas du navigateur, cliquez sur le bouton "+".

  3. Cliquez sur "Ajouter un point d'arrêt d'exception".

  4. Un nouveau point d'arrêt sera créé. Il devrait être configuré au besoin, mais vous pouvez modifier son comportement.

  5. Exécutez votre projet et reproduisez l'exception.

Vous avez également mentionné que vous aviez établi un lien avec certaines bibliothèques/structures tierces. Si l'exception se produit dans ces frameworks, vous allez avoir du mal à compiler le code et à ce que Xcode ne puisse pas vous montrer la ligne à l'origine de l'exception. Si tel est le cas et que vous êtes certain d’utiliser correctement les bibliothèques, vous devez alors signaler un rapport de bogue aux responsables de ces bibliothèques.

286
Carter

Suivez simplement les instructions de cette réponse à StackOverflow:

Activer les zombies

Fondamentalement, il vous suffit d'activer "Activer les zombies". Xcode devrait alors se rompre à la ligne ayant causé le problème.

 enter image description here

(Il est absolument choquant que, même en 2017, Xcode l'ait toujours désactivée par défaut. Pourquoi voudriez-vous que {not} _ voie voir la ligne à l'origine du problème? Et "Enable Zombie Objects "?! Vraiment?! Les auteurs de Xcode croient-ils vraiment qu'il s'agit d'un nom utile, qui donnerait un sens quelconque aux nouveaux développeurs? Il est déprimant de constater à quel point la cote de Xcode est mauvaise, année après année, dans l'App Store. on écoute ...)

17
Mike Gledhill

Editez le schéma actuel et activez NSZombieEnabled , MallocStackLogging et guard malloc . Ensuite, lorsque votre application se bloque, tapez ceci dans la console gdb:

(gdb) info malloc-history 0x543216

Remplacez 0x543216 par l'adresse de l'objet qui a provoqué la NSInvalidArgumentException. Elle devrait vous donner une trace de pile bien plus utile, montrant les lignes de votre code à l'origine du blocage.

8
chown

J'ai vu ce comportement dans un code fortement optimisé; vérifier, ajuster le niveau d'optimisation de votre cible et ceux des bibliothèques tierces peut aider. (Paramètre de niveau d'optimisation LLVM 3.0)

Générez-vous des symboles de débogage?

2
FluffulousChimp

J'ai écrit du code pour générer un crash d'index hors limite . La suite est l'exception levée. 

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

Si vous lisez attentivement le First Throw call stack

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

0 and 1 sont les processus système après un crash. 

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

2 est la ligne à l'origine de l'exception. 

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3 vous indique le nom de la classe (ViewController) et la fonction naem (ComplexFunction) dans laquelle une exception a été levée. 

0
AsifHabib