cbforest icon indicating copy to clipboard operation
cbforest copied to clipboard

Crash while compaction in background on iOS

Open 5b5 opened this issue 8 years ago • 2 comments

using couchbase-lite-ios 1.4 (via pod install)

The following crash occurs rather frequently when database compaction starts while app is started in background (e.g. via background fetch or silent push message) Compaction is started automatically, not manually.

Crashed: Thread
0  PurpleAnt                      0x1004d2894 std::__1::__hash_const_iterator<std::__1::__hash_node<std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, void*>*> std::__1::__hash_table<std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::__unordered_map_hasher<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::__unordered_map_equal<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool>, std::__1::equal_to<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >, true>, std::__1::allocator<std::__1::__hash_value_type<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool> > >::find<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const (__hash_table:2228)
1  PurpleAnt                      0x1004d133c cbforest::Database::getKeyStore(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) const (unordered_map:1121)
2  PurpleAnt                      0x1004d19e8 cbforest::Database::updatePurgeCount() (Database.cc:227)
3  PurpleAnt                      0x1004d10b4 cbforest::Database::compactionCallback(_fdb_file_handle*, unsigned int, char const*, fdb_doc_struct*, unsigned long long, unsigned long long, void*) (Database.cc:406)
4  PurpleAnt                      0x100516d78 _fdb_compact_file(_fdb_kvs_handle*, filemgr*, btreeblk_handle*, docio_handle*, hbtrie*, hbtrie*, btree*, btree*, unsigned long long, bool) + 8200
5  PurpleAnt                      0x1005154c4 fdb_compact_file + 1876
6  PurpleAnt                      0x100501624 compactor_thread(void*) + 22196
7  libsystem_pthread.dylib        0x18a3e568c _pthread_body + 240
8  libsystem_pthread.dylib        0x18a3e559c _pthread_body + 282
9  libsystem_pthread.dylib        0x18a3e2cb4 thread_start + 4

5b5 avatar Sep 05 '17 09:09 5b5

ForestDB is calling the compaction callback from the background compactor thread, and unfortunately Database::compactionCallback calls updatePurgeCount() which isn't thread-safe.

snej avatar Sep 05 '17 18:09 snej

The real fix won't be simple, because the Database class isn't designed to be thread-safe, and CBForest itself has no notion of queues or event loops so it can't somehow schedule the updatePurgeCount() call to run on the regular thread.

The best workaround I can think of is to take out the call to updatePurgeCount() at Database.cc:406. If your app never purges documents, there won't be any side effects. If it does purge documents, you'll need to rebuild view indexes after purging (which is what that updatePurgeCount call would have done for you.)

snej avatar Sep 05 '17 18:09 snej