realm-swift
realm-swift copied to clipboard
Crash in RLMObservationInfo::didChange(NSString*, NSKeyValueChange, NSIndexSet*) const (RLMObservation.hpp:116)
Hi!
I'm currently experiencing the following crash when trying to KVO observe objects invalidated property in my Realm. All the registering for the observations is done on the main thread. Any idea what could be wrong?
The crash specifically seems to occur when calling RLMRealm.defaultRealm().refresh() on the main thread and only in Release builds. Debug is running fine!
Thread : Crashed: com.apple.main-thread
0 MyApp 0x0000000100718fc4 RLMObservationInfo::didChange(NSString*, NSKeyValueChange, NSIndexSet*) const (RLMObservation.hpp:116)
1 MyApp 0x000000010071adb8 (anonymous namespace)::TransactLogHandler::notifyObservers() (RLMObservation.mm:473)
2 MyApp 0x0000000100719e6c RLMAdvanceRead(realm::SharedGroup&, realm::History&, RLMSchema*) (RLMObservation.mm:503)
3 MyApp 0x0000000100743d74 -[RLMRealm handleExternalCommit] (RLMRealm.mm:738)
4 MyApp 0x00000001007488f0 -[RLMNotifier listen]::$_1::__invoke(void*) (RLMRealmUtil.mm:249)
5 CoreFoundation 0x0000000182753f8c __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
6 CoreFoundation 0x0000000182753230 __CFRunLoopDoSources0 + 264
7 CoreFoundation 0x00000001827512e0 __CFRunLoopRun + 712
8 CoreFoundation 0x000000018267cf74 CFRunLoopRunSpecific + 396
9 GraphicsServices 0x000000018c0d76fc GSEventRunModal + 168
10 UIKit 0x000000018727ed94 UIApplicationMain + 1488
11 MyApp 0x000000010014a398 main (main.m:33)
12 libdyld.dylib 0x0000000194b1aa08 start + 4
Sorry you've hit this! It's the first we hear of it.
I'll try reproducing this issue based on the information you've given us, but if you could send us a repro case along with steps to reproduce at [email protected], that would certainly accelerate the process.
I'll try to come up with a sample project, but can't promise you anything. One more piece of information I was able to find out: I suppose this crash is just accuring on iOS 9? I really can't wrap my head around it, is it maybe some code stripping problem or has to do with the new bitcode feature introduced (although I have that turned of for my application in both Debug and Release)
Okay I investigated this issue a little further today, it is also reproducible in iOS 8 (nonetheless, it seems to be occuring a little more often on iOS 9 but that really could be subjective). Unfortunately, I couldn't quite reproduce it easily in a sample project :/
Might it be an issue that I'm trying to subscribe the invalidated property using ReactiveCocoa?
No, that should definitely work fine.
Subscribing via ReactiveCocoa shouldn't be making a difference here. Thanks for looking into creating a repro case for us. Keep us posted!
Were you able to find anything out regarding this issue?
I haven't been able to come up with a repro case, and the stack trace only really makes sense if something went wrong before the point where it actually crashes.
Are you observing invalidated over a multi-level keypath (and if so, are all of the things in the keypath realm objects?), or observing other properties on the same objects (and if so, might they be changing as well in the cases that lead to crashes?).
Maybe it'll help if I shed some more light on what I'm up to :)
I currently have the problem, that some of the objects I display in a table view are getting deleted at some point and the table view not being reloaded fast enough. This then sometimes leads to crashes due to objects being "deleted or invalidated". Therefore I planned on observing the "invalidated" property to automatically reload the table and stop all other interaction with the objects until the dataset has been reloaded and is "save" again to access. Here's the code I use to do that
// Observe all the RLMObjects on their invalidation status
for var i = 0; i < self.snipViewModel.numberOfItems(); i++ {
if let realmObject = self.viewModel.itemAtIndex(i) as? RLMObject where !realmObject.invalidated {
self.invalidatedDisposables.append(realmObject.rac_valuesForKeyPath("invalidated", observer: nil).subscribeNext({ [weak self] (x) -> Void in
if let invalidatedStatus = x as? Bool where invalidatedStatus == true {
self?.reloadData()
self?.reloadTable()
}
}))
}
}
I store the disposables generated by ReactiveCocoa in an array to later get rid of them (e.g. when the table view is no longer displayed) so I don't get the updates anymore.
Would any of you guys have another idea how I could solve my initial problem? I'm really desperate to find a solution for all of this ... :/
Adding a notification block to the Realm which calls self.reloadData() should solve the same problem (unless you're doing write transactions on the main thread), but would have the downside of reloading for a lot of changes that don't need it.
Yeah thats the problem, I guess that would be a little too much reloading overhead I would have with that approach :(
@tspecht were you ever able to create a repro case for us to verify and troubleshoot? The invalidated key should be KVO-compliant.
Closing due to lack of information to reproduce. Will reopen if we can obtain a repro case.
I've got same crash.. It's really hard to replicate.. We've got ~200 crashes for last week with 163.6k daily users.. I can provide stacktrace if it helps, but it looks very similar to trace from above..
@alexgarbarev could you please file a new issue with as much information as possible that could help us identify when this happens? It will be difficult to impossible for us to make progress on it until we can reproduce it ourselves thouhg.
Ok, thanks @jpsim. Finally I've replicated that crash and did special github repo with demo: https://github.com/alexgarbarev/RealmKVOCrash/ It's pretty easy to replicate - you should delete object, while it observed by KVO. Should I still create a new issue? I think it's pretty much the same problem - same stacktrace.
Thanks for the repro case. It's a fairly straightforward issue of that removing the last observer from within an observation results in the object that tracks the observer information being deleted while we're still using it.
Thanks @tgoyne. I've tried master branch in my demo repository from above. Yep, that crash was fixed, but I was able to replicate another one. (see the screenshot)

It looks like sometimes object deleted while another KVO notification isn't complete yet, so KVC call in change dictionary composing fails with exception:
*** Terminating app due to uncaught exception 'RLMException', reason: 'Object has been deleted or invalidated.'
*** First throw call stack:
(
0 CoreFoundation 0x000000010e2d2d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010dd46deb objc_exception_throw + 48
2 RealmCrash 0x000000010d0a70e3 _ZL17RLMVerifyAttachedP13RLMObjectBase + 83
3 RealmCrash 0x000000010d0aeb29 _ZL3getIN5realm10StringDataEET_P13RLMObjectBasem + 25
4 RealmCrash 0x000000010d0a5a8d _ZL12RLMGetStringP13RLMObjectBasem + 29
5 RealmCrash 0x000000010d0a6e67 ___ZL17RLMAccessorGetterP11RLMProperty15RLMAccessorCode_block_invoke_9 + 39
6 Foundation 0x000000010d8fa167 -[NSObject(NSKeyValueCoding) valueForKey:] + 280
7 RealmCrash 0x000000010d101f56 _ZZN18RLMObservationInfo11valueForKeyEP8NSStringENK3$_4clEv + 150
8 RealmCrash 0x000000010d101ca5 _ZN18RLMObservationInfo11valueForKeyEP8NSString + 1893
9 RealmCrash 0x000000010d0edbd5 -[RLMObjectBase valueForKey:] + 85
10 Foundation 0x000000010d8d8b0b NSKeyValueDidChangeBySetting + 65
11 Foundation 0x000000010d8d7e94 NSKeyValueDidChange + 301
12 Foundation 0x000000010d8dc70d -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 118
13 RealmCrash 0x000000010d105967 _ZZNK18RLMObservationInfo9didChangeEP8NSString16NSKeyValueChangeP10NSIndexSetENK3$_3clIU8__strongP11objc_objectEEDaT_ + 39
14 RealmCrash 0x000000010d100f3e _ZNK18RLMObservationInfo7forEachIZNKS_9didChangeEP8NSString16NSKeyValueChangeP10NSIndexSetE3$_3EEvOT_ + 222
15 RealmCrash 0x000000010d100c8e _ZNK18RLMObservationInfo9didChangeEP8NSString16NSKeyValueChangeP10NSIndexSet + 222
16 RealmCrash 0x000000010d109d59 _ZZ12RLMDidChangeRKNSt3__16vectorIN5realm14BindingContext13ObserverStateENS_9allocatorIS3_EEEERKNS0_IPvNS4_IS9_EEEEENK3$_7clINS2_10ColumnInfoEEEDamRKT_P18RLMObservationInfo + 169
17 RealmCrash 0x000000010d10539e _ZN12_GLOBAL__N_17forEachIZ12RLMDidChangeRKNSt3__16vectorIN5realm14BindingContext13ObserverStateENS1_9allocatorIS5_EEEERKNS2_IPvNS6_ISB_EEEEE3$_7EEvRKS5_OT_ + 190
18 RealmCrash 0x000000010d104edd _Z12RLMDidChangeRKNSt3__16vectorIN5realm14BindingContext13ObserverStateENS_9allocatorIS3_EEEERKNS0_IPvNS4_IS9_EEEE + 605
19 RealmCrash 0x000000010d225452 _ZN12_GLOBAL__N_121RLMNotificationHelper10did_changeERKNSt3__16vectorIN5realm14BindingContext13ObserverStateENS1_9allocatorIS5_EEEERKNS2_IPvNS6_ISB_EEEE + 50
20 RealmCrash 0x000000010d265f42 _ZN12_GLOBAL__N_119TransactLogObserverC2IZN5realm5_impl11transaction7advanceERNS2_11SharedGroupEPNS2_14BindingContextENS2_10SchemaModeENS5_9VersionIDEE3$_0EES8_S6_OT_NS2_4util8OptionalIS9_EE + 1554
21 RealmCrash 0x000000010d26523d _ZN12_GLOBAL__N_119TransactLogObserverC1IZN5realm5_impl11transaction7advanceERNS2_11SharedGroupEPNS2_14BindingContextENS2_10SchemaModeENS5_9VersionIDEE3$_0EES8_S6_OT_NS2_4util8OptionalIS9_EE + 45
22 RealmCrash 0x000000010d2651fa _ZN5realm5_impl11transaction7advanceERNS_11SharedGroupEPNS_14BindingContextENS_10SchemaModeENS2_9VersionIDE + 138
23 RealmCrash 0x000000010d070bfc _ZN5realm5_impl16RealmCoordinator16advance_to_readyERNS_5RealmE + 1004
24 RealmCrash 0x000000010d2511a7 _ZN5realm5Realm6notifyEv + 359
25 RealmCrash 0x000000010d29623f _ZZN5realm5_impl17WeakRealmNotifierC1ERKNSt3__110shared_ptrINS_5RealmEEEbENK3$_0clEPv + 79
26 RealmCrash 0x000000010d2961e8 _ZZN5realm5_impl17WeakRealmNotifierC1ERKNSt3__110shared_ptrINS_5RealmEEEbEN3$_08__invokeEPv + 24
27 CoreFoundation 0x000000010e1f8301 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
28 CoreFoundation 0x000000010e1ee22c __CFRunLoopDoSources0 + 556
29 CoreFoundation 0x000000010e1ed6e3 __CFRunLoopRun + 867
30 CoreFoundation 0x000000010e1ed0f8 CFRunLoopRunSpecific + 488
31 GraphicsServices 0x0000000111aacad2 GSEventRunModal + 161
32 UIKit 0x000000010e688f09 UIApplicationMain + 171
33 RealmCrash 0x000000010cfbedbf main + 111
34 libdyld.dylib 0x000000010fd5c92d start + 1
35 ??? 0x0000000000000001 0x0 + 1
)
You can replicate that crash in the demo from above (I've updated realm and pushed updates). It happens time to time, but you'll face with that at least once per 3-4 runs
Nice catch @alexgarbarev, let's reopen this.
@tgoyne @jpsim UPD: this night spent not for nothing. Demo repo from above updated. Now it crashes in 100% runs for me. My observation is:
- it crashes when main runloop paused (it happens during UITableView deceleration animation for example) and we update and delete same object. It looks like KVO-handling on main thread runs on invalidated object then (after main runloop resumed).
Please let me know if I can help with something.
Is anyone actively working on this? We have a crash that seems to be related to this. What can I do to help get this figured out?
No one is actively working on this AFAICT. You could debug the repro case shared above in order to determine what could fix it.