Skip to content

Commit

Permalink
Added more troubleshooting for Scope, in debug builds
Browse files Browse the repository at this point in the history
Scope::unregister will throw an exception if the data has changed
since it was registered. This usually means the data was invalidated /
freed, and indicates the Scope needs to be unregistered earlier.

For couchbase/couchbase-lite-core#712
  • Loading branch information
snej committed Feb 28, 2019
1 parent 6f18863 commit b2c4784
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
18 changes: 15 additions & 3 deletions Fleece/Core/Doc.cc
Expand Up @@ -86,7 +86,7 @@ namespace fleece { namespace impl {
_registered = true;
Log("Register (%p ... %p) --> Scope %p, sk=%p [Now %zu]",
data.buf, data.end(), this, sk, sMemoryMap->size());
//#if DEBUG
//#if DEBUG // Leaving this enabled for troubleshooting
if (_iter != sMemoryMap->begin() && prev(_iter)->first == key) {
Scope *existing = prev(_iter)->second;
if (existing->_data == _data && existing->_externDestination == _externDestination
Expand All @@ -95,12 +95,16 @@ namespace fleece { namespace impl {
data.buf, data.end(), this, sk);
} else {
FleeceException::_throw(InternalError,
"Incompatible duplicate Scope %p for (%p .. %p) with sk=%p: conflicts with %p with sk=%p",
"Incompatible duplicate Scope %p for (%p .. %p) with sk=%p: conflicts with %p for (%p .. %p) with sk=%p",
this, _data.buf, _data.end(), _sk.get(),
existing, existing->_sk.get());
existing, existing->_data.buf, existing->_data.end(),
existing->_sk.get());
}
}
//#endif
#if DEBUG
_dataHash = _data.hash();
#endif
}


Expand All @@ -111,6 +115,14 @@ namespace fleece { namespace impl {
_data.buf, _data.end(), this, _sk.get(), sMemoryMap->size()-1);
sMemoryMap->erase(_iter);
_registered = false;
#if DEBUG
if (_data.hash() != _dataHash)
FleeceException::_throw(InternalError,
"Memory range (%p .. %p) was altered while Scope %p (sk=%p) was active. "
"This usually means the Scope's data was freed/invalidated before the Scope "
"was unregistered/deleted. Unregister it earlier!",
_data.buf, _data.end(), this, _sk.get());
#endif
}
}

Expand Down
19 changes: 11 additions & 8 deletions Fleece/Core/Doc.hh
Expand Up @@ -58,14 +58,17 @@ namespace fleece { namespace impl {
using memoryMap = std::multimap<size_t, Scope*>;
static memoryMap *sMemoryMap;

Retained<SharedKeys> _sk;
slice const _externDestination;
slice const _data;
alloc_slice const _alloced;
bool _registered {false};
memoryMap::iterator _iter;
Retained<SharedKeys> _sk; // SharedKeys used for this Fleece data
slice const _externDestination; // Extern ptr destination for this data
slice const _data; // The memory range I represent
alloc_slice const _alloced; // Retains data if it's an alloc_slice
bool _registered {false}; // Am I registered in sMemoryMap?
memoryMap::iterator _iter; // Pointer to my entry in sMemoryMap
#if DEBUG
uint32_t _dataHash; // hash of _data, for troubleshooting
#endif
protected:
bool _isDoc {false};
bool _isDoc {false}; // True if I am a field of a Doc
};


Expand Down Expand Up @@ -102,7 +105,7 @@ namespace fleece { namespace impl {
private:
void init(Trust) noexcept;

const Value* _root {nullptr};
const Value* _root {nullptr}; // The root object of the Fleece
};

} }

0 comments on commit b2c4784

Please sign in to comment.