realm-swift: Crash for some users Realm 5.3.3 - realm::util::terminate(char const*, char const*, long) + 10
Goals
The app is loading data on a background thread from one local db to realm. I have it batching in units of 250 and looping in a function with autoreleasepool wrapped around it to try to keep the memory pressure down since I thought that was the issue first. Nothing seems to work.
Expected Results
Not to crash.
Actual Results
Crashed: com.apple.root.background-qos SIGABRT ABORT 0x00000001b89c4df0
0 libsystem_kernel.dylib pthread_kill + 8 2 libsystem_c.dylib abort + 104 3 Realm realm::util::terminate(char const, char const, long) + 10 4 Realm realm::util::terminate_internal(std::1::basic_stringstream<char, std::1::char_traits<char>, std::1::allocator<char> >&) + 780 5 Realm realm::util::terminate(char const, char const, long, std::initializer_listrealm::util::Printable&&) + 328 6 Realm realm::Cluster::init(realm::MemRef) + 156 7 Realm realm::ClusterNodeInner::try_get(realm::ObjKey, realm::ClusterNode::State&) const + 204 8 Realm realm::ClusterTree::is_valid(realm::ObjKey) const + 36 9 Realm realm::ConstObj::is_valid() const + 108 10 Realm RLMObject_Private.hpp - Line 41 RLMVerifyInWriteTransaction(RLMObjectBase) + 41 11 Realm RLMAccessor.mm - Line 78 invocation function for block in objc_object (anonymous namespace)::makeSetter<bool, bool>(RLMProperty*) + 78 12 App Sync.swift - Line 730 Sync.createRealmObjectFromObject(object:container:queryRealm:) + 730 13 App Sync.swift - Line 225 closure #1 in closure #3 in Sync.updateRealmObjects(š + 225 14 App <compiler-generated> - Line 4335423344 partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) + 4335423344 15 App thunk for @callee_guaranteed () -> (@error @owned Error)partial apply + 4335500284 16 RealmSwift Realm.swift - Line 227 Realm.write(withoutNotifying:š + 227 17 App Sync.swift - Line 1958 closure #3 in Sync.updateRealmObjects(š + 1958 18 App <compiler-generated> - Line 4335423344 partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) + 4335423344 19 App thunk for @callee_guaranteed () -> (@error @owned Error)partial apply + 4335500264 20 libswiftObjectiveC.dylib $s10ObjectiveC15autoreleasepool8invokingxxyKXE_tKlF + 64 21 App Sync.swift - Line 205 Sync.updateRealmObjects(š + 205 22 App Sync.swift - Line 82 closure #1 in Sync.requestForAccess(_š + 82 23 App <compiler-generated> - Line 4333817056 thunk for @escaping @callee_guaranteed () -> () + 4333817056 24 libdispatch.dylib <redacted> + 32 29 libsystem_pthread.dylib start_wqthread + 8
Steps for others to Reproduce
I cannot reproduce this error locally on any devices. I tried with large data sets on an iPhone 6s, iPhone XS Max, iPad Pro, iPhone 11. Yet I see it in the field. Iāve tried to break out the offending function which is mutating the object into sub functions to get a better stacktace, but that doesnāt help. It is crashing on this createRealmObjectFromObject function.
Code Sample
func updateRealmObjects(){
DispatchQueue(label: "background").async {
autoreleasepool {
let writeRealm = try! Realm()
do {
let objects = getSomeObjectArray()
var escape = false
parentLoop: while objects!.count != 0 || escape {
try autoreleasepool {
try writeRealm.safeWrite {
loop: while index <objectsCount {
if (objects?.count ?? 0) > 0 {
writeRealm.create(Object.self, value: self.createRealmObjectFromObject(object: objects![0], container: container, queryRealm: writeRealm), update: .modified)
} else {
print("THIS SHOULD NEVER HAPPEN.)
escape = true
break loop;
}
index += 1
objects!.remove(at: 0)
if index%250 == 0{
index -= 250
objectCount -= 250
break loop;
}
}
}
}
}
}
} catch {
print(error)
}
}
}
func createRealmObjectFromObject(object: LocalObjectType, container: String, queryRealm: Realm) -> RealmObject {
let syncObject = queryRealm.object(ofType: RealmObject.self, forPrimaryKey: object.identifier) ?? RealmObject()
syncObject.property0 = object.property0
syncObject.property1 = object.property1
... etc
return syncObject
}
(excuse the formatting/ hacky style here. Just was throwing stuff at the wall to fix production code that didnāt fail in our testing )
Version of Realm and Tooling
Realm (5.3.3):
-
Realm/Headers (= 5.3.3)
-
Realm/Headers (5.3.3)
-
RealmSwift (5.3.3):
- Realm (= 5.3.3) Realm framework version: ?
Realm Object Server version: N/A
Xcode version: Version 11.6 (11E708)
iOS/OSX version: 13.6.0 (17G68) - iPhone 11 Pro 13.4.1 (17E262) - iPhone 7 Plus 13.6.1 (17G80) - iPhone 11 Pro Max 13.6.0 (17G68) - iPhone X
Dependency manager + version: irrelevant. Cocoapods.
Updates from users and crash reports
It looks like wrapping the code in autorelease, ensuring serialized background threads, etc have shifted the problem. Now it is crashing, but for less users. To reproduce the issue nowā it works on launch the first time. The user kills the app. Relaunches it and the second time it crashes. From the updated crash reports for the latest version we are seeing the crash on the outer function where it tries to add what looks to be an invalidated object? to Realm⦠That only happens after the app is killed and restarted⦠At this point it feels like wack-a-mole:
RLMObjectBase.mm - Line 293 -[RLMObjectBase isInvalidated] + 293
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 2
- Comments: 19 (6 by maintainers)
@gongzhang unfortunately I donāt have one. However weāve noticed that if user is āfortunedā to get this crash, then it will always crash for that user. So, we mark it and on the next launch completely delete Realm database. We can do it since itās possible for us to sync all data once again from backend. Not a solution, but workaround that increases our crash-free.
@leemaguire actually this has become almost unusable on 5.3.5. Duplicate objects are being created. Linked Lists on the parent object are not reliably being added š¬ Not to mention itās extremely slow now⦠UI Updates are being called on the main thread after write transactions complete on the background thread (which is awkward when you are batching data and things jump around visually during a sync).
Any chance for a migration tool to go back to the land of 4.x? We can also schedule a screen-share session and get to the bottom of it and hopefully help yaāll out.