web-dev-qa-db-fra.com

Quelle est la signification du code d'exception "EXC_I386_GPFLT"?

Quelle est la signification du code d'exception EXC_I386_GPFLT?

Sa signification varie-t-elle en fonction de la situation?

Dans ce cas, je fais référence au type d'exception EXC_BAD_ACCESS avec le code d'exception EXC_I386_GPFLT

Le programme est développé dans Xcode 5.0.1, traitant de cblas_zgemm() de la bibliothèque BLAS (enfin, je suppose que ce n'est pas grave ...)

Merci beaucoup!

91
Lewen

EXC_I386_GPFLT fait sûrement référence à "une faute de protection générale", qui permet au x86 de vous dire que "vous avez fait quelque chose que vous n'êtes pas autorisé à faire". Cela ne signifie généralement pas que vous accédez à des limites de mémoire insuffisantes, mais il est possible que votre code dépasse les limites et que le code/les données incorrects soient utilisés de manière à constituer une violation de protection. 

Malheureusement, il peut être difficile de comprendre exactement quel est le problème sans plus de contexte. Il existe 27 causes différentes énumérées dans mon Manuel du programmeur AMD64, Vol 2 de 2005 - à dire vrai, il est probable que 8 ans plus tard, quelques plus. 

Si c'est un système 64 bits, un scénario plausible est que votre code utilise un "pointeur non canonique" - ce qui signifie qu'une adresse 64 bits est formée de telle sorte que les 16 bits supérieurs de l'adresse ne soient pas toutes les copies du haut des 48 bits inférieurs (en d’autres termes, les 16 bits supérieurs d’une adresse doivent tous être 0 ou tous 1, sur la base du bit situé juste au-dessous de 16 bits). Cette règle est en place pour garantir que l'architecture peut "augmenter en toute sécurité le nombre de bits valides dans la plage d'adresses". Cela indiquerait que le code est en train de remplacer certaines données de pointeur par d'autres éléments ou de sortir des limites lors de la lecture d'une valeur de pointeur. 

L’accès non aligné avec un registre SSE est une autre cause probable. Dans Word, il lit un registre SSE 16 octets à partir d’une adresse non alignée sur 16 octets. 

Comme je l'ai dit, il y a beaucoup d'autres raisons possibles, mais la plupart d'entre elles impliquent des choses que le code "normal" ne ferait pas dans un système d'exploitation 32 ou 64 bits (telles que le chargement de registres de segments avec un index de sélecteur non valide ou l'écriture dans MSR (registres spécifiques de modèle)). 

93
Mats Petersson

Vous pouvez souvent obtenir des informations à partir des fichiers d'en-tête. Par exemple:

$ cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
$ find usr -name \*.h -exec fgrep -l EXC_I386_GPFLT {} \;
usr/include/mach/i386/exception.h
^C
$ more usr/include/mach/i386/exception.h
....
#define EXC_I386_GPFLT          13      /* general protection fault     */

OK, donc c'est une faute de protection générale (comme son nom l'indique quand même). Googling "défaut de protection générale i386" donne beaucoup de résultats, mais ceci a l'air intéressant:

La protection de la mémoire est également mise en œuvre à l'aide des descripteurs de segment . En premier lieu, le processeur vérifie si une valeur est chargée dans un segment register fait référence à un descripteur valide. Ensuite, il vérifie que tous les adresse linéaire calculée se trouve réellement dans le segment. Également Le type d'accès (lecture, écriture ou exécution) est comparé à informations dans le descripteur de segment. Chaque fois que l'un de ces chèques échoue, une exception (interruption) 13 (hex 0D) est levée. Cette exception est appelé une faute de protection générale (GPF).

Ce 13 correspond à ce que nous avons vu dans les fichiers d’en-tête, donc cela ressemble à la même chose. Cependant, du point de vue du programmeur d'application, cela signifie simplement que nous référons à la mémoire, nous ne devrions pas l'être, et peu importe la façon dont elle est mise en œuvre sur le matériel.

22
trojanfoe

Pour déboguer et trouver la source: Activez les zombies pour l’application (Product\Scheme) et lancez Instruments, sélectionnez Zombies. Exécutez votre application dans Xcode Ensuite, allez dans Instruments, puis commencez à enregistrer . Revenez dans votre application et essayez de générer l’erreur. Les instruments devraient détecter le mauvais appel (à zombie) s’il y en a un.

J'espère que ça aide!

20
Khalid Mammadov

Je me demandais pourquoi cela était apparu lors de mes tests unitaires.

J'ai ajouté une déclaration de méthode à un protocole incluant throws; mais la méthode de projection potentielle n'a même pas été utilisée dans ce test particulier. Activer les Zombies dans les tests semblait trop compliqué.

Il s'avère qu'un cleanK clean a fait l'affaire. Je suis toujours ébahi quand cela résout les problèmes actuels.

12
ctietze

J'ai eu la même exception à Swift 4.2. J'ai passé environ une demi-heure à essayer de trouver un bogue dans mon code, mais le problème a disparu après la fermeture de Xcode et la suppression du dossier de données dérivé.

4

J'ai eu cette erreur en faisant ceci:

 NSMutableDictionary *aDictionary=[[NSMutableDictionary alloc] initWithObjectsAndKeys:<#(nonnull id), ...#>, nil]; //with 17 objects and keys

Il est parti quand je suis revenu à:

NSMutableDictionary *aDictionary=[[NSMutableDictionary alloc] init];
[aDictionary setObject:object1 forKey:@"Key1"]; //17 times
0
Peter B. Kramer

Dans mon cas, l'erreur a été générée dans Xcode lors de l'exécution d'une application sur le simulateur iOS. Bien que je ne puisse pas répondre à la question précise "ce que l'erreur signifie", je peux dire ce qui m'a aidé, peut-être que cela aide aussi les autres.

La solution pour moi était de Erase All Content and Settings dans le simulateur et de Clean Build Folder... dans Xcode.

0
Manuel

Si l'erreur est renvoyée à l'intérieur d'une fermeture définissant self comme unowned, vous pouvez être limité dans ce à quoi vous pouvez accéder et vous obtiendrez ce code d'erreur dans certaines situations. Surtout pendant le débogage. Si tel est le cas, essayez de remplacer [unowned self] par [weak self].

0
Matjan

Cela m'est arrivé parce que Xcode ne semblait pas aimer utiliser le même nom de variable dans deux classes différentes (qui sont conformes au même protocole, si cela compte, bien que le nom de la variable n'ait aucun rapport avec aucun protocole). J'ai simplement renommé ma nouvelle variable.

J'ai dû entrer dans les setters où il se plantait pour le voir, pendant le débogage. Cette réponse s'applique à iOS

0
Stephen J