【问题标题】:Osx kernel crash inside ctl_enqueuedatactl_enqueuedata 内的 Osx 内核崩溃
【发布时间】:2014-03-27 17:45:45
【问题描述】:

我的代码使用 ctl_enqueuedata 进行内核用户通信。

我注意到有时(我无法真正重现它)- 我在 ctl_enqueuedata 内部崩溃了

当我使用调试器连接时,回溯如下

frame #0: 0xffffff80248bcecb mach_kernel`Debugger(message=<unavailable>) + 555 at model_dep.c:912
frame #1: 0xffffff802481d636 mach_kernel`panic(str=<unavailable>) + 198 at debug.c:336
frame #2: 0xffffff8024b4e45f mach_kernel`kauth_cred_unref_hashlocked(credp=0xffffff8035ca0d58) + 47 at kern_credential.c:4470
frame #3: 0xffffff8024b4cf7d mach_kernel`kauth_cred_unref(credp=<unavailable>) + 29 at kern_credential.c:4521
* frame #4: 0xffffff8024b9e585 mach_kernel`sodealloc(so=0xffffff8035ca0b80) + 21 at uipc_socket.c:710
frame #5: 0xffffff8024b59942 mach_kernel`ctl_unlock [inlined] ctl_sofreelastref + 354 at kern_control.c:263
frame #6: 0xffffff8024b598be mach_kernel`ctl_unlock(so=<unavailable>, refcount=<unavailable>, lr=<unavailable>) + 222 at kern_control.c:1076
frame #7: 0xffffff8024b58ebd mach_kernel`ctl_enqueuedata(kctlref=<unavailable>, unit=<unavailable>, data=<unavailable>, len=<unavailable>, flags=<unavailable>) + 301 at kern_control.c:549
frame #8: 0xffffff7fa6090efd

套接字凭据似乎为零。

怎么可能。是内核错误还是我误用了 ctl_enqueuedata?

【问题讨论】:

    标签: macos kernel kernel-extension mach xnu


    【解决方案1】:

    在这条跟踪中让我感到奇怪的是,套接字在ctl_enqueuedata 的末尾被销毁(sodealloc)。这不是我在正常操作中所期望的。

    可能是您的套接字的ctl_disconnect_func/ctl_disconnect 回调被调用和调用ctl_enqueuedata() 之间存在竞争条件吗?一旦您的断开回调触发,您应该确保没有新数据入队。此外,您应该确保在您从断开连接回调返回时所有入队操作都已完成。在实践中,这意味着您需要在入队时持有锁,并在断开连接时获取该锁,同时更改数据结构以取消注册连接。

    如果您已经确认这绝对不是您的问题:这是什么内核版本?我很难正确协调行号。

    【讨论】:

    • 是的!我也在想当时客户端正在断开连接,内核正在使用 ctl_enqueuedata 发送数据。但是我尝试在 ctl_disconnect_func 和 lck_shared_lock 中使用 lck_rw_lock_exclusive(dlist.read_write_lock) 在 ctl_enqueuedata 之前创建一个锁。
    • 我不确定它是否真的有效,但我注意到developer.apple.com/library/mac/documentation/Kernel/Reference/… 这有助于说“ctl_disconnect_func 用于接收客户端已与内核控制断开连接的通知。”如果这是正确的,那么锁定将无济于事 - 客户端已经断开连接,我们刚刚收到有关它的通知
    • 另外,如果用户空间进程刚刚崩溃会怎样? (在我的情况下也是可能的)。在这种情况下,无论我们在 ctl_disconnect_func 中使用哪种锁 - 用户空间都不存在
    • 再次查看the kern_control.c source,特别是函数int ctl_disconnect(struct socket *so),它在用户空间断开连接时调用(通过uipc_socket.c 中的sodisconnectlocked()),套接字锁定对我来说看起来没问题。我仍然认为您的代码中的断开功能和入队数据之间存在竞争条件。我当然可能是错的,但这似乎是迄今为止最有可能的解释。
    • 这是一个内核错误“Georgy,这是对您提交的错误报告的状态更新:错误 ID 16471801 - 用户空间断开连接时 ctl_enqueuedata 中的随机内核崩溃解决此问题的方法是正在开发中。有空我们会再次跟进。"
    猜你喜欢
    • 1970-01-01
    • 2014-05-28
    • 2014-07-07
    • 2018-06-16
    • 2016-01-17
    • 1970-01-01
    • 2017-10-12
    • 2014-09-16
    • 2016-08-14
    相关资源
    最近更新 更多