Qu'est-ce que EXC_BAD_ACCESS et comment le déboguer

À un moment ou à un autre, vous rencontrerez un crash causé par EXC_BAD_ACCESS. Dans cette astuce, vous apprendrez ce qu'est EXC_BAD_ACCESS et en quoi il est causé. Je vais également vous donner quelques conseils pour corriger les bogues causés par EXC_BAD_ACCESS..

1. Qu'est-ce que EXC_BAD_ACCESS??

Une fois que vous aurez compris la cause sous-jacente de EXC_BAD_ACCESS, vous comprendrez mieux son nom cryptique. Il y a une explication simple et une explication plus technique. Commençons par l'explication simple d'abord.

Garder les choses simples

Chaque fois que vous rencontrez EXC_BAD_ACCESS, cela signifie que vous envoyez un message à un objet déjà libéré. C'est le scénario le plus courant, mais il y a des exceptions, comme nous le verrons dans un instant..

Ce que cela signifie vraiment

L'explication technique est un peu plus complexe. En C et Objective-C, vous traitez constamment avec pointeurs. Un pointeur n'est rien d'autre qu'une variable qui stocke l'adresse mémoire d'une autre variable. Lorsque vous envoyez un message à un objet, le pointeur qui pointe sur l'objet auquel vous envoyez le message doit être déréférencé. Cela signifie que vous prenez l'adresse de la mémoire vers laquelle pointe le pointeur et accédez à la valeur de ce bloc de mémoire..

Lorsque ce bloc de mémoire n'est plus mappé pour votre application ou, autrement dit, ce bloc de mémoire n'est pas utilisé pour ce que vous pensez qu'il est utilisé, il n'est plus possible d'accéder à ce bloc de mémoire. Lorsque cela se produit, le noyau envoie une exception (EXC), indiquant que votre application ne peut pas accéder à ce bloc de mémoire (MAUVAIS ACCÈS).

En résumé, lorsque vous rencontrez EXC_BAD_ACCESS, cela signifie que vous essayez d'envoyer un message à un bloc de mémoire qui ne peut pas l'exécuter..

Dans certains cas, cependant, EXC_BAD_ACCESS est provoqué par un pointeur corrompu. Chaque fois que votre application tente de déréférencer un pointeur corrompu, une exception est levée par le noyau..

2. Débogage de EXC_BAD_ACCESS

Le débogage de EXC_BAD_ACCESS peut être difficile et frustrant. Cependant, maintenant que EXC_BAD_ACCESS n'est plus une énigme pour vous, cela devrait être moins intimidant.

La première chose que vous devez comprendre est que votre application ne plante pas nécessairement dès que le bloc de mémoire n’est plus accessible par votre application. C'est ce qui rend souvent le débogage EXC_BAD_ACCESS si difficile.

La même chose est vraie pour les pointeurs corrompus. Votre application ne plantera pas car un pointeur a été corrompu. En outre, il ne se bloquera pas si vous transmettez un pointeur corrompu dans votre application. Lorsque votre application tente de déréférencer le pointeur corrompu, les choses tournent mal..

Des morts-vivants

Bien que les zombies aient gagné en popularité au cours des dernières années, ils sont présents dans Xcode depuis plus de dix ans. Le nom zombi Cela peut paraître un peu dramatique, mais c’est en fait un excellent nom pour la fonctionnalité qui va nous aider à déboguer EXC_BAD_ACCESS. Laissez-moi vous expliquer comment ça marche.

Dans Xcode, vous pouvez activer les objets zombies, ce qui signifie que les objets désalloués sont conservés sous la forme de zombies. Autrement dit, les objets désalloués sont conservés en vie à des fins de débogage. Il n'y a pas de magie impliquée. Si vous envoyez un message à un objet zombie, votre application plantera quand même à la suite de EXC_BAD_ACCESS..

Pourquoi est-ce utile? Ce qui rend EXC_BAD_ACCESS difficile à déboguer, c’est que vous ne savez pas à quel objet votre application tentait d’accéder. Les objets zombies résolvent ce problème dans de nombreux cas. En conservant les objets désalloués en vie, Xcode peut vous dire à quel objet vous vouliez accéder, facilitant ainsi la recherche du problème..

Activer les zombies dans Xcode est très facile. Notez que cela peut varier en fonction de la version de Xcode que vous utilisez. L’approche suivante s’applique à Xcode 6 et 7. Cliquez sur le schéma actif en haut à gauche et choisissez Modifier le schéma.

Sélectionner Courir à gauche et ouvrez le Diagnostics onglet en haut. Pour activer les objets zombies, cochez la case intitulée Activer les objets zombies.

Si vous rencontrez maintenant EXC_BAD_ACCESS, le résultat affiché dans la console de Xcode vous donnera une bien meilleure idée de l'endroit où commencer votre recherche. Jetez un coup d'œil à l'exemple de sortie suivant.

2015-08-12 06: 31: 55.501 Debug [2371: 1379247] - Message [ChildViewController respondsToSelector:] envoyé à l'instance désallouée 0x17579780

Dans l'exemple ci-dessus, Xcode nous indique qu'un message de répond au sélecteur: a été envoyé à un objet zombie. Cependant, l’objet zombie n’est plus une instance du ChildViewController classe. Le bloc de mémoire qui était précédemment alloué à la ChildViewController l'instance n'est plus mappée pour votre application. Cela devrait vous donner une bonne idée de la cause première du problème..

Malheureusement, les objets zombies ne pourront pas vous sauver la vie pour chaque crash causé par EXC_BAD_ACCESS. Si les objets zombies ne font pas l'affaire, alors il est temps d'effectuer une analyse appropriée.

Analyser

Si les objets zombies ne résolvent pas votre problème, alors la cause première peut être moins triviale. Dans ce cas, vous devez examiner de plus près le code en cours d'exécution lorsque votre application se bloque. Cela peut être fastidieux et fastidieux.

Pour vous aider à trouver des problèmes dans votre base de code, vous pouvez demander à Xcode d'analyser votre code afin de vous aider à identifier les problèmes. Notez que Xcode analyse votre projet, ce qui signifie qu’il soulignera tous les problèmes potentiels qu’il rencontre..

Pour que Xcode analyse votre projet, choisissez Analyser de Xcode Produit menu ou appuyez sur Maj-Commande-B. Cela prendra quelques instants à Xcode, mais une fois terminé, vous devriez voir une liste de problèmes dans Navigateur de problème sur la gauche. Les problèmes décelés par l'analyse sont surlignés en bleu.

Lorsque vous cliquez sur un problème, Xcode vous conduit au bloc de code qui nécessite votre attention. Notez que Xcode fait seulement une suggestion. Dans certains cas, il est possible que le problème ne soit pas pertinent et ne nécessite pas de résolution.

Si vous ne trouvez pas le bogue à l'origine de EXC_BAD_ACCESS, il est important d'examiner attentivement chaque problème rencontré par Xcode lors de l'analyse de votre projet..

Conclusion

EXC_BAD_ACCESS est une frustration courante chez les développeurs et est inhérent à la gestion manuelle de la mémoire. Les problèmes liés à la gestion de la mémoire sont devenus moins fréquents depuis l'introduction d'ARC (comptage automatique de références), mais ils n'ont en aucun cas disparu.