Was bedeutet der Ausnahmecode "EXC_I386_GPFLT"?


117

Was bedeutet Ausnahmecode EXC_I386_GPFLT?

Variiert seine Bedeutung je nach Situation?

In diesem Fall beziehe ich mich auf den Ausnahmetyp EXC_BAD_ACCESSmit AusnahmecodeEXC_I386_GPFLT

Das Programm wurde in Xcode 5.0.1 entwickelt und befasst sich mit cblas_zgemm()der BLAS-Bibliothek. (Nun, ich denke, es spielt keine Rolle ...)

Vielen Dank!

Antworten:


112

EXC_I386_GPFLT bezieht sich sicherlich auf "Allgemeiner Schutzfehler". Auf diese Weise kann der x86 Ihnen mitteilen, dass "Sie etwas getan haben, was Sie nicht tun dürfen". Dies bedeutet normalerweise NICHT, dass Sie außerhalb der Speichergrenzen zugreifen, aber es kann sein, dass Ihr Code außerhalb der Speichergrenzen liegt und fehlerhafter Code / fehlerhafte Daten auf eine Weise verwendet werden, die zu einer Art Schutzverletzung führt.

Leider kann es schwierig sein, genau herauszufinden, wo das Problem liegt, ohne mehr Kontext. In meinem AMD64-Programmierhandbuch, Band 2 aus dem Jahr 2005 sind 27 verschiedene Ursachen aufgeführt. Nach allen Angaben ist es wahrscheinlich, dass 8 Jahre später einige hinzugekommen wären Mehr.

Wenn es sich um ein 64-Bit-System handelt, ist es plausibel, 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 der Oberseite 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 darauf hinweisen, dass der Code entweder einige Zeigerdaten mit anderen Dingen überschreibt oder beim Lesen eines Zeigerwerts die Grenzen überschreitet.

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

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


24

So debuggen Sie und finden Sie die Quelle: Aktivieren Sie Zombies für die App (Produkt \ Schema) und starten Sie Instrumente, wählen Sie Zombies aus. Führen Sie Ihre App in Xcode aus. Gehen Sie dann zu Instrumente, um die Aufnahme zu starten. Kehren Sie zu Ihrer App zurück und versuchen Sie, den Fehler zu generieren. Instrumente sollten einen schlechten Anruf (zum Zombie) erkennen, wenn es einen gibt.

Ich hoffe es hilft!



23

Sie können häufig Informationen aus den Header-Dateien abrufen. Beispielsweise:

$ 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 einen allgemeinen Schutzfehler (wie der Name schon sagt). Das Googeln von "i386 allgemeiner Schutzfehler" liefert viele Treffer, aber das sieht interessant aus:

Der Speicherschutz wird auch mithilfe der Segmentdeskriptoren implementiert. Zunächst prüft der Prozessor, ob ein in ein Segmentregister geladener Wert auf einen gültigen Deskriptor verweist. Anschließend wird überprüft, ob jede berechnete lineare Adresse tatsächlich innerhalb des Segments liegt. Außerdem wird die Art des Zugriffs (Lesen, Schreiben oder Ausführen) anhand der Informationen im Segmentdeskriptor überprüft. Wenn eine dieser Prüfungen fehlschlägt, wird die Ausnahme (Interrupt) 13 (hex 0D) ausgelöst. Diese Ausnahme wird als General Protection Fault (GPF) bezeichnet.

Das 13stimmt mit dem überein, was wir in den Header-Dateien gesehen haben, also sieht es genauso aus. Aus Sicht des Anwendungsprogrammierers bedeutet dies jedoch nur, dass wir auf Speicher verweisen, den wir nicht sein sollten, und es spielt keine Rolle, wie er auf der Hardware implementiert ist.


1
Moderne Betriebssysteme verwenden jedoch im Allgemeinen keine Segmente für den Speicherschutz. Dies alles wird mit der MMU durchgeführt und würde zu einem PF-Vektor 14 führen (normalerweise als "Segmentierungsfehler" angezeigt).
Mats Petersson

16

Ich fragte mich, warum dies während meiner Unit-Tests auftrat.

Ich habe einem Protokoll eine Methodendeklaration hinzugefügt, die Folgendes enthielt throws: Aber die potenziell werfende Methode wurde in diesem speziellen Test nicht einmal verwendet. Das Aktivieren von Zombies im Test klang nach zu viel Mühe.

Es stellte sich heraus, dass ein cleanK Clean den Trick gemacht hat. Ich bin immer verblüfft, wenn das tatsächliche Probleme löst.


Dies hat es auch in Swift für mich behoben. Vielen Dank!
lwdthe1

8

Ich hatte eine ähnliche Ausnahme bei Swift 4.2. Ich habe ungefähr eine halbe Stunde damit verbracht, einen Fehler in meinem Code zu finden, aber das Problem ist behoben, nachdem Xcode geschlossen und abgeleitete Datenordner entfernt wurden. Hier ist die Verknüpfung:

rm -rf ~/Library/Developer/Xcode/DerivedData

2

In meinem Fall wurde der Fehler in Xcode ausgelöst, als eine App auf dem iOS-Simulator ausgeführt wurde. Obwohl 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 Settingsim Simulator und Clean Build Folder...in Xcode.


1

Ich hatte dieses Problem beim Verlassen einer Ansicht (kehren Sie zur vorherigen Ansicht zurück).

der Grund war zu haben

addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    view.leadingAnchor.constraint(equalTo: safeAreaLayoutGuide.leadingAnchor),
    view.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor),
    view.trailingAnchor.constraint(equalTo: safeAreaLayoutGuide.trailingAnchor),
    view.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor)
])

Ändern Sie safeAreaLayoutGuide, selfum das Problem zu lösen.

Die Bedeutung richtet die Ansicht an der führenden, nachfolgenden, oberen und unteren Ansicht der Übersicht aus, anstatt auf den sicheren Bereich.


0

Dies geschah mir, weil Xcode mich anscheinend nicht mit demselben Variablennamen in zwei verschiedenen Klassen mochte (die dem gleichen Protokoll entsprechen, wenn dies wichtig ist, obwohl der Variablenname in keinem Protokoll etwas zu tun hat). Ich habe meine neue Variable einfach umbenannt.

Ich musste in die Setter treten, in denen es abstürzte, um es beim Debuggen zu sehen. Diese Antwort gilt für iOS


0

Wenn der Fehler in einen Abschluss geworfen wird, der selfals definiert ist unowned, können Sie möglicherweise nur eingeschränkt darauf zugreifen und erhalten diesen Fehlercode in bestimmten Situationen. Besonders beim Debuggen. Wenn dies bei Ihnen der Fall ist, wechseln Sie [unowned self]zu[weak self]


0

Ich habe diesen Fehler dabei bekommen:

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

Es ging weg, als ich zurückkehrte zu:

NSMutableDictionary *aDictionary=[[NSMutableDictionary alloc] init];
[aDictionary setObject:object1 forKey:@"Key1"]; //17 times

0

Für mich gibt es ein Problem im Zusammenhang mit dem Storyboard. Es gibt die Option, ViewController für iOS 9.0 und höher zu erstellen, die zuvor für iOS 10.0 und höher festgelegt wurden. Eigentlich möchte ich die Version von 10 auf iOS 9.3 downgraden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.