从 IOUserService 锁定时 IOLock 崩溃 mac OS

IOLock crashes mac OS when locking from IOUserService

我们正在使用需要锁定的数据结构,并希望从使用 PCIDriverKit 探测 PCI 设备时运行的 IOUserClient 线程访问它。

  1. 这种线程不允许使用IOLock吗?当尝试从未使用 IOPCIDevice 提供程序的 IOUserClient 线程使用 IOLock 时,它没有崩溃。
  2. 有没有其他方法可以使用 PCIDriverKit 的锁?与 pthreads.h 链接似乎是不可能的(继续出​​现错误,因为它不是框架的一部分)。

调用 IOLockLock 时,我们得到一个内核崩溃说明:

panic(cpu 3 caller 0xffffff801a9c58f6): Kernel trap at 0xffffff801d6cbb33, type 14=page fault, registers:
CR0: 0x0000000080010033, CR2: 0x0000000000000028, CR3: 0x000000010cc6a074, CR4: 0x00000000000606e0
RAX: 0x0000000000000000, RBX: 0xffffff9359970250, RCX: 0xffffff86902e0c90, RDX: 0x0000000000000008
RSP: 0xffffffa05ff5bc60, RBP: 0xffffffa05ff5bc70, RSI: 0x0000000000000006, RDI: 0xffffff9359765000
R8:  0xffffff801b879b80, R9:  0xffffffc69a7581e0, R10: 0xffffff9359703800, R11: 0x0000000f9358cf60
R12: 0x000000000000001e, R13: 0x0000000000000046, R14: 0xffffff93596ee600, R15: 0xffffff8696094068
RFL: 0x0000000000010286, RIP: 0xffffff801d6cbb33, CS:  0x0000000000000008, SS:  0x0000000000000010
Fault CR2: 0x0000000000000028, Error code: 0x0000000000000000, Fault CPU: 0x3 VMM, PL: 0, VF: 0

Backtrace (CPU 3), Frame : Return Address
0xffffffa05ff5b680 

Return Address
0xffffffa05ff5b680 : 0xffffff801a88e0dd mach_kernel : _handle_debugger_trap + 0x3fd
0xffffffa05ff5b6d0 : 0xffffff801a9d4f33 mach_kernel : _kdp_i386_trap + 0x143
0xffffffa05ff5b710 : 0xffffff801a9c552a mach_kernel : _kernel_trap + 0x55a
0xffffffa05ff5b760 : 0xffffff801a832a2f mach_kernel : _return_from_trap + 0xff
0xffffffa05ff5b780 : 0xffffff801a88d8fd mach_kernel : _DebuggerTrapWithState + 0xad
0xffffffa05ff5b8a0 : 0xffffff801a88dbf3 mach_kernel : _panic_trap_to_debugger + 0x273
0xffffffa05ff5b910 : 0xffffff801b09d81a mach_kernel : _panic + 0x54
0xffffffa05ff5b980 : 0xffffff801a9c58f6 mach_kernel : _sync_iss_to_iks + 0x2c6
0xffffffa05ff5bb00 : 0xffffff801a9c55dd mach_kernel : _kernel_trap + 0x60d
0xffffffa05ff5bb50 : 0xffffff801a832a2f mach_kernel : _return_from_trap + 0xff
0xffffffa05ff5bb70 : 0xffffff801d6cbb33 com.apple.iokit.IOUSBHostFamily : __ZN15IOUSBHostDevice4freeEv + 0x133
0xffffffa05ff5bc70 : 0xffffff801d69824d com.apple.iokit.IOUSBHostFamily : __ZN24AppleUSBHostLegacyClient4freeEv + 0x1b
0xffffffa05ff5bc90 : 0xffffff801d603c05 com.apple.iokit.IOUSBFamily : __ZN14AppleUSBDevice4freeEv + 0xf9
0xffffffa05ff5bce0 : 0xffffff801a97b7a1 mach_kernel : _iokit_notify + 0x141
0xffffffa05ff5bd20 : 0xffffff801a8935c2 mach_kernel : _ipc_kobject_server + 0x162
0xffffffa05ff5bd90 : 0xffffff801a869cf5 mach_kernel : _ipc_kmsg_send + 0x115
0xffffffa05ff5bdf0 : 0xffffff801a89489c mach_kernel : _mach_msg_send_from_kernel_proper + 0xbc
0xffffffa05ff5be20 : 0xffffff801a877f4a mach_kernel : _ipc_right_dealloc + 0x56a
0xffffffa05ff5bea0 : 0xffffff801a8821b8 mach_kernel : _mach_port_deallocate + 0x88
0xffffffa05ff5bed0 : 0xffffff801a87f1e3 mach_kernel : __kernelrpc_mach_port_deallocate_trap + 0x43
0xffffffa05ff5bef0 : 0xffffff801a9a982d mach_kernel : _mach_call_munger64 + 0x29d
0xffffffa05ff5bfa0 : 0xffffff801a833216 mach_kernel : _hndl_mach_scall64 + 0x16
      Kernel Extensions in backtrace:
         com.apple.iokit.IOUSBHostFamily(1.2)[BD7179E5-F2E2-3E86-83D5-F3EA5EE1EE3F]@0xffffff801d688000->0xffffff801d716fff
            dependency: com.apple.driver.AppleBusPowerController(1.0)[C9BC6F50-42B7-3CD3-8608-B8F8236D3243]@0xffffff801bc2e000->0xffffff801bc31fff
            dependency: com.apple.driver.AppleSMC(3.1.9)[1CE81438-E589-30EA-B40B-615AC3BDBED4]@0xffffff801bf56000->0xffffff801bf6efff
            dependency: com.apple.driver.usb.AppleUSBCommon(1.0)[A8CD0277-B482-3874-8AA0-C7177FE83D1E]@0xffffff801c0a6000->0xffffff801c0a9fff
            dependency: com.apple.driver.AppleUSBHostMergeProperties(1.2)[6086D16D-B5BA-3D7F-9EAD-F6E9E56459E4]@0xffffff801d783000->0xffffff801d783fff
            dependency: com.apple.iokit.IOACPIFamily(1.4)[1B2FE91E-3EC7-3ED3-AF6B-E9C4BE29D5E3]@0xffffff801ce42000->0xffffff801ce43fff
         com.apple.iokit.IOUSBFamily(900.4.2)[7215E3ED-95C3-3298-BB93-2458C14F1DAF]@0xffffff801d5e1000->0xffffff801d646fff
            dependency: com.apple.driver.usb.AppleUSBCommon(1.0)[A8CD0277-B482-3874-8AA0-C7177FE83D1E]@0xffffff801c0a6000->0xffffff801c0a9fff
            dependency: com.apple.iokit.IOPCIFamily(2.9)[99A70889-A31C-3B25-8E88-ADD3F317E4E4]@0xffffff801d36a000->0xffffff801d392fff
            dependency: com.apple.iokit.IOUSBHostFamily(1.2)[BD7179E5-F2E2-3E86-83D5-F3EA5EE1EE3F]@0xffffff801d688000->0xffffff801d716fff

Process name corresponding to current thread: airportd
Boot args: -v keepsyms=1 tlbto_us=0 vti=9 

谢谢


更新: 最终崩溃是由我的 DEXT 中的空指针异常引起的。我的教训是,DEXT 中的此类异常可能会使您的 Mac 完全崩溃,并且日志根本不会提供任何信息(如您所见)。最好的办法是使用 LLDB 进行调试。

  1. 如果您在没有加载任何第 3 方 kexts 的情况下遇到内核恐慌,那是 macOS 中的错误,您应该将其报告给 Apple。这与我在下面说的任何内容无关。在没有内核代码的情况下触发恐慌? 不是你的错,这不应该是可能的,报告它,否则它不会被修复。特别是如果你有一种相当可靠的触发它的方法。如果此问题让您付出金钱,请提交 DTS TSI。
  2. 那个崩溃堆栈看起来不像是直接由来自 dext 的调用触发的。因此,如果您的锁确实导致了崩溃,那么它在某种程度上是偶然的——可能是内存损坏问题——所以很难说您的代码具体是什么触发了这个问题。仅仅因为它在您锁定某个地方时出现,并不意味着它是造成的。也可能是时间变化造成的。
  3. 在dexts中,考虑使用OSAction进行同步,注意你可以通过在.iig中用QUEUENAME macro标记方法来安排处理特定调度队列上的方法文件。不幸的是,所有外部方法都是通过单个 ExternalMethod 方法分派的,因此如果您需要单个用户客户端在不同线程上执行外部方法,据我所知您不能这样做。
  4. 确保你没有在你的 dext 中遇到竞争条件(同样,如果你有,它不应该 KP,但请耐心等待)- 默认情况下,每个对象 都有自己独特的默认队列 - 这意味着主驱动程序对象和用户客户端对象中的方法将运行在不同的线程上,所以如果两个对象相互访问,这必须以线程安全的方式完成,否则您需要为所有用户客户端实例显式使用相同的队列作为驱动程序服务。