ความหมายของรหัสข้อยกเว้น“ EXC_I386_GPFLT” คืออะไร?


117

ความหมายของรหัสข้อยกเว้นEXC_I386_GPFLTคืออะไร?

ความหมายแตกต่างกันไปตามสถานการณ์หรือไม่?

ในกรณีนั้นฉันหมายถึงประเภทEXC_BAD_ACCESSข้อยกเว้นที่มีรหัสข้อยกเว้นEXC_I386_GPFLT

โปรแกรมได้รับการพัฒนาใน Xcode 5.0.1 ซึ่งเกี่ยวข้องกับcblas_zgemm()ไลบรารี BLAS (ฉันเดาว่ามันไม่สำคัญ ... )

ขอบคุณมาก!

คำตอบ:


112

EXC_I386_GPFLT หมายถึง "ความผิดปกติของการป้องกันทั่วไป" ซึ่งเป็นวิธีการของ x86 ที่จะบอกคุณว่า "คุณทำบางอย่างที่คุณไม่ได้รับอนุญาตให้ทำ" โดยทั่วไปไม่ได้หมายความว่าคุณเข้าถึงหน่วยความจำนอกขอบเขต แต่อาจเป็นไปได้ว่ารหัสของคุณกำลังอยู่นอกขอบเขตและทำให้รหัส / ข้อมูลไม่ถูกต้องถูกนำไปใช้ในลักษณะที่ทำให้เกิดการละเมิดการป้องกันในบางประเภท

น่าเสียดายที่อาจเป็นเรื่องยากที่จะเข้าใจว่าปัญหาคืออะไรหากไม่มีบริบทเพิ่มเติมมี 27 สาเหตุที่แตกต่างกันที่ระบุไว้ในคู่มือโปรแกรมเมอร์ AMD64 ของฉันฉบับที่ 2 จากปี 2548 - โดยบัญชีทั้งหมดมีแนวโน้มว่า 8 ปีต่อมาจะมีการเพิ่มบางส่วน มากกว่า.

หากเป็นระบบ 64 บิตสถานการณ์ที่เป็นไปได้คือโค้ดของคุณกำลังใช้ "ตัวชี้ที่ไม่ใช่มาตรฐาน" ซึ่งหมายความว่าที่อยู่ 64 บิตถูกสร้างขึ้นในลักษณะที่ 16 บิตบนของที่อยู่ไม่ได้ สำเนาทั้งหมดที่อยู่ด้านบนสุดของ 48 บิตที่ต่ำกว่า (กล่าวคือ 16 บิตบนสุดของแอดเดรสทั้งหมดควรเป็น 0 หรือทั้งหมด 1 ตามบิตที่ต่ำกว่า 16 บิต) กฎนี้มีไว้เพื่อรับประกันว่าสถาปัตยกรรมสามารถ "ขยายจำนวนบิตที่ถูกต้องในช่วงที่อยู่" ได้อย่างปลอดภัย สิ่งนี้จะบ่งชี้ว่ารหัสกำลังเขียนทับข้อมูลตัวชี้บางส่วนด้วยข้อมูลอื่น ๆ หรืออยู่นอกขอบเขตเมื่ออ่านค่าตัวชี้บางค่า

สาเหตุที่เป็นไปได้อีกประการหนึ่งคือการเข้าถึงที่ไม่สอดคล้องกับการลงทะเบียน SSE หรืออีกนัยหนึ่งคือการอ่านการลงทะเบียน SSE 16 ไบต์จากที่อยู่ที่ไม่ได้จัดแนว 16 ไบต์

มีดังที่ฉันได้กล่าวไปแล้วว่าสาเหตุที่เป็นไปได้อื่น ๆ อีกมากมาย แต่ส่วนใหญ่เกี่ยวข้องกับสิ่งที่โค้ด "ปกติ" จะไม่ทำในระบบปฏิบัติการ 32- หรือ 64 บิต (เช่นการโหลดส่วนการลงทะเบียนด้วยดัชนีตัวเลือกที่ไม่ถูกต้องหรือการเขียนถึง MSR (รีจิสเตอร์เฉพาะรุ่น))


24

ในการแก้จุดบกพร่องและค้นหาแหล่งที่มา: เปิดใช้งาน Zombies สำหรับแอป (Product \ Scheme) และ Launch Instruments เลือก Zombies เรียกใช้แอปของคุณใน Xcode จากนั้นไปที่เครื่องมือเริ่มบันทึก กลับไปที่แอพของคุณและลองสร้างข้อผิดพลาด เครื่องมือควรตรวจจับการโทรที่ไม่ดี (ถึงซอมบี้) หากมี

หวังว่าจะช่วยได้!



23

คุณมักจะได้รับข้อมูลจากไฟล์ส่วนหัว ตัวอย่างเช่น:

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

ตกลงดังนั้นจึงเป็นข้อผิดพลาดในการป้องกันทั่วไป (ตามชื่อที่แนะนำอยู่ดี) Googling "i386 general protection fault" ให้ผลกระทบมากมาย แต่สิ่งนี้ดูน่าสนใจ:

การป้องกันหน่วยความจำยังดำเนินการโดยใช้ตัวบอกส่วน ขั้นแรกโปรเซสเซอร์จะตรวจสอบว่าค่าที่โหลดในการลงทะเบียนเซ็กเมนต์อ้างอิงตัวบอกที่ถูกต้องหรือไม่ จากนั้นจะตรวจสอบว่าที่อยู่เชิงเส้นทุกรายการที่คำนวณได้อยู่ภายในส่วนนั้น ๆ นอกจากนี้ประเภทของการเข้าถึง (อ่านเขียนหรือดำเนินการ) จะถูกตรวจสอบกับข้อมูลในตัวบอกส่วน เมื่อใดก็ตามที่การตรวจสอบเหล่านี้ล้มเหลวข้อยกเว้น (ขัดจังหวะ) 13 (ฐานสิบหก 0D) จะถูกยกขึ้น ข้อยกเว้นนี้เรียกว่า General Protection Fault (GPF)

ซึ่ง13ตรงกับสิ่งที่เราเห็นในไฟล์ส่วนหัวดังนั้นดูเหมือนว่าสิ่งเดียวกัน อย่างไรก็ตามจากมุมมองของโปรแกรมเมอร์แอปพลิเคชันหมายความว่าเรากำลังอ้างถึงหน่วยความจำที่เราไม่ควรจะเป็นและไม่สำคัญว่าจะนำไปใช้กับฮาร์ดแวร์อย่างไร


1
อย่างไรก็ตามระบบปฏิบัติการสมัยใหม่ไม่ได้ใช้เซ็กเมนต์สำหรับการป้องกันหน่วยความจำโดยทั่วไป ทุกอย่างทำด้วย MMU และจะนำไปสู่ ​​PF เวกเตอร์ 14 (โดยปกติจะแสดงเป็น "Segmentation fault")
Mats Petersson

16

ฉันสงสัยว่าทำไมสิ่งนี้จึงปรากฏขึ้นระหว่างการทดสอบหน่วยของฉัน

ฉันได้เพิ่มการประกาศวิธีการในโปรโตคอลซึ่งรวมถึงthrows; แต่วิธีการขว้างอาจไม่ได้ใช้ในการทดสอบนั้น การเปิดใช้งาน Zombies ในการทดสอบฟังดูเหมือนเป็นปัญหามากเกินไป

ปรากฎว่า⌘K clean ทำเคล็ดลับ ฉันมักจะรู้สึกท้อแท้เสมอเมื่อสามารถแก้ปัญหาที่เกิดขึ้นจริงได้


สิ่งนี้แก้ไขให้ฉันใน Swift ด้วย ขอบคุณ!
lwdthe1

8

ฉันมีข้อยกเว้นที่คล้ายกันที่ Swift 4.2 ฉันใช้เวลาประมาณครึ่งชั่วโมงในการค้นหาจุดบกพร่องในโค้ดของฉัน แต่ปัญหาได้หายไปหลังจากปิด Xcode และลบโฟลเดอร์ข้อมูลที่ได้รับ นี่คือทางลัด:

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

2

ในกรณีของฉันเกิดข้อผิดพลาดใน Xcode เมื่อเรียกใช้แอปบนโปรแกรมจำลอง iOS แม้ว่าฉันจะไม่สามารถตอบคำถามเฉพาะ "ความหมายของข้อผิดพลาด" ได้ แต่ฉันสามารถพูดได้ว่าสิ่งที่ช่วยฉันได้บางทีมันอาจช่วยคนอื่นได้ด้วย

วิธีแก้ปัญหาสำหรับฉันคือErase All Content and SettingsในโปรแกรมจำลองและClean Build Folder...ใน Xcode


1

ฉันมีปัญหานี้เมื่อออกจากมุมมอง (กลับไปที่มุมมองก่อนหน้า)

เหตุผลก็คือมี

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

เปลี่ยนsafeAreaLayoutGuideเพื่อselfแก้ปัญหา

ความหมายจะจัดมุมมองให้ตรงกับส่วนนำหน้าด้านท้ายด้านบนด้านล่างแทนที่จะเป็นพื้นที่ปลอดภัย)


0

สิ่งนี้เกิดขึ้นกับฉันเพราะ Xcode ดูเหมือนจะไม่ชอบฉันโดยใช้ชื่อตัวแปรเดียวกันในสองคลาสที่แตกต่างกัน (ซึ่งเป็นไปตามโปรโตคอลเดียวกันหากมีความสำคัญแม้ว่าชื่อตัวแปรจะไม่มีอะไรเกี่ยวข้องกับโปรโตคอลใด ๆ ก็ตาม) ฉันเพิ่งเปลี่ยนชื่อตัวแปรใหม่ของฉัน

ฉันต้องเข้าไปในเซ็ตเตอร์ที่มันขัดข้องเพื่อที่จะเห็นมันในขณะที่ดีบัก คำตอบนี้ใช้ได้กับ iOS


0

ถ้าข้อผิดพลาดจะถูกโยนทิ้งภายในปิดที่กำหนดselfเป็นunownedคุณอาจถูก จำกัด ในสิ่งที่คุณสามารถเข้าถึงและจะได้รับรหัสข้อผิดพลาดนี้ในบางสถานการณ์ โดยเฉพาะอย่างยิ่งในขณะที่แก้ไขข้อบกพร่อง หากเป็นกรณีนี้ให้คุณลองเปลี่ยน[unowned self]เป็น[weak self]


0

ฉันได้รับข้อผิดพลาดนี้ขณะทำสิ่งนี้:

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

มันหายไปเมื่อฉันเปลี่ยนกลับเป็น:

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

0

สำหรับฉันแล้วปัญหาที่เกี่ยวข้องกับสตอรีบอร์ดมีตัวเลือกของ ViewController build สำหรับ set iOS 9.0 และใหม่กว่าที่ตั้งไว้สำหรับ iOS 10.0 และใหม่กว่า อันที่จริงฉันต้องการดาวน์เกรดเวอร์ชันจาก 10 เป็น iOS 9.3

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.