2014-03-27 84 views
2

我的代碼使用ctl_enqueuedata進行內核用戶通信。ctl_enqueuedata內的Osx內核崩潰

我注意到,有時(我真的不能重現) - 我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 

看來,插座憑證是零。

怎麼可能。是內核bug還是我濫用ctl_enqueuedata?

回答

1

這件事情讓我覺得奇怪的是,插座在ctl_enqueuedata的末尾被銷燬(sodealloc)。這不是我在正常操作中所期望的。

難道是你的套接字的ctl_disconnect_func/ctl_disconnect回調被調用和調用ctl_enqueuedata()之間的競態條件?一旦你的斷開連接回調觸發,你應該確保沒有新的數據入隊。此外,您應該確保在您從斷開連接回撥中返回時,所有入隊操作都已完成。實際上,這意味着您需要在排隊時持有鎖,並在斷開連接時獲取該鎖,同時更改數據結構以註銷連接。

如果你已經證實,這絕對不是你的情況的問題:這是什麼內核版本?我很難調整行號。

+0

是的!我也在想,當時客戶端正在斷開連接,並且內核正在使用ctl_enqueuedata發送數據。但我試圖在ctl_disconnect_func和lck_shared_lock之前使用lck_rw_lock_exclusive(dlist.read_write_lock)創建一個鎖,然後再ctl_enqueuedata。 –

+0

我不確定它是否真的有效,但我注意到https://developer.apple.com/library/mac/documentation/Kernel/Reference/kern_control_header_reference/Reference/reference.html這有助於說:「ctl_disconnect_func用於接收通知客戶端已與內核控制器斷開連接。「如果這是正確的,那麼鎖定將無法幫助 - 客戶端已斷開連接,並且我們剛剛收到關於它的通知 –

+0

另外,如果用戶空間進程剛剛崩潰會怎樣? (在我的情況下也是這樣)。在這種情況下,不管我們在ctl_disconnect_func中有什麼樣的鎖定 - 用戶空間不存在 –