Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the meaning of exception code "EXC_I386_GPFLT"?

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


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!


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.


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

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.


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)