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


117

异常代码是什么意思EXC_I386_GPFLT

它的含义是否随情况而变化?

在这种情况下,我指的是EXC_BAD_ACCESS带有异常代码的异常类型EXC_I386_GPFLT

该程序是用Xcode 5.0.1开发的,用于处理cblas_zgemm()BLAS库。(嗯,我想这没关系...

非常感谢你!

Answers:


112

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

不幸的是,如果没有更多的背景信息,可能很难确切地找出问题所在,我的《 AMD64程序员手册》(第2卷)从2005年开始列出了27种不同的原因-从所有原因来看,很可能8年后会增加一些原因。更多。

如果是64位系统,则可能的情况是您的代码正在使用“非规范指针”,这意味着64位地址的形成方式是该地址的高16位不前48位低位的所有副本(换句话说,地址的前16位应全部为0或全为1,基于16位以下的位)。制定此规则是为了确保体系结构可以“安全地扩展地址范围内的有效位数”。这将表明该代码或者正在用其他东西覆盖某些指针数据,或者在读取某些指针值时超出范围。

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

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



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

好的,这是一般性的保护错误(无论如何,顾名思义)。谷歌搜索“ i386常规保护故障”会产生很多成功,但这看起来很有趣:

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

13与我们在头文件中看到的相匹配,因此看起来就像是同一件事。但是,从应用程序程序员的角度来看,这仅意味着我们在引用不应使用的内存,并且在硬件上实现的方式也无关紧要。


1
但是,现代操作系统通常不使用段来进行内存保护。所有这些都由MMU完成,并会导致PF矢量14(通常显示为“分段故障”)。
Mats Petersson

16

我想知道为什么在我的单元测试中会出现这种情况。

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

事实证明,cleanK干净就可以了。当我解决实际问题时,我总是很沮丧。


这也为我在Swift中解决了。谢谢!
lwdthe1

8

我在Swift 4.2上也有类似的例外。我花了大约半个小时试图在代码中查找错误,但是在关闭Xcode并删除派生数据文件夹后,问题不再存在。这是捷径:

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

2

就我而言,在iOS模拟器上运行应用程序时,在Xcode中引发了错误。虽然我无法回答“错误的含义”这个特定问题,但我可以说是什么对我有所帮助,也许也可以对其他人有所帮助。

对我来说,解决方案是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)
])

进行更改safeAreaLayoutGuideself解决问题。

含义使视图与超级视图的前导,尾随,顶部,底部对齐,而不是与安全区域对齐)


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

对我来说,它与情节提要有关的问题是,对于设置为iOS 9.0的ViewController构建选项,以及以后为iOS 10.0和更高版本设置的选项。实际上我想将版本从10降级到iOS 9.3。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.