The RefCounted helper class (c4Impl.hh) has a destructor with an assertion in it. An assertion failure throws an exception, but throwing from a destructor is illegal and triggers immediate termination.
To reproduce this I added a throw call at the start of MapReduceIndex::readState() to simulate a DB read error. This produces the following crash during the CBL ViewInternal test suite:
13:55:51.779| WARNING: ForestDB error: unknown error (-9999)
{at FDBLogCallback:68}
13:55:51.780| WARNING: ForestDB error: Assertion failed: _refCount == 0 (/Couchbase/CouchbaseLite/vendor/CBForest/C/c4Impl.hh:115, in ~RefCounted) {at FDBLogCallback:68}
libc++abi.dylib: terminating with uncaught exception of type cbforest::error: unknown error
[x] The destructor shouldn't throw an exception. In fact I should review all destructors to make sure they don't throw; it was only recently that I learned they can't in C++11.
[x] The implementation of RefCounted is wrong in that it initializes the refCount to 1. This results in an invalid refCount in this situation where an exception occurs during construction of a subclass.
The RefCounted helper class (c4Impl.hh) has a destructor with an assertion in it. An assertion failure throws an exception, but throwing from a destructor is illegal and triggers immediate termination.
This seems to be the cause of https://github.com/couchbase/couchbase-lite-ios/issues/1422; the assertion failure happens because the RefCounted instance hasn't been constructed yet.
To reproduce this I added a
throw
call at the start ofMapReduceIndex::readState()
to simulate a DB read error. This produces the following crash during the CBL ViewInternal test suite: