Lew*_*wen 111 c c++ exc-bad-access
异常代码的含义是EXC_I386_GPFLT什么?
其含义是否因情况而异?
在这种情况下,我指的是EXC_BAD_ACCESS带有异常代码的异常类型EXC_I386_GPFLT
该程序是在Xcode 5.0.1中开发的,处理cblas_zgemm()BLAS库.(好吧,我想这没关系......)
非常感谢你!
Mat*_*son 103
EXC_I386_GPFLT肯定是指"一般保护错误",这是x86告诉你"你做了一些你不允许做的事"的方法.它通常并不意味着您访问内存不足,但可能是您的代码超出范围并导致错误的代码/数据以某种方式使用保护违规.
不幸的是,如果没有更多的上下文,很难弄清楚问题究竟是什么,我的AMD64程序员手册中列出了27种不同的原因,从2005年开始的第2卷 - 从所有情况来看,8年之后可能会增加一些更多.
如果它是一个64位系统,一个合理的场景是你的代码使用"非规范指针" - 这意味着64位地址的形成方式是地址的高16位不是低48位的顶部的所有副本(换句话说,地址的前16位应全部为0或全1,基于低于16位的位).此规则用于保证架构可以"安全地扩展地址范围内的有效位数".这表明代码要么用其他东西覆盖某些指针数据,要么在读取某些指针值时超出范围.
另一个可能的原因是使用SSE寄存器进行未对齐访问 - 换句话说,从非16字节对齐的地址读取16字节SSE寄存器.
正如我所说,还有许多其他可能的原因,但大多数都涉及"正常"代码不会在32位或64位操作系统中执行的操作(例如加载具有无效选择器索引的段寄存器或写入MSR(模型特定寄存器)).
tro*_*foe 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 */
Run Code Online (Sandbox Code Playgroud)
好的,所以这是一个普遍的保护错误(正如其名称所暗示的那样).谷歌搜索"i386一般保护故障"产生了许多命中,但这看起来很有趣:
内存保护也使用段描述符实现.首先,处理器检查段寄存器中加载的值是否引用了有效的描述符.然后它检查计算出的每个线性地址是否实际位于该段内.此外,还根据段描述符中的信息检查访问类型(读,写或执行).只要其中一个检查失败,就会引发异常(中断)13(十六进制0D).此异常称为常规保护错误(GPF).
这13符合我们在头文件中看到的内容,因此它看起来像是一样的东西.然而,从应用程序员的角度来看,它只是意味着我们引用的是不应该存在的内存,而且它在硬件上的实现方式并不重要.
小智 21
调试和查找源:为应用程序启用僵尸(Product\Scheme)和启动仪器,选择Zombies.在Xcode中运行您的应用程序然后转到仪器开始录制.返回到您的应用程序并尝试生成错误.如果有的话,仪器应该检测到不良呼叫(僵尸).
希望能帮助到你!
cti*_*tze 16
我想知道为什么这会在我的单元测试中出现.
我在方案中添加了一个方法声明,其中包括throws; 但是潜在的投掷方法甚至没有用于那个特定的测试.在测试中启用Zombies听起来有点麻烦.
结果显示⌘K干净就行了.当解决实际问题时,我总是很乏味.
我在 Swift 4.2 也有类似的例外。我花了大约半个小时试图在我的代码中找到一个错误,但是在关闭 Xcode 并删除派生数据文件夹后问题就消失了。这是快捷方式:
rm -rf ~/Library/Developer/Xcode/DerivedData
Run Code Online (Sandbox Code Playgroud)