在协议见证相关问题上崩溃

Crash on a protocol witness related issue

在我的 iOS 应用程序“Progression”中很少发生崩溃(在 ~1000+ 会话中发生 1 次崩溃)我目前无法修复。消息是

Progression: protocol witness for TrainingSetSessionManager.update(object:weight:reps:) in conformance TrainingSetSessionDataManager + 40

这次崩溃让我想到了以下方法:

func update(object: TrainingSetSession, weight: Double?, reps: Int?) {
        try? realm.write { // <-- crashes
            if let weight = weight {
                object.amountOfWeight = weight
            }
            if let reps = reps {
                object.numberOfReps = reps
            }
        }
    }

堆栈跟踪如下所示:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x000000010c622340
VM Region Info: 0x10c622340 is not in any region.  Bytes after previous region: 49423169  Bytes before following region: 58580160
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      mapped file              108e44000-109700000 [ 8944K] r--/r-- SM=ALI  ...t_id=259b6c25
--->  GAP OF 0x6700000 BYTES
      MALLOC_TINY              10fe00000-10ff00000 [ 1024K] rw-/rwx SM=PRV  

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [2042]
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   Progression                     0x0000000104bf0a30 0x104984000 + 2542128
1   Progression                     0x0000000104c5eab0 0x104984000 + 2992816
2   Progression                     0x0000000104c5da90 0x104984000 + 2988688
3   Progression                     0x0000000104c5e188 0x104984000 + 2990472
4   Progression                     0x0000000104c91428 0x104984000 + 3200040
5   Progression                     0x0000000104caee14 0x104984000 + 3321364
6   Progression                     0x0000000104cad5c8 0x104984000 + 3315144
7   Progression                     0x0000000104cec258 0x104984000 + 3572312
8   Progression                     0x0000000104b5605c 0x104984000 + 1908828
9   Progression                     0x0000000104b5a6b0 0x104984000 + 1926832
10  Progression                     0x0000000104a1f234 0x104984000 + 635444
11  Progression                     0x0000000104aab410 0x104984000 + 1209360
12  Progression                     0x0000000104a1f6ac 0x104984000 + 636588
13  libswiftFoundation.dylib        0x00000001a3985b3c NSFastEnumerationIterator.next() + 196 (NSFastEnumeration.swift:46)
14  Progression                     0x0000000104afd344 0x104984000 + 1545028
15  libswiftCore.dylib              0x00000001a3ac7d0c Sequence._copyContents(initializing:) + 516 (Sequence.swift:1110)
16  libswiftCore.dylib              0x00000001a3ae0120 _copyCollectionToContiguousArray<A>(_:) + 604 (ContiguousArrayBuffer.swift:725)
17  Progression                     0x0000000104b006e4 0x104984000 + 1558244
18  libswiftCore.dylib              0x00000001a3ad7a00 Array.init<A>(_:) + 44 (Array.swift:849)
19  Progression                     0x0000000104f7fe28 0x104984000 + 6274600
20  Progression                     0x0000000104f830c8 0x104984000 + 6287560
21  Progression                     0x0000000104e79fac 0x104984000 + 5201836
22  Progression                     0x0000000104e7a18c 0x104984000 + 5202316
23  Progression                     0x0000000104ea21e8 0x104984000 + 5366248
24  Progression                     0x0000000104e61798 0x104984000 + 5101464
25  Progression                     0x0000000104e61878 0x104984000 + 5101688
26  Progression                     0x0000000104e3cb78 0x104984000 + 4950904
27  Progression                     0x0000000104e3c5ec 0x104984000 + 4949484
28  Progression                     0x0000000104e85f00 0x104984000 + 5250816
29  Progression                     0x0000000104f7fc74 0x104984000 + 6274164
30  Progression                     0x0000000104b00ce8 0x104984000 + 1559784
31  Progression                     0x0000000104b028b8 0x104984000 + 1566904
32  Progression                     0x0000000104ae0c94 0x104984000 + 1428628
33  Progression                     0x0000000104ae0d8c 0x104984000 + 1428876
34  Progression                     0x0000000104a23428 0x104984000 + 652328
35  Progression                     0x0000000104a2323c 0x104984000 + 651836
36  Progression                     0x0000000104b1bd6c 0x104984000 + 1670508
37  Progression                     0x0000000104b1c804 0x104984000 + 1673220
38  Progression                     0x0000000104b2e1c8 0x104984000 + 1745352
39  Progression                     0x0000000104b25cb0 0x104984000 + 1711280
40  Progression                     0x0000000104b6d344 0x104984000 + 2003780
41  Progression                     0x0000000104aa2658 0x104984000 + 1173080
42  Progression                     0x0000000104afab58 0x104984000 + 1534808
43  Progression                     0x0000000104999c68 TrainingSetSessionDataManager.update(object:weight:reps:) + 40 (TrainingSetSessionDataManager.swift:53)
44  Progression                     0x0000000104999c68 protocol witness for TrainingSetSessionManager.update(object:weight:reps:) in conformance TrainingSetSessionDataManager + 40 (<compiler-generated>:52)
45  Progression                     0x0000000104999c68 TrainingSetCell.amountOfWeight.setter + 732 (TrainingSetCell.swift:116)
46  Progression                     0x000000010499b368 TrainingSetCell.setCell() + 1060 (TrainingSetCell.swift:248)
47  Progression                     0x00000001049d9064 TrainingSetCell.viewModel.didset + 8 (TrainingSetCell.swift:61)
48  Progression                     0x00000001049d9064 TrainingSetCell.viewModel.setter + 8 (TrainingSetCell.swift:0)
49  Progression                     0x00000001049d9064 TrainingSessionViewController.tableView(_:cellForRowAt:) + 236 (TrainingSessionViewController.swift:285)
50  Progression                     0x00000001049d9290 @objc TrainingSessionViewController.tableView(_:cellForRowAt:) + 140 (<compiler-generated>:0)
51  UIKitCore                       0x00000001a2ae8120 -[_UIFilteredDataSource tableView:cellForRowAtIndexPath:] + 104 (_UIFilteredDataSource.m:87)
52  UIKitCore                       0x00000001a2ab3168 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 644 (UITableView.m:15012)
53  UIKitCore                       0x00000001a2a7ef00 -[UITableView _updateVisibleCellsNow:] + 2476 (UITableView.m:2953)
54  UIKitCore                       0x00000001a2a9d310 -[UITableView layoutSubviews] + 368 (UITableView.m:9632)
55  UIKitCore                       0x00000001a2dd1f84 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2504 (UIView.m:17526)
56  QuartzCore                      0x00000001a32ec7b4 -[CALayer layoutSublayers] + 308 (CALayer.mm:10147)
57  QuartzCore                      0x00000001a32ecc88 CA::Layer::layout_if_needed(CA::Transaction*) + 524 (CALayer.mm:10014)
58  QuartzCore                      0x00000001a330147c CA::Layer::layout_and_display_if_needed(CA::Transaction*) + 144 (CALayer.mm:2485)
59  QuartzCore                      0x00000001a3246a6c CA::Context::commit_transaction(CA::Transaction*, double, double*) + 416 (CAContextInternal.mm:2449)
60  QuartzCore                      0x00000001a3271f34 CA::Transaction::commit() + 732 (CATransactionInternal.mm:449)
61  QuartzCore                      0x00000001a32732c4 CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 96 (CATransactionInternal.mm:932)
62  CoreFoundation                  0x000000019fe4c358 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36 (CFRunLoop.c:1799)
63  CoreFoundation                  0x000000019fe465c4 __CFRunLoopDoObservers + 576 (CFRunLoop.c:1912)
64  CoreFoundation                  0x000000019fe46b74 __CFRunLoopRun + 1056 (CFRunLoop.c:2953)
65  CoreFoundation                  0x000000019fe4621c CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
66  GraphicsServices                0x00000001b794a784 GSEventRunModal + 164 (GSEvent.c:2259)
67  UIKitCore                       0x00000001a2884fe0 -[UIApplication _run] + 1072 (UIApplication.m:3253)
68  UIKitCore                       0x00000001a288a854 UIApplicationMain + 168 (UIApplication.m:4707)
69  Progression                     0x000000010498ae50 main + 68 (AppDelegate.swift:14)
70  libdyld.dylib                   0x000000019fb066b0 start + 4

Thread 1:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 2 name:
Thread 2:
0   libsystem_kernel.dylib          0x00000001cdc242d0 mach_msg_trap + 8
1   libsystem_kernel.dylib          0x00000001cdc23660 mach_msg + 76 (mach_msg.c:103)
2   CoreFoundation                  0x000000019fe4cc30 __CFRunLoopServiceMachPort + 380 (CFRunLoop.c:2641)
3   CoreFoundation                  0x000000019fe46c14 __CFRunLoopRun + 1216 (CFRunLoop.c:2974)
4   CoreFoundation                  0x000000019fe4621c CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
5   Foundation                      0x00000001a10f5df0 -[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 232 (NSRunLoop.m:374)
6   Foundation                      0x00000001a10f5cbc -[NSRunLoop(NSRunLoop) runUntilDate:] + 92 (NSRunLoop.m:421)
7   UIKitCore                       0x00000001a2938d48 -[UIEventFetcher threadMain] + 516 (UIEventFetcher.m:838)
8   Foundation                      0x00000001a1267a34 __NSThread__start__ + 864 (NSThread.m:724)
9   libsystem_pthread.dylib         0x00000001eb6a1b40 _pthread_start + 320 (pthread.c:881)
10  libsystem_pthread.dylib         0x00000001eb6aa768 thread_start + 8

Thread 3 name:
Thread 3:
0   libsystem_kernel.dylib          0x00000001cdc4a230 kevent + 8
1   Progression                     0x0000000104b11c14 0x104984000 + 1629204
2   Progression                     0x0000000104b125e8 0x104984000 + 1631720
3   libsystem_pthread.dylib         0x00000001eb6a1b40 _pthread_start + 320 (pthread.c:881)
4   libsystem_pthread.dylib         0x00000001eb6aa768 thread_start + 8

Thread 4 name:
Thread 4:
0   libsystem_kernel.dylib          0x00000001cdc242d0 mach_msg_trap + 8
1   libsystem_kernel.dylib          0x00000001cdc23660 mach_msg + 76 (mach_msg.c:103)
2   CoreFoundation                  0x000000019fe4cc30 __CFRunLoopServiceMachPort + 380 (CFRunLoop.c:2641)
3   CoreFoundation                  0x000000019fe46c14 __CFRunLoopRun + 1216 (CFRunLoop.c:2974)
4   CoreFoundation                  0x000000019fe4621c CFRunLoopRunSpecific + 600 (CFRunLoop.c:3242)
5   AudioSession                    0x00000001a79000c4 GenericRunLoopThread::Entry(void*) + 164 (GenericRunLoopThread.h:91)
6   AudioSession                    0x00000001a790225c CAPThread::Entry(CAPThread*) + 92 (CAPThread.cpp:321)
7   libsystem_pthread.dylib         0x00000001eb6a1b40 _pthread_start + 320 (pthread.c:881)
8   libsystem_pthread.dylib         0x00000001eb6aa768 thread_start + 8

Thread 5:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 6:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 7:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 8:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 9:
0   libsystem_pthread.dylib         0x00000001eb6aa754 start_wqthread + 0

Thread 0 crashed with ARM Thread State (64-bit):
    x0: 0x00000002824cb110   x1: 0x00000000009b4604   x2: 0x0000000000000000   x3: 0x0000000000000000
    x4: 0x0000000283ee4c48   x5: 0x0000000000000010   x6: 0x0000000000000049   x7: 0x000000020298de50
    x8: 0x000000010787f320   x9: 0x0000000000000000  x10: 0x0000000000000005  x11: 0x0000000074200000
   x12: 0x0000000000000038  x13: 0x0000000000000001  x14: 0x0000000000000036  x15: 0x0000000000000010
   x16: 0x00000001afc27fe0  x17: 0x00000001ffad5380  x18: 0x000000011b53e89c  x19: 0x00000002824cb1e0
   x20: 0x00000002824cb100  x21: 0x00000002824cb1e0  x22: 0x0000000110032400  x23: 0x000000016b476040
   x24: 0x0000000283ee4c48  x25: 0x000000016b4769e0  x26: 0x000000016b4768f0  x27: 0x000000020298e150
   x28: 0x00000001051c10d0   fp: 0x000000016b475e70   lr: 0x0000000104c5eab0
    sp: 0x000000016b475e70   pc: 0x0000000104bf0a30 cpsr: 0x60000000
   esr: 0x92000006 (Data Abort) byte read Translation fault

我收到了关于这次崩溃的不同报告,有些报告显示了不同的摘要。我列出了其中的一些,堆栈跟踪总是导致我的更新功能。

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000009cc6ab0e28 -> 0x0000001cc6ab0e28 (possible pointer authentication failure)
VM Region Info: 0x1cc6ab0e28 is in 0x1000000000-0x7000000000;  bytes after start: 54872706600  bytes before end: 357444153815
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      commpage (reserved)      fc0000000-1000000000 [  1.0G] ---/--- SM=NUL  ...(unallocated)
--->  GPU Carveout (reserved) 1000000000-7000000000 [384.0G] ---/--- SM=NUL  ...(unallocated)
      UNUSED SPACE AT END

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [13261]
Triggered by Thread:  0
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000c02836f4068 -> 0x00000002836f4068 (possible pointer authentication failure)
VM Region Info: 0x2836f4068 is in 0x280000000-0x2a0000000;  bytes after start: 57622632  bytes before end: 479248279
      REGION TYPE                 START - END      [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      unused shlib __TEXT      1fe08a000-1fe93c000 [ 8904K] r--/r-- SM=COW  ... this process
      GAP OF 0x816c4000 BYTES
--->  MALLOC_NANO              280000000-2a0000000 [512.0M] rw-/rwx SM=PRV  
      GAP OF 0xd20000000 BYTES
      commpage (reserved)      fc0000000-1000000000 [  1.0G] ---/--- SM=NUL  ...(unallocated)

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [63749]
Triggered by Thread:  0
Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Triggered by Thread:  0

用户可以通过按下按钮或结束编辑文本字段来触发此更新功能。我目前无法重现此崩溃。

我使用realm作为数据库,我将realm更新到最新版本,并使用了不同的版本。

有谁知道导致崩溃的原因吗?

在编辑我最初的问题以添加 Jay 提议的更多上下文时,我认为它找到了问题。

可能会发生什么? 崩溃所在的视图包含 table 视图。每个单元格将在呈现之前进行配置。如果这个单元格(它是一个力量锻炼应用程序)的重量已经初始设置或正在更改,我会使用一个保存信息的标志。调用 prepareForReuse 时,此标志尚未重置。这现在意味着滚动 table 视图会为每个重复使用的单元触发数据库写入,这会导致对数据库进行不必要的写入。不需要,因为完全相同的数字已经保存在数据库中。

我的猜测:快速滚动可能会导致竞争条件(我已经阅读了一些关于领域的问题)并且这可能会导致这种奇怪的崩溃,因为有多个短时间内启动单次写入。

解决方法: 我现在将 prepareForReuse 上的标志重置为其初始值以防止这种不当行为。

只有在设置单元格并发生所描述的行为时才会发生崩溃。因此,我非常有信心最终解决了这个问题。让我们来看看。 -- 我无法重现该问题,但这种情况也很少见。