ccgus / fmdb

A Cocoa / Objective-C wrapper around SQLite
Other
13.84k stars 2.76k forks source link

FMDatabaseQueue inDatabase: _block_invoke #613

Open ManuelManzanera opened 6 years ago

ManuelManzanera commented 6 years ago

Hi,

We are having the problem mentioned in the title. We think it happens when some actions are executed with the App in the background but we can not reproduce it.

0. Crashed: fmdb.<FMDatabaseQueue: 0x174249b70>

0 libsystem_kernel.dylib 0x191ac1014 pthread_kill + 8 1 libsystem_pthread.dylib 0x191b8b264 pthread_kill + 112 2 libsystem_c.dylib 0x191a359c4 abort + 140 3 libsystem_c.dylib 0x191a0a53c basename_r + 314 4 FMDB 0x100b0936c 30-[FMDatabaseQueue inDatabase:]_block_invoke (FMDatabaseQueue.m:157) 5 Clubberize 0x10032f254 DatabaseAdapter.getEvenById(Int!) -> Event? (DatabaseAdapter.swift:1541) 6 Clubberize 0x100231824 static GeofenceAdapter.getEvent([AnyHashable : Any]) -> Event! (GeofenceAdapter.swift:200) 7 Clubberize 0x100231204 static GeofenceAdapter.cancelEvenId(Int!) -> () (GeofenceAdapter.swift:104) 8 Clubberize 0x10022932c GeofenceTransition.getGeofenceIdentifiers(String, fOnVenueGeofence : (Int, Int, Int, [Beacon], [Event], Bool) -> (), fOnFestivalGeofence : (Int, Int, [Beacon], [Festival], Bool) -> ()) -> () (GeofenceTransition.swift:164) 9 Clubberize 0x100228afc GeofenceTransition.onGeofenceExit(CLCircularRegion) -> () (GeofenceTransition.swift:132) 10 Clubberize 0x1003596c4 GeofenceLoad.stopMonitoringRegion(CLRegion) -> () (GeofenceLoad.swift:455) 11 Clubberize 0x1003593a4 GeofenceLoad.stopMonitoringAllRegions([String]) -> [String] (GeofenceLoad.swift:431) 12 Clubberize 0x100357874 GeofenceLoad.(resetMonitoredGeofences() -> ()).(closure #1) (GeofenceLoad.swift:281) 13 Clubberize 0x100345d80 DatabaseAdapter.(getNearestGeofences(Double, nLongitude : Double, nCount : Int, closure : ([Geofence]) -> ()?) -> ()).(closure #1) (DatabaseAdapter.swift:2359) 14 Clubberize 0x100315a2c thunk (DatabaseAdapter.swift) 15 FMDB 0x100b093a8 30-[FMDatabaseQueue inDatabase:]_block_invoke (FMDatabaseQueue.m:162) 16 libdispatch.dylib 0x19197e9a0 _dispatch_client_callout + 16 17 libdispatch.dylib 0x19198bee0 _dispatch_barrier_sync_f_invoke + 84 18 FMDB 0x100b09318 -[FMDatabaseQueue inDatabase:] (FMDatabaseQueue.m:176) 19 Clubberize 0x100344bc8 DatabaseAdapter.getNearestGeofences(Double, nLongitude : Double, nCount : Int, closure : ([Geofence]) -> ()?) -> () (DatabaseAdapter.swift:2371) 20 Clubberize 0x100357814 GeofenceLoad.resetMonitoredGeofences() -> () (GeofenceLoad.swift:292) 21 Clubberize 0x1003f1600 LocationHelper.locationManager(CLLocationManager, didUpdateLocations : [CLLocation]) -> () (LocationHelper.swift:297) 22 Clubberize 0x1003f19bc @objc LocationHelper.locationManager(CLLocationManager, didUpdateLocations : [CLLocation]) -> () (LocationHelper.swift) 23 CoreLocation 0x19ad4a730 (null) + 35704 24 CoreLocation 0x19ad49fcc (null) + 33812 25 CoreLocation 0x19ad3d1d8 (null) + 1000 26 CoreFoundation 0x192a7530c CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 20 27 CoreFoundation 0x192a74b28 CFRunLoopDoBlocks + 288 28 CoreFoundation 0x192a72e1c __CFRunLoopRun + 1884 29 CoreFoundation 0x1929a2da4 CFRunLoopRunSpecific + 424 30 GraphicsServices 0x19440d074 GSEventRunModal + 100 31 UIKit 0x198c5dc9c UIApplicationMain + 208 32 Clubberize 0x1001853b4 main (AppDelegate.swift:23) 33 libdyld.dylib 0x1919b159c start + 4

--

0. Crashed: fmdb.<FMDatabaseQueue: 0x174249b70>

0 libsystem_kernel.dylib 0x191ac1014 pthread_kill + 8 1 libsystem_pthread.dylib 0x191b8b264 pthread_kill + 112 2 libsystem_c.dylib 0x191a359c4 abort + 140 3 libsystem_c.dylib 0x191a0a53c basename_r + 314 4 FMDB 0x100b0936c 30-[FMDatabaseQueue inDatabase:]_block_invoke (FMDatabaseQueue.m:157) 5 Clubberize 0x10032f254 DatabaseAdapter.getEventById(Int!) -> Event? (DatabaseAdapter.swift:1541) 6 Clubberize 0x100231824 static GeofenceAdapter.getEvent([AnyHashable : Any]) -> Event! (GeofenceAdapter.swift:200) 7 Clubberize 0x100231204 static GeofenceAdapter.cancelEventByGeofenceId(Int!) -> () (GeofenceAdapter.swift:104) 8 Clubberize 0x10022932c GeofenceTransition.getGeofenceIdentifiers(String, fOnVenueGeofence : (Int, Int, Int, [Beacon], [Event], Bool) -> (), fOnFestivalGeofence : (Int, Int, [Beacon], [Festival], Bool) -> ()) -> () (GeofenceTransition.swift:164) 9 Clubberize 0x100228afc GeofenceTransition.onGeofenceExit(CLCircularRegion) -> () (GeofenceTransition.swift:132) 10 Clubberize 0x1003596c4 GeofenceLoad.stopMonitoringRegion(CLRegion) -> () (GeofenceLoad.swift:455) 11 Clubberize 0x1003593a4 GeofenceLoad.stopMonitoringAllRegions([String]) -> [String] (GeofenceLoad.swift:431) 12 Clubberize 0x100357874 GeofenceLoad.(resetMonitoredGeofences() -> ()).(closure #1) (GeofenceLoad.swift:281) 13 Clubberize 0x100345d80 DatabaseAdapter.(getNearestGeofences(Double, nLongitude : Double, nCount : Int, closure : ([Geofence]) -> ()?) -> ()).(closure #1) (DatabaseAdapter.swift:2359) 14 Clubberize 0x100315a2c thunk (DatabaseAdapter.swift) 15 FMDB 0x100b093a8 30-[FMDatabaseQueue inDatabase:]_block_invoke (FMDatabaseQueue.m:162) 16 libdispatch.dylib 0x19197e9a0 _dispatch_client_callout + 16 17 libdispatch.dylib 0x19198bee0 _dispatch_barrier_sync_f_invoke + 84 18 FMDB 0x100b09318 -[FMDatabaseQueue inDatabase:] (FMDatabaseQueue.m:176) 19 Clubberize 0x100344bc8 DatabaseAdapter.getNearestGeofences(Double, nLongitude : Double, nCount : Int, closure : ([Geofence]) -> ()?) -> () (DatabaseAdapter.swift:2371) 20 Clubberize 0x100357814 GeofenceLoad.resetMonitoredGeofences() -> () (GeofenceLoad.swift:292) 21 Clubberize 0x1003f1600 LocationHelper.locationManager(CLLocationManager, didUpdateLocations : [CLLocation]) -> () (LocationHelper.swift:297) 22 Clubberize 0x1003f19bc @objc LocationHelper.locationManager(CLLocationManager, didUpdateLocations : [CLLocation]) -> () (LocationHelper.swift) 23 CoreLocation 0x19ad4a730 (null) + 35704 24 CoreLocation 0x19ad49fcc (null) + 33812 25 CoreLocation 0x19ad3d1d8 (null) + 1000 26 CoreFoundation 0x192a7530c CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 20 27 CoreFoundation 0x192a74b28 CFRunLoopDoBlocks + 288 28 CoreFoundation 0x192a72e1c __CFRunLoopRun + 1884 29 CoreFoundation 0x1929a2da4 CFRunLoopRunSpecific + 424 30 GraphicsServices 0x19440d074 GSEventRunModal + 100 31 UIKit 0x198c5dc9c UIApplicationMain + 208 32 Clubberize 0x1001853b4 main (AppDelegate.swift:23) 33 libdyld.dylib

ccgus commented 6 years ago

Did you by any chance define NDEBUG, so the recursive check in inDatabase: gets skipped?

groue commented 6 years ago

Hello @ManuelManzanera,

Do both DatabaseAdapter.getNearestGeofences(...) and DatabaseAdapter.getEventById(...) invoke -[FMDatabaseQueue inDatabase:]? If so, couldn't it be possible that you'd have two nested calls to this method, as in the pseudo-code below?

[dbQueue inDatabase:^(FMDatabase *db) {
    ...
    [dbQueue inDatabase:^(FMDatabase *db) {
        ...
    }];
    ...
}];

If so, this is a programmer error, as you can see in this line: https://github.com/ccgus/fmdb/blob/v2.7/src/fmdb/FMDatabaseQueue.m#L178.

The fix is to refactor methods that access the database: have them stop using an implicit database queue. Instead, they should take a Database connection parameter. That database is provided by an explicit call to -[dbQueue inDatabase:] from, in your case, LocationHelper.locationManager(_:didUpdateLocations:) or GeofenceLoad.resetMonitoredGeofences().

But I'm not sure this is the origin of your crash, since you say that you can't reproduce it. Still, the signatures of DatabaseAdapter.getNearestGeofences(...) and DatabaseAdapter.getEventById(...) show no trace of a database parameter: this mean that one can not call the other.