[c++] What's the meaning of exception code "EXC_I386_GPFLT"?

What's the meaning of exception code EXC_I386_GPFLT?

Does its meaning vary according to the situation?

In that case, I'm referring to exception type EXC_BAD_ACCESS with exception code EXC_I386_GPFLT

The program is developed in Xcode 5.0.1, dealing with cblas_zgemm() of the BLAS library.(Well, I guess it doesn't matter...)

Thank you very much!

This question is related to c++ c exc-bad-access

The answer is


I'm seeing this error code in rotation crashes on Xcode 12.0 Beta 6, only on the iOS 14 simulator. It doesn't crash on my real device running iOS 13 though! So if you're running beta stuff and seeing rotation crashes in the simulator, maybe you just need to run on a real device with a non-beta iOS version.


In my case EXC_I386_GPFLT was caused by missing return value in the property getter. Like this:

- (CppStructure)cppStructure
{
    CppStructure data;
    data.a = self.alpha;
    data.b = self.beta;

    return data; // this line was missing
}

Xcode 12.2


You can often get information from the header files. For example:

$ 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, so it's a general protection fault (as its name suggests anyway). Googling "i386 general protection fault" yields many hits, but this looks interesting:

Memory protection is also implemented using the segment descriptors. First, the processor checks whether a value loaded in a segment register references a valid descriptor. Then it checks that every linear address calculated actually lies within the segment. Also, the type of access (read, write, or execute) is checked against the information in the segment descriptor. Whenever one of these checks fails, exception (interrupt) 13 (hex 0D) is raised. This exception is called a General Protection Fault (GPF).

That 13 matches what we saw in the header files, so it looks like the same thing. However from the application programmer's point-of-view, it just means we're referencing memory we shouldn't be, and it's doesn't really matter how it's implemented on the hardware.


In my case the error was thrown in Xcode when running an app on the iOS simulator. While I cannot answer the specific question "what the error means", I can say what helped me, maybe it also helps others.

The solution for me was to Erase All Content and Settings in the simulator and to Clean Build Folder... in Xcode.


For me it issue related to storyboard there is option of ViewController build for set iOS 9.0 and later previously set for iOS 10.0 and later. Actually i want to downgrade the ver from 10 to iOS 9.3.


This happened to me because Xcode didn't appear to like me using the same variable name in two different classes (that conform to the same protocol, if that matters, although the variable name has nothing related in any protocol). I simply renamed my new variable.

I had to step into the setters where it was crashing in order to see it, while debugging. This answer applies to iOS


If the error is thrown inside a closure that defines self as unowned, you may be limited in what you can access and will get this error code in certain situations. Especially while debugging. If this is the case for you try changing [unowned self] to [weak self]


I got this error while doing this:

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

It went away when I reverted to:

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

To debug and find the source: Enable Zombies for the app (Product\Scheme) and Launch Instruments, Select Zombies. Run your app in Xcode Then go to Instruments start recording. Go back to your App and try generating the error. Instruments should detect bad call (to zombie) if there is one.

Hope it helps!


I wondered why this appeared during my unit tests.

I have added a method declaration to a protocol which included throws; but the potentially throwing method wasn't even used in that particular test. Enabling Zombies in test sounded like too much trouble.

Turns out a ?K clean did the trick. I'm always flabberghasted when that solves actual problems.


I had a similar exception at Swift 4.2. I spent around half an hour trying to find a bug in my code, but the issue has gone after closing Xcode and removing derived data folder. Here is the shortcut:

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

I could get this error working with UnsafeMutablePointer

let ptr = rawptr.assumingMemoryBound(to: A.self) //<-- wrong A.self Change it to B.Self
ptr.pointee = B()

I had this issue when leaving a view (pop back to the previous view).

the reason was having

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

Change safeAreaLayoutGuide to self solve the issue.

Meaning aligns the view with the superview's leading, trailing, top, bottom instead of to safe area)


EXC_I386_GPFLT is surely referring to "General Protection fault", which is the x86's way to tell you that "you did something that you are not allowed to do". It typically DOESN'T mean that you access out of memory bounds, but it could be that your code is going out of bounds and causing bad code/data to be used in a way that makes for an protection violation of some sort.

Unfortunately it can be hard to figure out exactly what the problem is without more context, there are 27 different causes listed in my AMD64 Programmer's Manual, Vol 2 from 2005 - by all accounts, it is likely that 8 years later would have added a few more.

If it is a 64-bit system, a plausible scenario is that your code is using a "non-canonical pointer" - meaning that a 64-bit address is formed in such a way that the upper 16 bits of the address aren't all copies of the top of the lower 48 bits (in other words, the top 16 bits of an address should all be 0 or all 1, based on the bit just below 16 bits). This rule is in place to guarantee that the architecture can "safely expand the number of valid bits in the address range". This would indicate that the code is either overwriting some pointer data with other stuff, or going out of bounds when reading some pointer value.

Another likely causes is unaligned access with an SSE register - in other word, reading a 16-byte SSE register from an address that isn't 16-byte aligned.

There are, as I said, many other possible reasons, but most of those involve things that "normal" code wouldn't be doing in a 32- or 64-bit OS (such as loading segment registers with invalid selector index or writing to MSR's (model specific registers)).