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!

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


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!



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.


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.


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

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.


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)


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


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]


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

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.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.