IOLock аварийно завершает работу mac OS при блокировке от IOUserService

#macos #driver #iokit #pci #driverkit

Вопрос:

Мы используем структуру данных, которая требует блокировки, и хотим получить к ней доступ из потока IOUserClient, который запускается при поиске устройства PCI с помощью PCIDriverKit.

  1. Разве использование IOLock не допускается в такого рода нитях? При попытке использовать IOLock из потока IOUserClient, который не использует поставщик IOPCIDevice, это сработало без сбоя.
  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. Мой урок заключается в том, что такое исключение в DEXTs может полностью привести к сбою вашего Mac, а журналы вообще не будут информативными (как вы видите). Лучше всего выполнить отладку с помощью LLDB.

Ответ №1:

  1. Если вы попали в панику ядра без загрузки сторонних kexts, это ошибка в macOS, и вы должны сообщить об этом в Apple. Это независимо от всего, что я скажу ниже. Вызвать панику без кода ядра? Это не ваша вина, это не должно быть возможно, сообщите об этом, или это не будет исправлено, особенно если у вас есть способ достаточно надежно запустить его. Подайте DTS TSI, если эта проблема стоит вам денег.
  2. Этот аварийный стек не выглядит так, как будто он напрямую вызван вызовом из dext. Поэтому, если ваша блокировка действительно вызывает сбой, это как — то случайно — возможно, проблема с повреждением памяти, — поэтому трудно сказать, что конкретно в вашем коде вызывает проблему. Просто потому, что он появляется, когда вы запираетесь в определенном месте, это не значит, что это вызвано этим. Это также может быть вызвано изменениями во времени.
  3. В dexts рассмотрите возможность использования OSAction для синхронизации и обратите внимание, что вы можете запланировать обработку методов в определенной очереди отправки, пометив метод QUEUENAME макросом в .iig файле. К сожалению, все внешние методы отправляются через один ExternalMethod метод, поэтому, насколько мне известно, если вам нужен однопользовательский клиент для выполнения внешних методов в разных потоках, вы не можете этого сделать.
  4. Убедитесь, что вы не попали на гонки в вашей аппарат (опять же, это не КП, если у вас есть, но медведь со мной) — по умолчанию у каждого объекта есть своя уникальная очередь по умолчанию — это означает, что методы в основной движущей объекта и пользователя объекта будет выполняться в разных потоках, поэтому, если два объекта друг с другом, что должно быть сделано на многопотоковое исполнение способом, или вам нужно явно использовать одну и ту же очередь, как сервис драйвера для всех экземпляров клиента пользователя.