Search code examples
iosswiftdebuggingcrashrealm

Crash on a protocol witness related issue


In my iOS app "Progression" there is rarely a crash (1 crash in ~1000+ Sessions) I am currently not able to fix. The message is

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

This crash points me to the following method:

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
            }
        }
    }

The stack trace looks like this:

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

I have different reports for this crash and some show me different summaries. I list some of them, the stack trace always leads to my update function.

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

This update function can be triggered by the user either by pressing a button or by ending editing a textfield. I am currently not able to reproduce this crash.

I use realm as a database, I updated realm to the latest version and used different versions.

Does anyone know what causes the crash?


Solution

  • While editing my initial question to add more context as Jay proposed I think it found the issue.

    What probably happens? The view where the crash is, contains a table view. Each cell will be configured before being presented. I use a flag which holds the information, if the amount of weight for this cell (it is a strength workout app) has been initially set or is a change. When prepareForReuse is being called, this flag has not been reset. And that now means scrolling through the table view triggers a DB write for each reused cell, that leads to unnecessary writes to the db. Unnecessary, because the exact same number is already saved in the db.

    My speculation: Scrolling fast could maybe lead to a race condition (I have read something about that issue with realm) and that maybe causes this weird crash, because there are multiple single writes initiated in a short time.

    Solution: I now reset the flag on prepareForReuse to its initial value to prevent this misbehaviour.

    The crash only happens when the cell is set up and the described behaviour happens. Therefor I'm quite confident I fixed the issue finally. Let's see. -- I was not able to reproduce the issue, but it also only happens pretty rare.