Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos EXC_保护例外_Macos_Exception - Fatal编程技术网

Macos EXC_保护例外

Macos EXC_保护例外,macos,exception,Macos,Exception,当我试图关闭一个套接字句柄时,OSX应用程序崩溃,在以前的所有平台上都运行良好,但在约塞米蒂似乎崩溃了 这条线在哪里 -(void)stopPacketReceiver { close(sd); } 在Xcode中,它暂停所有线程并显示EXC_GUARD异常,这是什么样的异常,有什么想法吗 谢谢, 艾哈迈德 编辑: 这里是我得到的异常代码 异常类型:EXC_GUARD 异常代码:0x400000010000000,0x08fd4dbfade2dead首先,听起来棒极了-听起来好像它捕获了

当我试图关闭一个套接字句柄时,OSX应用程序崩溃,在以前的所有平台上都运行良好,但在约塞米蒂似乎崩溃了

这条线在哪里

-(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位表示有问题的描述符

o第二个异常代码是与 守卫

您的代码正在关闭它不拥有的套接字。可能
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库动态库,这个应用程序使用它,在这个库中创建的任何套接字句柄仍然是我进程的一部分,或者否?。您提到您的代码正在关闭它不拥有的套接字,我认为套接字句柄在进程中是唯一的,但在系统中不是唯一的?那么,我的应用程序如何才能关闭它不拥有的套接字呢?我可能有错误的假设,所以如果你能解释一下,我将不胜感激。我已经编辑了我的答案来解释异常代码。库创建的任何套接字