Crash found in two different cases, but which is not consistently reproducing.
Background
We are trying to query from Couchbade DB using backgroundTellDatabaseNamed API. As per the documentation
“As a convenience, CBLManager’s backgroundTellDatabaseNamed:to: method will run a block on an existing background thread (the same one the replicator runs on). You must be careful to avoid using any of the calling thread’s objects in the block, since the block runs on a different thread. Instead, you should use the CBLDatabase object passed to the block and derive other objects like documents from it.”
So we are using the database object given in the backgroundTellDatabaseNamed block and performing the createQuery operation on the same object.
Sample Code
public func fetchAllOpenNotifications(callback: @escaping (_ documents: [OpenNotification]?) → Void) {
self.database.manager.backgroundTellDatabaseNamed(database.name) { database in
guard let query = database.existingViewNamed(viewName)?.createQuery() else {
callback(nil)
return
}
query.prefetch = true
query.runAsync({ (enumeratorResult, error) in
let documents = enumeratorResult.compactMap({ ($0 as? CBLQueryRow)?.document })
var openNotifications = OpenNotification
for document in documents {
openNotifications.append(OpenNotification(latitude: document.latitudeLongitude.0,
longitude: document.latitudeLongitude.1,
documentID: document.documentID, // Stack trace was pointing to this line on first crash
notificationNumber: document.notificationNumber))
}
callback(openNotifications)
})
}
}
We are observing the below-given crashes here.
Crash 1.
-[CBLSavedRevision documentID]: unrecognized selector sent to instance 0x2885a3840
CoreFoundation
0x209209ea4 0x2090ed000 + 1167012
libobjc.A.dylib
0x2083d9a50 0x2083d3000 + 27216
CoreFoundation
0x209122b14 0x2090ed000 + 219924
CoreFoundation
0x20920f7bc 0x2090ed000 + 1189820
CoreFoundation
0x20921146c 0x2090ed000 + 1197164
myApp
MyAppStackclosure #in closure #1 in closure #1 in callback(_ (in myApp) (MyApp Stack.swift:307)
MyApp
$SIeg_IeyB_TR (in MyApp) (:0)
Foundation
0x209c998bc 0x209b82000 + 1145020
Foundation
0x209ba1ab8 0x209b82000 + 129720
Foundation
0x209ba0f8c 0x209b82000 + 126860
Foundation
0x209c9b790 0x209b82000 + 1152912
libdispatch.dylib
0x208bef198 0x208be1000 + 57752
libdispatch.dylib
0x208c42484 0x208be1000 + 398468
libdispatch.dylib
0x208be582c 0x208be1000 + 18476
libdispatch.dylib
0x208be4fb0 0x208be1000 + 16304
libdispatch.dylib
0x208bf1a18 0x208be1000 + 68120
libdispatch.dylib
0x208bf22c0 0x208be1000 + 70336
libsystem_pthread.dylib
0x208e2517c 0x208e19000 + 49532
libsystem_pthread.dylib
0x208e27cec 0x208e19000 + 60652
Crash 2:
SIGABRT
libsystem_kernel.dylib
0x23087b104 0x230858000 + 143620
libsystem_c.dylib
0x2307d2d78 0x23077b000 + 359800
libsystem_malloc.dylib
0x2308cf768 0x2308b1000 + 124776
libsystem_malloc.dylib
0x2308cf924 0x2308b1000 + 125220
libsystem_malloc.dylib
0x2308c22d4 0x2308b1000 + 70356
Foundation
0x2316710c8 0x23165e000 + 78024
Foundation
0x231662df0 0x23165e000 + 19952
MyApp
-[CBLCache addResource:] (in MyApp) (CBLCache.m:58)
MyApp
-[CBLDatabase documentWithID:mustExist:isNew:] (in MyApp) (CBLDatabase.m:0)
MyApp
-[CBLQueryRow document] (in MyApp) (CBLQueryRow.m:0)
MyApp
MyAppyAppStackclosure #in closure #1 in closure #1 in callback(_ (in MyApp) (:0)
I don’t think the “document” property is persistent throughout the iteration but I’m not sure. If it is it means you cannot flatten the query like that. @jens or @pasin does this look like something that should work?
I don’t understand how you can access custom properties like latitudeLongitude or notificationNumber on a CBLDocument object. Is this real code that compiles?
(also, note that Couchbase Lite 1.4 is nearly at the end of its support lifespan, and no one on the team has worked on it much in years…)
Yes, this code will compile with the help of a CBLExtension through whcih we can capture the custom properties.
Found like one of the crashes (crash 2) is pointing to this line. Now we know accessing the document like this will cause for some memory issue. But still, the crash log showing its something else. Any idea on this?
(Note: we are about to migrate to latest couchbase version. But until that we have to support the existing one)
That’s just the same information you posted earlier, again without any symbols. I don’t know where you’re getting these crash logs from, but it should be able to provide the symbols for you. If it’s a 3rd party service like Crashlytics, look at their documentation or ask their support.
The log with symbols isn’t the same stack. It looks like a different issue. Looks like your app is calling into Couchbase Lite on a background thread via NSOperation. Is this call thread-safe? In Couchbase Lite 1.x you can’t use a CBLDatabase instance on multiple threads/queues.
There are two operations getting executed in the operation queue.
Looping through the enumeration result and accessing documents enumeratorResult.compactMap({ ($0 as? CBLQueryRow)?.document })
Creating a model object from this document properties
Do you think these two tasks will cause any CBLDatabase instance use? Query generation and executing the query to get enumeratorResult are performing outside the operation queue. Also I suspect the usage of query.runAsync({ (enumeratorResult, error) in }) here instead of using synchronous query query.run.