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?
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.