web-dev-qa-db-fra.com

Types d'exceptions dans les journaux de plantage iOS

J'ai vu différents types de journaux de plantage depuis que j'ai commencé à apprendre le développement iOS.

Je sais que: Type d'exception: EXC_BAD_ACCESS (SIGSEGV) signifie que nous accédons à un objet libéré.

mais je ne sais pas:
Type d'exception: EXC_BAD_ACCESS (SIGBUS)
Type d'exception: EXC_CRASH (SIGABRT)
Type d'exception: EXC_BREAKPOINT (SIGTRAP)

Savez-vous combien de types d'exceptions dans les journaux de plantage iOS et que signifient-ils?

49
Tuyen Nguyen

Je sais que: Type d'exception: EXC_BAD_ACCESS (SIGSEGV) signifie que nous accédons à un objet libéré.

Non.

Un SIGSEGV est un défaut de segmentation, ce qui signifie que vous essayez d'accéder à une adresse mémoire non valide.

Ces exceptions (en fait, ce sont des signaux) ne sont pas liées à Objective-C, mais à C. Donc, vous pouvez obtenir une telle exception sans objets Objective-C.

Notez qu'un signal ne fait pas exception, ce qui signifie que vous ne pouvez pas les attraper avec @try et @catch blocs.

Vous pouvez définir un gestionnaire de signal avec les fonctions signal et sigaction. Gardez à l'esprit que certains signaux, comme SIGABRT, ne peuvent pas être bloqués.

Vous pouvez consulter la page Wikipedia sur les signaux, si vous souhaitez plus d'informations.

Cela dit, pour reprendre:

SIGSEGV (Erreur de segmentation)

Accès à une adresse mémoire invalide. L'adresse existe, mais votre programme n'y a pas accès.

SIGBUS (Erreur de bus)

Accès à une adresse mémoire invalide. L'adresse n'existe pas ou l'alignement n'est pas valide.

SIGFPE (exception à virgule flottante)

Opération arithmétique non valide. Peut être lié à des opérations entières, malgré le nom.

SIGPIPE

Tuyau cassé.

SIGILL

Instruction de processeur illégale.

SIGTRAP

Lié au débogueur

SIGABRT

Crash du programme, non lié à l'un des signaux précédents.

96
Macmade

SIGSEGV signifie littéralement que vous accédez à une adresse que vous ne possédez pas. Ce n'est donc pas nécessairement que vous accédez à un objet libéré; vous pourriez accéder à un objet qui n'a jamais existé, comme dans:

UIView *view; // uninitialised, could point to anything
[view setFrame:someFrame];

Ou même simplement en faisant une erreur dans les éléments non-objets de niveau C, tels que:

int array[100];
array[1000] = 23; // out-of-bounds access

SIGBUS est très similaire à SIGSEGV, la différence étant au niveau matériel (généralement la différence entre essayer d'accéder à une adresse qui existe mais que vous ne possédez pas et essayer d'accéder à une adresse qui n'a rien derrière, mais ce n'est pas une définition stricte), mais est généralement associé au même type d'erreurs, bien qu'un SIGBUS soit beaucoup plus susceptible de concerner une variable non initialisée qu'un SIGSEGV.

Si vous essayez de mapper sur des erreurs que vous avez probablement commises dans Objective-C, vous voulez probablement simplement lire SIGSEGV et SIGBUS comme signifiant "un accès à la mémoire que je n'avais pas le droit de faire".

SIGABRT est un programme qui tente de s'interrompre, ce qui signifie généralement qu'une sorte de vérification de cohérence interne a échoué. Par exemple, SIGABRT est déclenché si vous essayez de libérer deux fois la même mémoire, ou - au niveau Cocoa - si vous raise un NSException qui n'est pas intercepté. Si vous obtenez un SIGABRT, vous avez fait quelque chose de mal qui est détecté par le logiciel système (contrairement à SEGV et BUS, qui surviennent dans le matériel).

SIGTRAP est un appel du programme vers un débogueur. Pour l'anecdote, Apple semble les utiliser lorsque vous faites quelque chose de mal qui peut être détecté dans le logiciel mais qui concerne l'environnement plutôt que votre code spécifique. Ainsi, par exemple, vous appelez une fonction C qui existe dans le SDK avec lequel vous avez construit, mais pas sur le périphérique sur lequel vous exécutez (par exemple lorsque vous construisez avec le dernier SDK avec une cible de déploiement inférieure), ou faites une chose similaire avec un objet.

30
Tommy

Ces messages proviennent de gdb et ne sont pas exclusifs à objective-C. Pour obtenir des informations sur les signaux, il vous suffit de saisir info signals sur la console du débogueur, il s'agit d'un exemple de sortie . Désolé de ne pas l'avoir affiché ici, mais le format de la sortie de la console est horrible.

Source et plus d'informations sur les signaux

4
Youssef

J'ai récemment étudié ce sujet et voici mon résumé:

EXC_BAD_ACCESS (SIGSEGV) ou EXC_BAD_ACCESS (SIGBUS)

Notre programme a probablement tenté d'accéder à un mauvais emplacement de mémoire ou l'adresse était bonne, mais nous n'avons pas eu le privilège d'y accéder. La mémoire a peut-être été désallouée en raison de la pression de la mémoire.

EXC_BREAKPOINT (SIGTRAP)

Cela est dû à un NSException levé (éventuellement par une bibliothèque en notre nom) ou à l'appel de _NSLockError Ou objc_exception_throw. Par exemple, cela peut être l'environnement Swift détectant une anomalie telle que le déballage forcé d'un nil facultatif.

EXC_BAD_INSTRUCTION (SIGILL)

C'est lorsque le code du programme lui-même est défectueux, pas la mémoire à laquelle il peut accéder. Cela devrait être rare sur les appareils iOS; peut-être un bogue du compilateur ou de l'optimiseur, ou un code d'assemblage écrit à la main défectueux. Sur Simulator, c'est une autre histoire car l'utilisation d'un opcode non défini est une technique utilisée par le runtime Swift pour arrêter l'accès aux objets zombies (objets désalloués).

EXC_GUARD

C'est à ce moment que le programme a fermé un descripteur de fichier qui était protégé. Un exemple est la base de données SQLite utilisée par le système.

1
Faisal Memon