What's the meaning of exception code “EXC_I386_GPFLT”?

给你一囗甜甜゛ 提交于 2019-11-26 06:19:23

问题


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!


回答1:


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




回答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.




回答3:


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!




回答4:


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.




回答5:


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



回答6:


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.




回答7:


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




回答8:


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]




回答9:


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


来源:https://stackoverflow.com/questions/19651788/whats-the-meaning-of-exception-code-exc-i386-gpflt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!