Macos EXC_保护例外
当我试图关闭一个套接字句柄时,OSX应用程序崩溃,在以前的所有平台上都运行良好,但在约塞米蒂似乎崩溃了 这条线在哪里Macos EXC_保护例外,macos,exception,Macos,Exception,当我试图关闭一个套接字句柄时,OSX应用程序崩溃,在以前的所有平台上都运行良好,但在约塞米蒂似乎崩溃了 这条线在哪里 -(void)stopPacketReceiver { close(sd); } 在Xcode中,它暂停所有线程并显示EXC_GUARD异常,这是什么样的异常,有什么想法吗 谢谢, 艾哈迈德 编辑: 这里是我得到的异常代码 异常类型:EXC_GUARD 异常代码:0x400000010000000,0x08fd4dbfade2dead首先,听起来棒极了-听起来好像它捕获了
-(void)stopPacketReceiver
{
close(sd);
}
在Xcode中,它暂停所有线程并显示EXC_GUARD异常,这是什么样的异常,有什么想法吗
谢谢,
艾哈迈德
编辑:
这里是我得到的异常代码
异常类型:EXC_GUARD
异常代码:0x400000010000000,0x08fd4dbfade2dead首先,听起来棒极了-听起来好像它捕获了可能是EXC\u BAD\u访问的内容(但这是一个猜测) 我猜
sd
不是一个有效的描述符。可能是Yosemite中更改的API导致您创建描述符的位置返回NULL,也可能是Yosemite中事件时间线的更改导致它已被清理
这里的调试提示:追溯到sd的创建过程。来自Quinn的《爱斯基摩人》(苹果开发者关系、开发者技术支持、核心操作系统/硬件),由我编辑,以删除特定情况下的特定内容:
EXC_GUARD是10.9中的一项更改,旨在帮助您检测文件
描述符问题。具体来说,系统现在可以标记特定的
被保护的文件描述符,之后在
这些描述符将触发EXC_GUARD崩溃(当它想要时)
操作这些文件描述符时,系统使用特殊的“保护”
专用API)
我们将此添加到系统中,因为我们发现很多应用程序都是
意外关闭文件描述符后神秘崩溃
由系统库打开的。例如,如果一个应用程序
关闭用于访问备份的SQLite文件的文件描述符
核心数据存储之后,核心数据将在很久之后神秘地崩溃
在…上guard异常会更快地发现这些问题,因此
使它们更易于调试
对于EXC_GUARD崩溃,异常代码分解如下:
o第一个异常代码…包含三位
字段:
- 前三位…表示[防护类型]
- 前32位的其余部分…表示[不允许的操作]
- 底部32位表示有问题的描述符
sd
包含您曾经拥有的描述符的描述符编号,但现在是一个悬空引用,因为您已经关闭了描述符,并且该编号现在已重新用于其他人的描述符。或者可能sd
只是有一个垃圾值
我们可以从异常代码中解码更多的信息,但最有可能的是,您只需准确地跟踪sd
在其生命周期中所做的事情
更新: 从编辑后的问题中,我看到您已经发布了异常代码。使用中的常量,防护类型为
guard\u type\u FD
,不允许的操作为kGUARD\u EXC\u CLOSE
(即CLOSE()
),描述符为0(FILENO STDIN)
因此,在所有的可能性中,当sd
实例变量未初始化时,调用了stopPacketReceiver
,并且具有所有实例变量在首次分配对象时获得的默认0值
神奇的值是0x08fd4dbfade2dead
,根据最初的开发者论坛帖子,“表明防护是由SQLite应用的”。这似乎很奇怪。描述符0通常在进程启动时打开(可能引用/dev/null)。因此,SQLite不应该拥有它
我怀疑发生的事情是,您的代码实际上关闭了描述符0两次。第一次没有守卫。关闭FILENO\u STDIN
是合法的。如果程序不希望/不需要原始标准输入,则有时会重新打开该描述符以引用其他内容(例如/dev/null)。在你的情况下,这将是一个意外,但不会引发例外。一旦它被关闭,描述符就可以被重新分配到打开描述符的下一个对象。我猜那是SQLite。当时,SQLite对描述符进行了保护。然后,您的代码再次尝试关闭它,并得到EXC\u-GUARD
异常
如果我是对的,那么代码出现异常是有点随机的(尽管它总是做一些不好的事情)。将文件描述符0分配给对其应用保护的子系统可能是竞争条件,也可能是操作系统版本之间操作顺序的变化
您需要更加小心,不要关闭未打开的描述符。您应该将任何用于保存文件描述符的实例变量初始化为-1,而不是0。同样,如果您关闭了自己拥有的描述符,那么应该将实例变量设置回-1。有趣的是,即使在创建套接字之前调用close on sd,它也不会抱怨,只是静静地运行。。我仍在努力解决它谢谢你的信息肯,我已经添加了上面的异常代码,你能帮我进一步确定这些代码说什么。另外,我想知道我有一个C库动态库,这个应用程序使用它,在这个库中创建的任何套接字句柄仍然是我进程的一部分,或者否?。您提到您的代码正在关闭它不拥有的套接字,我认为套接字句柄在进程中是唯一的,但在系统中不是唯一的?那么,我的应用程序如何才能关闭它不拥有的套接字呢?我可能有错误的假设,所以如果你能解释一下,我将不胜感激。我已经编辑了我的答案来解释异常代码。库创建的任何套接字