He descubierto cómo determinar la causa de las congelaciones. El truco consiste en tomar una muestra del proceso WindowServer del sistema mientras está congelado.
Por supuesto, como no puedo interactuar con el sistema mientras está congelado, utilicé un ordenador aparte para hacer ssh en mi mac, cambiar esa sesión a la cuenta Root con sudo -s
y luego ejecutar el siguiente comando en el momento en que el sistema se congela: sample WindowServer 5
Eso crea una muestra que muestra lo que el servidor de la ventana se atascó haciendo mientras estaba congelado, y lo mostró consistentemente bloqueado en las siguientes funciones:
4613 Thread_1658: Main Thread DispatchQueue_<multiple>
+ 4613 start (in libdyld.dylib) + 1 [0x7fff71e563d5]
+ 4613 ??? (in WindowServer) load address 0x107900000 + 0x150d [0x10790150d]
+ 4613 SLXServer (in SkyLight) + 1349 [0x7fff6b2b7af1]
+ 4613 server_loop (in SkyLight) + 602 [0x7fff6b2b7d52]
+ 2238 CGXRunOneServicesPass (in SkyLight) + 731 [0x7fff6b2b6df9]
+ ! 2236 mach_msg (in libsystem_kernel.dylib) + 60 [0x7fff71f8b76c]
+ ! : 2236 mach_msg_trap (in libsystem_kernel.dylib) + 10 [0x7fff71f8b22a]
+ ! 2 mach_msg (in libsystem_kernel.dylib) + 60,68 [0x7fff71f8b76c,0x7fff71f8b774]
+ 2087 CGXRunOneServicesPass (in SkyLight) + 1761 [0x7fff6b2b71ff]
+ ! 2086 post_port_data (in SkyLight) + 237 [0x7fff6b2b7551]
+ ! : 1986 rendezvousHandler(unsigned int, mach_msg_header_t*, void*) (in SkyLight) + 29 [0x7fff6b138bd1]
+ ! : | 1984 CGXHandleMessage (in SkyLight) + 101 [0x7fff6b2738bc]
+ ! : | + 1984 invocation function for block in rendezvousHandler(unsigned int, mach_msg_header_t*, void*) (in SkyLight) + 125 [0x7fff6b138c5f]
+ ! : | + 1979 _XGetEventShmem (in SkyLight) + 310 [0x7fff6b0837bd]
+ ! : | + ! 1979 WSEventSourceCreateGraphShmemForAuditToken (in SkyLight) + 82 [0x7fff6b1bccb5]
+ ! : | + ! 1978 WSAuditTokenCanMonitorEvents (in SkyLight) + 171 [0x7fff6b2bab0d]
+ ! : | + ! : 1978 WSAuditTokenIsPostEventTCCApprovedCachingFailure (in SkyLight) + 320 [0x7fff6b2ba977]
+ ! : | + ! : 1978 TCCAccessCheckAuditToken (in TCC) + 269 [0x7fff6c788a9e]
+ ! : | + ! : 1978 TCCAccessRequest (in TCC) + 345 [0x7fff6c783e5d]
+ ! : | + ! : 1978 _os_activity_initiate_impl (in libsystem_trace.dylib) + 53 [0x7fff7206889c]
+ ! : | + ! : 1978 _dispatch_lane_barrier_sync_invoke_and_complete (in libdispatch.dylib) + 60 [0x7fff71e15129]
+ ! : | + ! : 1978 _dispatch_client_callout (in libdispatch.dylib) + 8 [0x7fff71e0963d]
+ ! : | + ! : 1978 __TCCAccessRequest_block_invoke.68 (in TCC) + 862 [0x7fff6c784549]
+ ! : | + ! : 1978 tccd_send_message (in TCC) + 656 [0x7fff6c784c25]
+ ! : | + ! : 1978 xpc_connection_send_message_with_reply_sync (in libxpc.dylib) + 178 [0x7fff72088647]
+ ! : | + ! : 1978 dispatch_mach_send_with_result_and_wait_for_reply (in libdispatch.dylib) + 50 [0x7fff71e1d882]
+ ! : | + ! : 1978 _dispatch_mach_send_and_wait_for_reply (in libdispatch.dylib) + 609 [0x7fff71e1d3e7]
+ ! : | + ! : 1978 mach_msg (in libsystem_kernel.dylib) + 60 [0x7fff71f8b76c]
+ ! : | + ! : 1978 mach_msg_trap (in libsystem_kernel.dylib) + 10 [0x7fff71f8b22a]
Esto está tomado de una muestra que captó dos segundos de una congelación.
Esto demuestra claramente que el TCC es el culpable. Ahora que lo sé, la siguiente cuestión es averiguar cómo solucionar los bloqueos.