Apa arti kode pengecualian “EXC_I386_GPFLT”?

117

Apa arti kode pengecualian EXC_I386_GPFLT?

Apakah artinya berbeda-beda menurut situasinya?

Dalam hal ini, saya mengacu pada tipe EXC_BAD_ACCESSpengecualian dengan kode pengecualianEXC_I386_GPFLT

Program ini dikembangkan di Xcode 5.0.1, berhubungan dengan cblas_zgemm()perpustakaan BLAS. (Yah, saya rasa itu tidak masalah ...)

Terima kasih banyak!

Lewen
sumber

Jawaban:

112

EXC_I386_GPFLT pasti mengacu pada "Kesalahan Perlindungan Umum", yang merupakan cara x86 untuk memberi tahu Anda bahwa "Anda melakukan sesuatu yang tidak diizinkan untuk Anda lakukan". Biasanya ini TIDAK berarti Anda mengakses di luar batas memori, tetapi bisa jadi kode Anda keluar batas dan menyebabkan kode / data yang buruk digunakan dengan cara yang membuat semacam pelanggaran perlindungan.

Sayangnya sulit untuk mengetahui dengan tepat apa masalahnya tanpa konteks lebih lanjut, ada 27 penyebab berbeda yang tercantum dalam Manual Programmer AMD64 saya, Vol 2 dari tahun 2005 - dari semua akun, kemungkinan 8 tahun kemudian akan menambahkan beberapa lebih.

Jika ini adalah sistem 64-bit, skenario yang masuk akal adalah bahwa kode Anda menggunakan "penunjuk non-kanonik" - yang berarti bahwa alamat 64-bit dibentuk sedemikian rupa sehingga 16 bit atas dari alamat tersebut tidak semua salinan dari atas 48 bit bawah (dengan kata lain, 16 bit teratas dari sebuah alamat harus semuanya 0 atau semua 1, berdasarkan bit tepat di bawah 16 bit). Aturan ini diterapkan untuk menjamin bahwa arsitektur dapat "dengan aman memperluas jumlah bit yang valid dalam rentang alamat". Ini akan menunjukkan bahwa kode tersebut menimpa beberapa data penunjuk dengan barang lain, atau keluar batas saat membaca beberapa nilai penunjuk.

Kemungkinan penyebab lainnya adalah akses yang tidak selaras dengan register SSE - dengan kata lain, membaca register SSE 16-byte dari alamat yang tidak selaras 16-byte.

Ada, seperti yang saya katakan, banyak kemungkinan alasan lainnya, tetapi kebanyakan dari itu melibatkan hal-hal yang kode "normal" tidak akan lakukan dalam OS 32 atau 64-bit (seperti memuat register segmen dengan indeks pemilih yang tidak valid atau menulis ke MSR (model register khusus)).

Mats Petersson
sumber
24

Untuk men-debug dan menemukan sumber: Aktifkan Zombies untuk aplikasi (Produk \ Skema) dan Luncurkan Instrumen, Pilih Zombi. Jalankan aplikasi Anda di Xcode Lalu buka Instrumen mulai merekam. Kembali ke Aplikasi Anda dan coba buat kesalahan. Instrumen harus mendeteksi panggilan buruk (ke zombie) jika ada.

Semoga membantu!

Khalid Mammadov
sumber
23

Anda seringkali bisa mendapatkan informasi dari file header. Sebagai contoh:

$ 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     */

Oke, jadi ini adalah kesalahan perlindungan umum (seperti namanya). Googling "kesalahan perlindungan umum i386" menghasilkan banyak klik, tetapi ini terlihat menarik:

Perlindungan memori juga diimplementasikan dengan menggunakan deskriptor segmen. Pertama, prosesor memeriksa apakah nilai yang dimuat dalam register segmen mereferensikan deskriptor yang valid. Kemudian ia memeriksa bahwa setiap alamat linier yang dihitung sebenarnya terletak di dalam segmen tersebut. Selain itu, jenis akses (baca, tulis, atau eksekusi) diperiksa dengan informasi di deskriptor segmen. Setiap kali salah satu pemeriksaan ini gagal, pengecualian (interupsi) 13 (hex 0D) dimunculkan. Pengecualian ini disebut General Protection Fault (GPF).

Itu 13cocok dengan apa yang kita lihat di file header, jadi terlihat seperti hal yang sama. Namun dari sudut pandang programmer aplikasi, itu hanya berarti kita mereferensikan memori yang seharusnya tidak kita lakukan, dan tidak masalah bagaimana itu diterapkan pada perangkat keras.

trojanfoe.dll
sumber
1
OS modern tidak menggunakan segmen untuk perlindungan memori secara umum. Semuanya dilakukan dengan MMU, dan akan mengarah ke PF, vektor 14 (biasanya ditampilkan sebagai "Kesalahan segmentasi").
Mats Petersson
16

Saya bertanya-tanya mengapa ini muncul selama tes unit saya.

Saya telah menambahkan deklarasi metode ke protokol yang disertakan throws; tetapi metode yang berpotensi melempar bahkan tidak digunakan dalam tes khusus itu. Mengaktifkan Zombies dalam pengujian sepertinya terlalu merepotkan.

Ternyata ⌘K bersih berhasil. Saya selalu terperangah ketika itu menyelesaikan masalah yang sebenarnya.

ctietze
sumber
Ini juga memperbaikinya untuk saya di Swift. Terima kasih!
lwdthe1
8

Saya memiliki pengecualian serupa di Swift 4.2. Saya menghabiskan sekitar setengah jam mencoba menemukan bug di kode saya, tetapi masalah telah hilang setelah menutup Xcode dan menghapus folder data turunan. Ini jalan pintasnya:

rm -rf ~/Library/Developer/Xcode/DerivedData
Stanislau Baranouski
sumber
2

Dalam kasus saya, kesalahan tersebut terjadi di Xcode saat menjalankan aplikasi di simulator iOS. Meskipun saya tidak dapat menjawab pertanyaan spesifik "apa arti kesalahan itu", saya dapat mengatakan apa yang membantu saya, mungkin itu juga membantu orang lain.

Solusi bagi saya adalah Erase All Content and Settingsdi simulator dan Clean Build Folder...di Xcode.

Manuel
sumber
1

Saya mengalami masalah ini saat meninggalkan tampilan (kembali ke tampilan sebelumnya).

alasannya mengalami

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)
])

Ubah safeAreaLayoutGuideuntuk selfmenyelesaikan masalah.

Arti menyejajarkan tampilan dengan tampilan super di depan, belakang, atas, bawah, bukan ke area aman)

nuynait
sumber
0

Ini terjadi pada saya karena Xcode tampaknya tidak menyukai saya menggunakan nama variabel yang sama di dua kelas berbeda (yang sesuai dengan protokol yang sama, jika itu penting, meskipun nama variabel tidak ada hubungannya dengan protokol apa pun). Saya hanya mengganti nama variabel baru saya.

Saya harus melangkah ke setter yang mengalami crash untuk melihatnya, saat debugging. Jawaban ini berlaku untuk iOS

Stephen J.
sumber
0

Jika kesalahan dilempar ke dalam closure yang didefinisikan selfsebagai unowned, Anda mungkin dibatasi dalam apa yang dapat Anda akses dan akan mendapatkan kode kesalahan ini dalam situasi tertentu. Terutama saat debugging. Jika ini kasusnya, coba ubah [unowned self]ke[weak self]

Matjan
sumber
0

Saya mendapat kesalahan ini saat melakukan ini:

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

Itu hilang ketika saya kembali ke:

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

Bagi saya itu masalah terkait storyboard ada opsi ViewController build untuk set iOS 9.0 dan yang lebih baru sebelumnya ditetapkan untuk iOS 10.0 dan yang lebih baru. Sebenarnya saya ingin menurunkan versi dari 10 ke iOS 9.3.

Anil Kumar
sumber