Main thread is blocked with __psynch_mutexwait

My app is using ARKit and Scenekit to render some animation for user interaction, at some points, it hangs with the below thread backtrace
Anyway to tell what is blocking the main thread?
Code Block
(lldb) thread backtrace
* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
frame #0: 0x00000001b1dd5204 libsystem_kernel.dylib`__psynch_mutexwait + 8
frame #1: 0x00000001cf935224 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_wait + 92
frame #2: 0x00000001cf935174 libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow + 216
frame #3: 0x00000001b821e560 SceneKit`-[SCNRenderer _projectPoint:viewport:] + 220
* frame #4: 0x00000001b82c8438 SceneKit`-[SCNView projectPoint:] + 124
frame #5: 0x000000010477d970 app`static OffScreenIndicator.updateOffScreenOn(displayView=0x00000001071c2b30, sceneView=0x00000001071d5820, target=0x0000000281a3c700, image=0x0000000281411050, color=0x0000000283c3d4c0, frame=0x000000015683e340, self=app.OffScreenIndicator) at OffScreenIndicator.swift:26:37
frame #6: 0x000000010458d5d8 app`ARViewController.phoneIsFar(camPosition=SceneKit.SCNVector3 @ 0x000000016db94730, frame=0x000000015683e340, isTutorial=true, self=0x000000010883bc00) at ARViewController.swift:2434:48
frame #7: 0x000000010458a0b4 app`ARViewController.scanUpdate(frame=0x000000015683e340, showTutorial=true, scanAllDoneAction=0x000000010459300c app`partial apply forwarder for closure #1 () -> () in app.ARViewController.(stateUpdate_tutorial in _ED82BCD2A98A9516DA8B452F58022553)(frame: __C.ARFrame) -> () at <compiler-generated>, self=0x000000010883bc00) at ARViewController.swift:2371:13
frame #8: 0x0000000104560e14 app`ARViewController.stateUpdate_tutorial(frame=0x000000015683e340, self=0x000000010883bc00) at ARViewController.swift:2692:9
frame #9: 0x00000001045609f4 app`implicit closure #22 in implicit closure #21 in ARViewController.bindStateFunctions(frame=0x000000015683e340, self=0x000000010883bc00) at ARViewController.swift:1048:34
frame #10: 0x00000001045506fc app`ARViewController.updateState(frame=0x000000015683e340, self=0x000000010883bc00) at ARViewController.swift:1108:31
frame #11: 0x0000000104550274 app`ARViewController.session(session=0x00000001568cbdd0, frame=0x000000015683e340, self=0x000000010883bc00) at ARViewController.swift:696:9
frame #12: 0x0000000104550778 app`@objc ARViewController.session(_:didUpdate:) at <compiler-generated>:0
frame #13: 0x00000001afa25248 ARKitCore`__36-[ARSession _sessionDidUpdateFrame:]_block_invoke + 128
frame #14: 0x0000000106f37bcc libdispatch.dylib`_dispatch_call_block_and_release + 32
frame #15: 0x0000000106f396c0 libdispatch.dylib`_dispatch_client_callout + 20
frame #16: 0x0000000106f48f34 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 1000
frame #17: 0x0000000183e0111c CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 16
frame #18: 0x0000000183dfb120 CoreFoundation`__CFRunLoopRun + 2508
frame #19: 0x0000000183dfa21c CoreFoundation`CFRunLoopRunSpecific + 600
frame #20: 0x000000019b9c4784 GraphicsServices`GSEventRunModal + 164
frame #21: 0x000000018683aee8 UIKitCore`-[UIApplication _run] + 1072
frame #22: 0x000000018684075c UIKitCore`UIApplicationMain + 168
frame #23: 0x00000001022766b4 app`main at AppDelegate.swift:14:7
frame #24: 0x0000000183aba6b0 libdyld.dylib`start + 4
(lldb)
(lldb) thread list
Process 4264 stopped
* thread #1: tid = 0x131e7b, 0x00000001b1dd5204 libsystem_kernel.dylib`__psynch_mutexwait + 8, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
thread #6: tid = 0x131f75, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.uikit.eventfetch-thread'
thread #9: tid = 0x131f7e, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'AVAudioSession Notify Thread'
thread #11: tid = 0x131ffc, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.NSURLConnectionLoader'
thread #14: tid = 0x132099, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.coreaudio.AQClient'
thread #21: tid = 0x1320d9, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #27: tid = 0x132153, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.CoreMotion.MotionThread'
thread #28: tid = 0x132157, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #46: tid = 0x1321ff, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #49: tid = 0x132202, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #53: tid = 0x13228c, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #58: tid = 0x132397, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'com.apple.arkit.ardisplaylink.0x283d67a00'
thread #59: tid = 0x132398, 0x00000001b1dd5f5c libsystem_kernel.dylib`__ulock_wait + 8, name = 'com.apple.scenekit.scnview-renderer', queue = 'com.apple.scenekit.renderingQueue.ARSCNView0x1071d5820'
thread #60: tid = 0x1323a2, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'H11ANEServicesThread'
thread #61: tid = 0x1323b3, 0x00000001b1db12d0 libsystem_kernel.dylib`mach_msg_trap + 8, name = 'H11ANEServicesThread'
thread #62: tid = 0x13249f, 0x00000001b1db1324 libsystem_kernel.dylib`semaphore_timedwait_trap + 8
thread #65: tid = 0x1324a8, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #67: tid = 0x1324df, 0x00000001b1db1324 libsystem_kernel.dylib`semaphore_timedwait_trap + 8
thread #68: tid = 0x132505, 0x0000000198e9d150 libobjc.A.dylib`object_getClassName, queue = 'com.apple.libdispatch-manager'
thread #69: tid = 0x132507, 0x0000000198e9d150 libobjc.A.dylib`object_getClassName
thread #70: tid = 0x132537, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
thread #71: tid = 0x132538, 0x00000001cf938764 libsystem_pthread.dylib`start_wqthread
(lldb)


The main thread story is pretty clear:
  1. Your code (frame 5) has called -[SCNView projectPoint:] (frame 4).

  2. Internally SceneKit has called -[SCNRenderer _projectPoint:viewport:] (frame 3) which has tried to take a pthread mutex.

  3. That has blocked indefinitely, probably because some other thread is holding the mutex.

Looking through your other threads the most culprit is thread 59 which is labelled com.apple.scenekit.scnview-renderer, and thus something to do with SceneKit, and is itself stuck in __ulock_wait, an os_unfair_lock_t. Beyond that it’s hard to say.

The next time this happens detach the debugger from the app (Debug > Detach) and then press the Home button. Given that the app is hung that should generate a watchdog crash report. Once you have that, post it here. Use the text attachment feature (the paperclip icon) to avoid clogging up the timeline.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
Hi,
Thank you for the reply.
I can replicate the freeze but it's with different type of lock I guess "__psynch_rw_wrlock"
Attached the crash log


Regards,
Hai
For those reading along at home, one of my colleagues (who actually knows something about ARKit and SceneKit!) will be helping Hai Hw in a different context.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Hello,

We are encountering the exact same issue (main thread lock) with SceneKit displaying SCNNodes with SpriteKit materials.


Thread 0 name:
Thread 0 Crashed:
0   libsystem_kernel.dylib        	0x00000001b88e4678 __psynch_rw_wrlock + 8
1   libsystem_pthread.dylib       	0x00000001f24cc150 _pthread_rwlock_lock_wait + 84 (pthread_rwlock.c:647)
2   libsystem_pthread.dylib       	0x00000001f24d31a4 _pthread_rwlock_lock_slow + 728 (pthread_rwlock.c:761)
3   SceneKit                      	0x00000001bfccd760 C3DTransactionFlush + 436 (C3DTransaction.c:214)



Thread 13:
0   libsystem_kernel.dylib        	0x00000001b88e0540 semaphore_wait_trap + 8
1   libdispatch.dylib             	0x00000001815b3bf0 _dispatch_sema4_wait + 28 (lock.c:139)
2   libdispatch.dylib             	0x00000001815b42a8 _dispatch_semaphore_wait_slow + 132 (semaphore.c:132)
3   Metal                         	0x000000019bc4a4e4 -[_MTLCommandBuffer initWithQueue:retainedReferences:synchronousDebugMode:] + 188 (MTLCommandBuffer.m:275)
4   IOGPU                         	0x00000001caecac28 -[IOGPUMetalCommandBuffer initWithQueue:retainedReferences:synchronousDebugMode:] + 108 (IOGPUMetalCommandBuffer.m:39)
5   AGXMetalG14                   	0x00000001f3b491e4 -[AGXG14FamilyCommandBuffer initWithQueue:retainedReferences:] + 64 (agxa_command_buffer_objc.mm:232)
6   AGXMetalG14                   	0x00000001f3b4b608 -[AGXG14FamilyCommandQueue commandBuffer] + 52 (agxa_command_queue_objc.mm:24)
7   Jet                           	0x00000001cb0b54ec jet_context_Metal::ensureCommandBuffer(bool) + 52 (jet_context_Metal.mm:1589)
8   Jet                           	0x00000001cb0b5454 jet_context_Metal::override_Metal_render_state(id<MTLCommandQueue>, id<MTLRenderCommandEncoder>, jet_framebuffer*) + 176 (jet_context_Metal.mm:696)
9   SpriteKit                     	0x00000001c02bee0c -[SKSCNRenderer renderToTexture:commandQueue:] + 220 (SKSCNRenderer.mm:313)
10  SceneKit                      	0x00000001bfd89acc -[SCNTextureSpriteKitSource metalTextureWithEngineContext:textureSampler:nextFrameTime:] + 720 (SCNSpriteKitSource.m:370)
11  SceneKit                      	0x00000001bfcc3560 kSCNTextureSourceCallbackGetMetalTexture + 64 (SCNTextureSource.m:352)
12  SceneKit                      	0x00000001bfdf1118 C3DTextureProxyGetMetalTexture + 88 (C3DTextureProxy.c:153)
13  SceneKit                      	0x00000001bfdc3b60 -[SCNMTLResourceManager(Textures) renderResourceForImageProxy:sampler:engineContext:] + 232 (SCNMTLResourceManager+Textures.mm:658)
14  SceneKit                      	0x00000001bfd2f5bc -[SCNMTLResourceManager(Textures) renderResourcesForEffectSlot:withEngineContext:] + 132 (SCNMTLResourceManager+Textures.mm:616)
15  SceneKit                      	0x00000001bfde3c24 __39+[SCNMTLRenderContext registerBindings]_block_invoke_6.540 + 84 (SCNMTLRenderContext.mm:4397)
16  SceneKit                      	0x00000001bfce85dc _execute(SCNMTLRenderContext*, DrawCommand) + 4656 (SCNMTLRenderContext.mm:3595)
17  SceneKit                      	0x00000001bfd14720 -[SCNMTLRenderContext drawRenderElement:withPass:] + 648 (SCNMTLRenderContext.mm:0)
18  SceneKit                      	0x00000001bfcf9e5c _processRendererElement(SCNMTLRenderContext*, __C3DRendererElement*, __C3DFXPassInstance*) + 840 (SCNMTLRenderContext.mm:3053)
19  SceneKit                      	0x00000001bfd30a08 -[SCNMTLRenderContext processRendererElements:count:engineIterationContext:] + 1120 (SCNMTLRenderContext.mm:2675)
20  SceneKit                      	0x00000001bfcc0fa4 C3D::DrawNodesPass::_renderEye(long) + 560 (C3DDrawNodesPass.mm:472)
21  SceneKit                      	0x00000001bfcbb3f4 C3D::DrawNodesPass::execute(C3D::RenderArgs const&) + 248 (C3DDrawNodesPass.mm:273)
22  SceneKit                      	0x00000001bfcbaac0 C3D::__renderSlice(C3D::RenderGraph*, C3D::RenderPass*, unsigned short&, C3D::RenderGraph::GraphNode const&, C3D::RenderGraph::Stage*&, C3D::RenderArgs, bool, id<MTLCommandBuffer>&) + 1860 (C3DRenderGraph.mm:769)
23  SceneKit                      	0x00000001bfcfd7fc C3D::RenderGraph::execute() + 5436 (C3DRenderGraph.mm:1354)
24  SceneKit                      	0x00000001bfcc5c30 -[SCNRenderer _renderSceneWithEngineContext:sceneTime:] + 512 (SCNRenderer.m:5217)

Would love to know if a solution was found for Hai.

On our side the problem occurs when we add too many objects with a SpriteKit texture. We suspect an issue with the max numbers of command buffers in SceneKit. But we have not found a way to modify the default max (CommandQueue on SceneView is readOnly).

Thanks Gil

Main thread is blocked with __psynch_mutexwait
 
 
Q