应用挂起__psynch_mutexwait

Cas*_*ato 11 multithreading mutex core-data freeze ios

我们的应用似乎是半随机挂在psynch_mutexwait.它似乎与更新存储在CoreData中的大量数据的后台进程有关 - 但我完全无法弄清楚是谁锁定导致死锁的原因.

以下是lldb给我的完整堆栈跟踪 - 这显然是不完整的,并且线程1的最后一帧是伪造的.在那之前,我在该方法中有一个断点,它从未被击中过.

是否有任何方法可以确定正在等待什么锁?(或者甚至获得正确的堆栈跟踪?)当然,涉及很多代码,这使得随机NSLog语句成为一项艰巨的任务.

(lldb) bt all
* thread #1: tid = 0x2503, 0x39da20fc libsystem_kernel.dylib`__psynch_mutexwait + 24, stop reason = signal SIGSTOP
    frame #0: 0x39da20fc libsystem_kernel.dylib`__psynch_mutexwait + 24
    frame #1: 0x39ceb128 libsystem_c.dylib`pthread_mutex_lock + 392
    frame #2: 0x00022068 OnDeck`-[AttendanceWorkoutsController buildTable](self=0x00000003, _cmd=0x00000000) + 508 at AttendanceWorkoutsController.m:100

  thread #2: tid = 0x2803, 0x39d92648 libsystem_kernel.dylib`kevent64 + 24
    frame #0: 0x39d92648 libsystem_kernel.dylib`kevent64 + 24
    frame #1: 0x39ccb4f0 libdispatch.dylib`_dispatch_mgr_invoke + 796

  thread #5: tid = 0x2b03, 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20
    frame #0: 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20
    frame #1: 0x39d9204c libsystem_kernel.dylib`mach_msg + 40

  thread #6: tid = 0x242f, 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20
    frame #0: 0x39d91eb4 libsystem_kernel.dylib`mach_msg_trap + 20
    frame #1: 0x39d9204c libsystem_kernel.dylib`mach_msg + 40

  thread #7: tid = 0x2c03, 0x39da2594 libsystem_kernel.dylib`select$DARWIN_EXTSN + 20
    frame #0: 0x39da2594 libsystem_kernel.dylib`select$DARWIN_EXTSN + 20
    frame #1: 0x31bff1f6 CoreFoundation`__CFSocketManager + 678

  thread #8: tid = 0x2d03, 0x39da2d98 libsystem_kernel.dylib`__workq_kernreturn + 8
    frame #0: 0x39da2d98 libsystem_kernel.dylib`__workq_kernreturn + 8
    frame #1: 0x39cf0cfa libsystem_c.dylib`_pthread_workq_return + 18
(lldb) 
Run Code Online (Sandbox Code Playgroud)

Cas*_*ato 13

通过让几个人查看代码,并追踪冗长复杂的代码路径,我们发现似乎是罪魁祸首.在后台线程中运行的一种方法是查找并使用一些Core Data对象并使用主线程上下文.

如果IOS能提供有用的堆栈跟踪,肯定会帮助很多.

  • 尝试启用核心数据多线程触发器断言.它是为这些情况而引入的. (2认同)

Ola*_*laf 2

当另一个上下文中(和另一个线程上)的相关实体已被修改但尚未持久化时,就会出现这种情况。

场景:

A --> B

由于错误B,在另一个上下文中的另一个线程上有待处理的更改。该错误导致B其挂起,而不是保存或回滚。尝试在当前上下文/线程中保存A将导致等待其他线程释放 上的锁B

解决问题的唯一成功方法是列出所有待处理实体并与阻塞线程中的实体进行比较。花了一段时间:(

我仍在寻找列出数据库和实体上所有锁的东西。