C++ 异常代码“EXC_I386_GPFLT”是什么意思?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19651788/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:01:28  来源:igfitidea点击:

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

c++cexc-bad-access

提问by Lewen

What's the meaning of exception code EXC_I386_GPFLT?

异常代码的含义是EXC_I386_GPFLT什么?

Does its meaning vary according to the situation?

它的含义是否因情况而异?

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

在那种情况下,我指的是EXC_BAD_ACCESS带有异常代码的异常类型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...)

该程序是在 Xcode 5.0.1 中开发的,处理cblas_zgemm()BLAS 库。(好吧,我想这无关紧要...)

Thank you very much!

非常感谢!

回答by Mats Petersson

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.

EXC_I386_GPFLT 肯定是指“一般保护错误”,这是 x86 告诉您“您做了不允许做的事情”的方式。这通常并不意味着您访问超出内存范围,但可能是您的代码超出范围并导致以某种方式使用错误代码/数据,从而导致某种保护违规。

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.

不幸的是,如果没有更多的上下文,很难确切地弄清楚问题是什么,在我的 AMD64 程序员手册,2005 年第 2 卷中列出了 27 种不同的原因——从各方面来看,8 年后很可能会增加一些更多的。

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.

如果它是 64 位系统,那么可能的情况是您的代码使用的是“非规范指针”——这意味着 64 位地址的构成方式是地址的高 16 位不是低 48 位顶部的所有副本(换句话说,地址的前 16 位应全部为 0 或全部为 1,基于刚好低于 16 位的位)。这条规则是为了保证架构可以“安全地扩展地址范围内的有效位数”。这表明代码要么用其他东西覆盖了某些指针数据,要么在读取某些指针值时越界。

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.

另一个可能的原因是对 SSE 寄存器的未对齐访问 - 换句话说,从非 16 字节对齐的地址读取 16 字节 SSE 寄存器。

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

正如我所说,还有许多其他可能的原因,但其中大多数涉及“正常”代码在 32 位或 64 位操作系统中不会做的事情(例如加载具有无效选择器索引的段寄存器或写入MSR(型号特定寄存器))。

回答by Khalid Mammadov

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.

要调试和查找源:为应用程序启用 Zombies (Product\Scheme) 并启动 Instruments,选择 Zombies。在 Xcode 中运行您的应用程序然后转到 Instruments 开始录制。返回您的应用程序并尝试生成错误。如果有的话,仪器应该检测到错误的调用(对僵尸)。

Hope it helps!

希望能帮助到你!

回答by trojanfoe

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 looksinteresting:

好的,所以这是一个一般的保护错误(正如它的名字所暗示的那样)。谷歌搜索“i386 general protection fault”产生了很多命中,但这看起来很有趣:

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

内存保护也是使用段描述符实现的。首先,处理器检查加载到段寄存器中的值是否引用了有效的描述符。然后它检查计算出的每个线性地址是否实际位于段内。此外,根据段描述符中的信息检查访问类型(读、写或执行)。每当这些检查之一失败时,就会引发异常(中断)13(十六进制 0D)。此异常称为一般保护错误 (GPF)。

That 13matches 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.

13与我们在头文件中看到的相符,所以看起来是一样的。然而,从应用程序员的角度来看,这只是意味着我们正在引用我们不应该引用的内存,并且它在硬件上的实现方式并不重要。

回答by ctietze

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.

我在协议中添加了一个方法声明,其中包括throws;但是在那个特定的测试中甚至没有使用潜在的投掷方法。在测试中启用僵尸听起来太麻烦了。

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

结果是 ?K clean 成功了。当它解决实际问题时,我总是大吃一惊。

回答by Stanislau Baranouski

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:

我在 Swift 4.2 也有类似的例外。我花了大约半个小时试图在我的代码中找到一个错误,但是在关闭 Xcode 并删除派生数据文件夹后问题就消失了。这是快捷方式:

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

回答by Manuel

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.

就我而言,在 iOS 模拟器上运行应用程序时,Xcode 中抛出了错误。虽然我无法回答“错误意味着什么”这个具体问题,但我可以说是什么帮助了我,也许它也帮助了其他人。

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

我的解决方案是Erase All Content and Settings在模拟器和Clean Build Folder...Xcode 中。

回答by nuynait

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 safeAreaLayoutGuideto selfsolve the issue.

更改safeAreaLayoutGuideself解决问题。

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

意思是将视图与超级视图的前导、尾随、顶部、底部对齐,而不是与安全区域对齐)

回答by Stephen J

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.

这发生在我身上,因为 Xcode 似乎不喜欢我在两个不同的类中使用相同的变量名(符合相同的协议,如果这很重要,尽管变量名与任何协议无关)。我只是重命名了我的新变量。

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

在调试时,我必须进入它崩溃的 setter 才能看到它。此答案适用于 iOS

回答by Matjan

If the error is thrown inside a closure that defines selfas 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]

如果错误是在定义self为的闭包中抛出的unowned,则您可以访问的内容可能会受到限制,并且在某些情况下会收到此错误代码。尤其是在调试的时候。如果您遇到这种情况,请尝试更改[unowned self][weak self]

回答by Peter B. Kramer

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