realm-swift: Sequential calls to realm.write() sometimes throw an objc exception
In the context of a TestFlight beta-test, I get a significant number (a few each day) of crash reports similar to this one:
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0
Last Exception Backtrace:
0 CoreFoundation 0x2596b916 __exceptionPreprocess + 122 (NSException.m:162)
1 libobjc.A.dylib 0x25106e12 objc_exception_throw + 34 (objc-exception.mm:531)
2 Realm 0x520e68 -[RLMRealm beginWriteTransaction] + 180 (RLMRealm.mm:446)
3 RealmSwift 0x3eb150 _TFC10RealmSwift5Realm5writefzFzT_T_T_ + 44 (Realm.swift:153)
4 LapMonitor 0xe80fc _TTSf4g_n___TFC10LapMonitor16ActiveLapSessionP33_35B0DADE8A11F20A2053872E3981933117updateSessionDatafT20forDeviceSessionInfoVS_21LapMonitorSessionInfo_T_ + 972 (LapSession.swift:639)
5 LapMonitor 0xeafc8 _TTSf4d_g_n___TFC10LapMonitor16ActiveLapSession10lapMonitorfTCS_10LapMonitor20didUpdateSessionInfoVS_21LapMonitorSessionInfo_T_ + 360 (LapSession.swift:0)
6 LapMonitor 0xe13d8 _TTWC10LapMonitor16ActiveLapSessionS_24LapMonitorSessionHandlerS_FS1_10lapMonitorfTCS_10LapMonitor20didUpdateSessionInfoVS_21LapMonitorSessionInfo_T_ + 112 (LapSession.swift:0)
7 LapMonitor 0xd0c60 _TTSf4g_n___TFC10LapMonitor10LapMonitorP33_25576D73CF51C6E590B13A2BA772807319handleStatusMessagefVS0_P33_25576D73CF51C6E590B13A2BA772807323LapMonitorStatusMessageT_ + 564 (LapMonitor.swift:263)
8 LapMonitor 0xd25c0 _TTSf4d_g_d_n___TFC10LapMonitor10LapMonitor10peripheralfTCSo12CBPeripheral17didUpdateValueForCSo16CBCharacteristic5errorGSqPs5Error___T_ + 836 (LapMonitor.swift:0)
9 LapMonitor 0xcea44 _TToFC10LapMonitor10LapMonitor10peripheralfTCSo12CBPeripheral17didUpdateValueForCSo16CBCharacteristic5errorGSqPs5Error___T_ + 68 (LapMonitor.swift:0)
10 CoreBluetooth 0x2aa70cc0 -[CBPeripheral handleAttributeEvent:args:attributeSelector:delegateSelector:delegateFlag:] + 124 (CBPeripheral.m:644)
11 CoreBluetooth 0x2aa70d5c -[CBPeripheral handleCharacteristicEvent:characteristicSelector:delegateSelector:delegateFlag:] + 68 (CBPeripheral.m:666)
12 CoreBluetooth 0x2aa70e96 -[CBPeripheral handleCharacteristicValueUpdated:] + 70 (CBPeripheral.m:703)
13 CoreBluetooth 0x2aa769ee __29-[CBXpcConnection handleMsg:]_block_invoke + 58 (CBXpcConnection.m:227)
14 libdispatch.dylib 0x254d981e _dispatch_call_block_and_release + 6 (init.c:757)
15 libdispatch.dylib 0x254d980a _dispatch_client_callout + 18 (init.c:817)
16 libdispatch.dylib 0x254e7ba4 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1520 (inline_internal.h:1063)
17 CoreFoundation 0x2592db68 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 4 (CFRunLoop.c:1612)
18 CoreFoundation 0x2592c062 __CFRunLoopRun + 1570 (CFRunLoop.c:2718)
19 CoreFoundation 0x2587b224 CFRunLoopRunSpecific + 516 (CFRunLoop.c:2814)
20 CoreFoundation 0x2587b010 CFRunLoopRunInMode + 104 (CFRunLoop.c:2844)
21 GraphicsServices 0x26e6bac4 GSEventRunModal + 156 (GSEvent.c:2245)
22 UIKit 0x29f4f184 UIApplicationMain + 140 (UIApplication.m:3772)
23 LapMonitor 0x6d208 main + 132 (LapMonitorData.swift:12)
24 libdyld.dylib 0x2552386e tlv_get_addr + 42 (threadLocalHelpers.s:311)
All Realm write transaction in the app use realm.write and are called from the main thread, so it seems very unlikely that a previous write transaction was left open.
I could not so far reproduce the issue in a debug environment, so any advice about how to add instrumentation to the code so that this issue can be further investigated via crash logs is welcome.
Note that this looks very similar to #3831, that was supposed to be fixed in v1.0.2.
Any idea of what in the app could cause this ?
This issue is problematic because if my understanding is correct the objc exception thrown by -[RLMRealm beginWriteTransaction] can not be catched in Swift , so the app will inevitably crash when this occurs.
Version of Realm and Tooling
Realm framework version: RealmSwift 2.4.x, RealmSwift 2.5.1
Realm Object Server version: n/a
Xcode version: Xcode 8.2, Xcode 8.3.1
iOS versions / devices:
- iOS 9.3.5 (13G36) - iPhone4,1
- iOS 10.2.1 (14D27) - iPhone7,2
- iOS 10.3 (14E277) - iPhone7,2
- iOS 10.3.1 (14E304) - iPhone6,2 iPhone7,2 iPhone8,4
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 1
- Comments: 22 (6 by maintainers)
I had the same problem, but found a fairly simple solution that is working very well for me. Basically, check if
isInWriteTransactionand, if so, first callrealm.refresh(). I have the followingwritefunction in my DAO (data access object) base-class:which relies on the following Realm extension (where the secret sauce is the
refresh()call):I’m running into the exact same problem, with RealmSwift 2.8.3. Actions triggered from UI cause sequential (non-overlapping) realm.write { … } blocks to be executed, and without fail the second realm.write { … } block will fail with exception.
Interestingly enough, if I call realm.refresh() before starting the second realm.write { … }, then the crash goes away.