异常代码 EXC_I386_GPFLT的含义是什么?
EXC_I386_GPFLT
它的含义是否因情况而异?
在这种情况下,我指的是异常类型 EXC_BAD_ACCESS和异常代码 EXC_I386_GPFLT
EXC_BAD_ACCESS
该程序是在 Xcode 5.0.1中开发的,处理 BLAS 库的 cblas_zgemm()
cblas_zgemm()
非常感谢!
您通常可以从头文件中获得信息,例如:
$ 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与我们在头文件中看到的匹配,所以看起来是一样的。然而,从应用程序程序员的角度来看,这仅仅意味着我们引用了不应该引用的内存,并且它在硬件上是如何实现的并不重要。
13
EXC _ I386 _ GPFLT 肯定指的是“一般保护错误”,这是 x86告诉你“你做了一些你不允许做的事情”的方式。这通常并不意味着访问超出了内存范围,但可能是您的代码超出了范围,导致错误的代码/数据以某种方式被使用,从而导致某种类型的保护违规。
不幸的是,如果没有更多的背景信息,很难确切地找出问题所在。在我的 AMD64程序员手册(2005年第二卷)中列出了27种不同的原因——所有人都认为,8年后可能还会有更多的原因。
如果它是一个64位系统,一个看似合理的场景是你的代码使用了一个“非规范指针”——这意味着一个64位地址是这样形成的: 地址的上16位并不全是下48位顶部的副本(换句话说,地址的上16位应该全是0或全是1,基于略低于16位的位)。这个规则是为了保证体系结构能够“安全地扩展地址范围内的有效位数”。这将表明代码要么用其他内容覆盖某些指针数据,要么在读取某些指针值时出界。
另一个可能的原因是 SSE 寄存器的不对齐访问——换句话说,从一个没有16字节对齐的地址读取16字节的 SSE 寄存器。
正如我所说,还有许多其他可能的原因,但大多数都涉及到“正常”代码在32位或64位操作系统中不会做的事情(例如加载带有无效选择器索引的段寄存器或写入 MSR (模型特定的寄存器))。
调试和查找源代码: 启用僵尸应用程序(产品方案)和启动仪器,选择僵尸。 在 Xcode 运行你的应用程序 然后去仪器开始录音。 返回到应用程序并尝试生成错误。 如果有错误调用(对僵尸) ,则应该检测这种错误调用。
希望能有帮助!
我想知道为什么在我的单元测试中会出现这种情况。
我已经在一个包含 throws的协议中添加了一个方法声明; 但是潜在的抛出方法甚至没有在那个特定的测试中使用。在测试中启用僵尸听起来太麻烦了。
throws
事实证明,一次彻底的清理就能解决问题。当那样解决实际问题的时候,我总是惊呆了。
在我的例子中,这个错误是在 Xcode iOS 模拟器上运行应用程序时抛出的。虽然我不能回答具体的问题“什么错误意味着”,我可以说什么帮助我,也许它也帮助别人。
对我来说,解决方案是在模拟器中使用 Erase All Content and Settings,在 Xcode 使用 Clean Build Folder...。
Erase All Content and Settings
Clean Build Folder...
这种情况发生在我身上是因为 Xcode 似乎不喜欢我在两个不同的类中使用相同的变量名(如果这很重要的话,那么它们遵循相同的协议,尽管变量名在任何协议中都没有任何关联)。我只是简单地重命名了我的新变量。
在调试的时候,我不得不进入 setter 崩溃的地方才能看到它。这个答案适用于 iOS
我在 Swift 4.2也有过类似的例外。我花了大约半个小时试图在我的代码中找到一个 bug,但是在关闭 Xcode 并删除派生数据文件夹之后,问题已经解决了。这里有一条捷径:
rm -rf ~/Library/Developer/Xcode/DerivedData
如果错误被抛出到将 self定义为 unowned的闭包中,您可能会受到访问内容的限制,并且在某些情况下会得到这个错误代码。尤其是在调试的时候。如果是这种情况,请尝试将 [unowned self]改为 [weak self]
self
unowned
[unowned self]
[weak self]
我在做这个的时候得到了这个错误:
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
我在离开一个视图时遇到了这个问题(跳回到前一个视图)。
原因是
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) ])
将 safeAreaLayoutGuide改为 self可以解决这个问题。
safeAreaLayoutGuide
意思是将视图与管理视图的前导、尾随、顶部、底部对齐,而不是到达安全区域)
对于我来说,这个问题与情节串连板有关,可以选择 ViewController build For set iOS 9.0,以及之前为 iOS 10.0和更高版本设置的版本。实际上我想把版本从10降级到 iOS 9.3。
我在 Xcode 12.0 Beta 6(仅在 iOS 14模拟器上)的旋转崩溃中看到了这个错误代码。但是它不会在我真正运行 iOS13的设备上崩溃!因此,如果你正在运行测试版,并在模拟器中看到旋转崩溃,也许你只需要在一个真正的设备上运行非测试版 iOS 版本。
我可以得到这个错误与 UnsafeMutablePointer工作
UnsafeMutablePointer
let ptr = rawptr.assumingMemoryBound(to: A.self) //<-- wrong A.self Change it to B.Self ptr.pointee = B()
在我的例子中,EXC_I386_GPFLT是由于属性 getter 中缺少返回值而引起的,如下所示:
- (CppStructure)cppStructure { CppStructure data; data.a = self.alpha; data.b = self.beta; return data; // this line was missing }
Xcode 12.2
我的问题是愚蠢的 Xcode Playground。对我来说,这个游乐场自从几年前问世以来就一直不稳定,苹果公司一团糟。
删除派生数据等没有帮助,唯一的方法,使我的代码不抛出是运行它在一个应用程序项目
我在 Swift/iOS 上看到了同样的错误。 在我的例子中,这是因为我试图通过直接使用它的 start()函数来启动 (NS)Operation。但是我需要做的是把它传递给 OperationQueue。像这样的 var queue = OperationQueue(); queue.addOperation(myOperation)
start()
(NS)Operation
OperationQueue
var queue = OperationQueue(); queue.addOperation(myOperation)
老问题了,没什么 Objective-C 的东西被问到所以我会把我的硬币扔进去,也许能帮到别人。
有典型的 EXC _ BAD _ ACCESS,并与究竟是什么引起它挣扎。
经过深思熟虑,我发现这是由于我的代码引用了块内部的一个变量,这个变量是在块外定义的,并且没有使用 _ _ block 前缀。引用的变量被传递给块中的方法调用,并被引用和定义为一个自动释放参数。
很难用语言来解释。因此,一个 example = code 用于删除我使用块枚举的数组中的客户。“ error”被传入。然后我将它传递给块中调用的方法。在方法调用中更改错误参数的值。然后我尝试在块之外引用它。然后我就得到了错误的访问权限。这些问题和 OP 的问题没有什么关系,但是盯着这个问题让我看到了这个页面,其他人可能会发现这个问题很有用。
- (BOOL)deleteCustomer:(CHCustomer *)customer error:(NSError *__autoreleasing*)error { __block BOOL success = YES; NSMutableArray *customerOrders = [self ordersForCustomer:customer error:error]; if ([customerOrders count] > 0) { [customerOrders enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { CHOrderHeader *orderHeader = (CHOrderHeader *)obj; if (![self deleteOrderForOohSeqNo:[orderHeader oohSeqNo] preserveExistingPhotoKeys:NO error:error]) { *stop = YES; success = NO; } }]; // enumerateObjectsUsingBlock } // EXC_BAD_ACCESS occurred on line below: NSLog(@"Is this an NSError? %@", [*error class]); return success; }
在我的例子中,我没有在 String.localizedStringWithFormat的 format参数中使用正确的占位符:
String.localizedStringWithFormat
format
let format = "I have an %s." let string = "exception" String.localizedStringWithFormat(format, string)
将 %s改为 %@解决了这个问题。
%s
%@