我有一个 iOS 应用程序,它做了很多低级套接字工作,最近在添加 IPv6 支持后,我注意到在运行我的应用程序时有时会发生内核恐慌。整个设备重新启动,我得到一个包含很多神秘信息的恐慌文件(包括我的应用程序中没有堆栈帧),但有一些关键信息如下所示:
panic(cpu 0 caller 0xffffff800f15fba0): assertion failed: se->se_flags & SEF_ATTACHED, file: /SourceCache/xnu/xnu-2784.30.7/bsd/kern/uipc_socket.c, line: 6228
Debugger message: panic
幸运的是这个模块是开源的,我在这里找到了关闭版本的代码:http: //opensource.apple.com//source/xnu/xnu-2782.1.97/bsd/kern/uipc_socket.c
该错误似乎与此功能相匹配:
void
sockaddrlist_remove(struct sockaddr_list *sl, struct sockaddr_entry *se)
{
VERIFY(se->se_flags & SEF_ATTACHED);
se->se_flags &= ~SEF_ATTACHED;
VERIFY(sl->sl_cnt != 0);
sl->sl_cnt--;
TAILQ_REMOVE(&sl->sl_head, se, se_link);
}
我很确定第一个 VERIFY() 基本上是一个断言,它失败了。
但是,这只是告诉我,在这段代码运行之前的某个时间,我的程序可能损坏了一些内存。因此,像大多数内存损坏一样,找到原因非常具有挑战性。
根据我的日志记录,我看到这种情况发生在大致一些网络调用之后,包括 socket()、connect()、read() 和 write(),尽管在这里给出代码是不可行的。
另一条信息是这只发生在 IPv6 上。在 IPv4 上,一切正常。但是我已经清理了 IPv6 代码,并没有发现任何明显错误的地方。我也很困惑用户空间中的任何内存损坏问题都会导致内核失败。也许了解这会如何发生将有助于我追踪问题。
大多数人会说的下一步是尝试保护 malloc,但不幸的是,当我尝试打开它时,我遇到了另一个问题,所以现在让我们假设我目前不能使用保护 malloc。
我还尝试在运行时实时附加到程序并使其崩溃,但它不会在任何地方的调试器中停止,它只是重新启动整个设备(iPad)。
如果有人对这个棘手的错误有任何分类的想法,请告诉我。
编辑:
根据其中一个答案的反馈,我检查了相关套接字 API 调用的所有长度,这些似乎是正确的。所以这里似乎还有其他问题,可能会覆盖内存。
我可以尝试使用“Malloc Guard Edges”,但问题停止发生。我不能使用“Guard Malloc”,因为它只能在模拟器上运行,而且由于它与硬件的交互方式,我的应用程序在模拟器上运行不佳。
如果有人有更多想法,请告诉我。