wake-up-neo.com

Was bedeutet der Ausnahmecode "EXC_I386_GPFLT"?

Was bedeutet der Ausnahmecode EXC_I386_GPFLT?

Variiert seine Bedeutung je nach Situation?

In diesem Fall beziehe ich mich auf Ausnahmetyp EXC_BAD_ACCESS mit Ausnahmecode EXC_I386_GPFLT

Das Programm wurde in Xcode 5.0.1 entwickelt und befasst sich mit cblas_zgemm() der BLAS-Bibliothek.

Vielen Dank!

91
Lewen

EXC_I386_GPFLT bezieht sich sicherlich auf "General Protection fault" (Allgemeiner Schutzfehler). Dies ist der Weg des x86, um Ihnen mitzuteilen, dass "Sie etwas getan haben, das Sie nicht tun dürfen". In der Regel bedeutet dies NICHT, dass Sie außerhalb der Speichergrenzen zugreifen, aber es könnte sein, dass Ihr Code die Grenzen überschreitet und dazu führt, dass fehlerhafter Code/schlechte Daten verwendet werden, die eine Art von Schutzverletzung darstellen. 

Leider ist es schwierig, ohne weitere Zusammenhänge genau herauszufinden, worum es sich bei diesem Problem handelt. In meinem AMD64-Programmierhandbuch, Band 2 von 2005 sind 27 verschiedene Ursachen aufgeführt. Nach allen Angaben hätte 8 Jahre später wahrscheinlich dazu beigetragen Mehr. 

Wenn es sich um ein 64-Bit-System handelt, ist ein plausibles Szenario, dass Ihr Code einen "nicht kanonischen Zeiger" verwendet. Dies bedeutet, dass eine 64-Bit-Adresse so gebildet wird, dass die oberen 16 Bits der Adresse nicht vorhanden sind alle Kopien des oberen der unteren 48 Bits (mit anderen Worten, die oberen 16 Bits einer Adresse sollten alle 0 oder alle 1 sein, basierend auf dem Bit knapp unter 16 Bit). Diese Regel soll sicherstellen, dass die Architektur "die Anzahl der gültigen Bits im Adressbereich sicher erweitern kann". Dies würde bedeuten, dass der Code entweder einige Zeigerdaten mit anderen Daten überschreibt oder beim Lesen eines Zeigerwerts außerhalb der Grenzen liegt. 

Eine andere wahrscheinliche Ursache ist der nicht ausgerichtete Zugriff mit einem SSE - Register. Mit anderen Worten, das Lesen eines 16-Byte-Registers SSE von einer Adresse, die nicht auf 16-Byte ausgerichtet ist. 

Es gibt, wie gesagt, viele andere mögliche Gründe, aber die meisten davon betreffen Dinge, die ein "normaler" Code in einem 32- oder 64-Bit-Betriebssystem nicht ausführen würde (z. B. Laden von Segmentregistern mit ungültigem Auswahlindex oder Schreiben in) MSRs (modellspezifische Register). 

93
Mats Petersson

Sie können häufig Informationen aus den Header-Dateien erhalten. Zum Beispiel:

$ 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, es handelt sich also um eine allgemeine Schutzverletzung (wie der Name schon sagt). Googeln "i386 allgemeine Schutzverletzung" bringt viele Treffer, aber diese sieht interessant:

Der Speicherschutz wird auch mit den Segmentdeskriptoren ..__ implementiert. Zuerst prüft der Prozessor, ob ein in ein Segment geladener Wert Register verweist auf einen gültigen Deskriptor. Dann prüft es das Die berechnete lineare Adresse liegt tatsächlich im Segment. Auch die Die Art des Zugriffs (Lesen, Schreiben oder Ausführen) wird gegen .__ geprüft. Informationen in der Segmentbeschreibung. Immer wenn eine dieser Prüfungen schlägt fehl, Ausnahme (Interrupt) 13 (Hex 0D) wird ausgelöst. Diese Ausnahme ist Allgemeine Schutzverletzung (GPF) genannt.

Dieser 13 stimmt mit dem überein, was wir in den Header-Dateien gesehen haben, und sieht daher genauso aus. Vom Standpunkt des Anwendungsprogrammierers aus bedeutet dies jedoch nur, dass wir uns auf Speicher beziehen, auf den wir nicht sollten, und es spielt keine Rolle, wie er auf der Hardware implementiert wird.

22
trojanfoe

So debuggen und finden Sie die Quelle: Aktivieren Sie Zombies für die App (Product\Scheme) und starten Sie Instruments, wählen Sie Zombies aus. Führen Sie Ihre App in Xcode aus. Gehen Sie zu Instruments, und beginnen Sie mit der Aufnahme. Gehen Sie zurück zu Ihrer App und versuchen Sie, den Fehler zu generieren. Instrumente sollten einen schlechten Anruf (Zombie) erkennen, falls vorhanden.

Ich hoffe es hilft!

20
Khalid Mammadov

Ich habe mich gefragt, warum dies bei meinen Unit-Tests angezeigt wurde.

Ich habe eine Methodendeklaration zu einem Protokoll hinzugefügt, das throws enthielt. Die potentielle Wurfmethode wurde in diesem Test jedoch nicht verwendet. Die Aktivierung von Zombies im Test klang nach zu viel Mühe.

Es stellte sich heraus, dass ein ⌘K-Clean den Trick ausgeführt hat. Ich bin immer fassungslos, wenn das tatsächlich Probleme löst.

12
ctietze

Ich hatte die ähnliche Ausnahme bei Swift 4.2. Ich habe ungefähr eine halbe Stunde damit verbracht, einen Fehler in meinem Code zu finden. Nach dem Schließen von Xcode und dem Entfernen abgeleiteter Datenordner ist das Problem jedoch behoben.

Ich habe dabei folgende Fehlermeldung erhalten:

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

Es verschwand, als ich zu folgendem zurückkehrte:

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

In meinem Fall wurde der Fehler beim Ausführen einer App auf dem iOS-Simulator in Xcode ausgelöst. Während ich die spezifische Frage "Was bedeutet der Fehler" nicht beantworten kann, kann ich sagen, was mir geholfen hat, vielleicht hilft es auch anderen.

Die Lösung für mich war, Erase All Content and Settings im Simulator und Clean Build Folder... in Xcode.

0
Manuel

Wenn der Fehler innerhalb einer Schließung ausgegeben wird, die self als unowned definiert, sind Sie möglicherweise eingeschränkt, worauf Sie zugreifen können, und in bestimmten Situationen wird dieser Fehlercode angezeigt. Besonders beim Debuggen. Wenn dies der Fall ist, ändern Sie [unowned self] in [weak self].

0
Matjan

Dies geschah mir, weil Xcode es nicht so schätzte, als würde ich denselben Variablennamen in zwei verschiedenen Klassen verwenden (die dasselbe Protokoll einhalten, falls dies von Bedeutung ist, obwohl der Variablenname in keinem Protokoll verwandt ist). Ich habe einfach meine neue Variable umbenannt.

Ich musste in die Setter gehen, wo es abstürzte, um es während des Debugging zu sehen. Diese Antwort gilt für iOS

0
Stephen J