diff --git a/src/App/Document.cpp b/src/App/Document.cpp index a0f04b1550..2562dc67cd 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1242,6 +1242,7 @@ Document::~Document() d->objectArray.clear(); for (it = d->objectMap.begin(); it != d->objectMap.end(); ++it) { + it->second->setStatus(ObjectStatus::Destroy, true); delete(it->second); } @@ -2652,6 +2653,7 @@ void Document::remObject(const char* sName) // if not saved in undo -> delete object later std::unique_ptr delobj(pos->second); tobedestroyed.swap(delobj); + tobedestroyed->setStatus(ObjectStatus::Destroy, true); } } @@ -2717,6 +2719,7 @@ void Document::_remObject(DocumentObject* pcObject) // for a rollback delete the object if (d->rollback) { + pcObject->setStatus(ObjectStatus::Destroy, true); delete pcObject; } } diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index 9fdcaca62a..2c81458ea7 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -78,11 +78,16 @@ void PropertyLink::setValue(App::DocumentObject * lValue) aboutToSetValue(); #ifndef USE_OLD_DAG // maintain the back link in the DocumentObject class if it is from a document object - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - if(_pcLink) - _pcLink->_removeBackLink(static_cast(getContainer())); - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + if (_pcLink) + _pcLink->_removeBackLink(parent); + if (lValue) + lValue->_addBackLink(parent); + } } #endif _pcLink=lValue; @@ -214,11 +219,16 @@ void PropertyLinkList::setValue(DocumentObject* lValue) { #ifndef USE_OLD_DAG //maintain the back link in the DocumentObject class - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); + if (lValue) + lValue->_addBackLink(parent); + } } #endif @@ -240,11 +250,16 @@ void PropertyLinkList::setValues(const std::vector& lValue) aboutToSetValue(); #ifndef USE_OLD_DAG //maintain the back link in the DocumentObject class - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); + for(auto *obj : lValue) + obj->_addBackLink(parent); + } } #endif _lValueList = lValue; @@ -403,11 +418,16 @@ void PropertyLinkSub::setValue(App::DocumentObject * lValue, const std::vectorisDerivedFrom(App::DocumentObject::getClassTypeId())) { - if (_pcLinkSub) - _pcLinkSub->_removeBackLink(static_cast(getContainer())); - if (lValue) - lValue->_addBackLink(static_cast(getContainer())); + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + if (_pcLinkSub) + _pcLinkSub->_removeBackLink(parent); + if (lValue) + lValue->_addBackLink(parent); + } } #endif _pcLinkSub=lValue; @@ -603,11 +623,16 @@ void PropertyLinkSubList::setValue(DocumentObject* lValue,const char* SubName) { #ifndef USE_OLD_DAG //maintain backlinks - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - if (lValue) - lValue->_addBackLink(static_cast(getContainer())); + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); + if (lValue) + lValue->_addBackLink(parent); + } } #endif @@ -634,17 +659,21 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c #ifndef USE_OLD_DAG //maintain backlinks. - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); - //_lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + for(auto *obj : lValue) + obj->_addBackLink(parent); + } } #endif @@ -664,17 +693,21 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c #ifndef USE_OLD_DAG //maintain backlinks. - if(getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); - //_lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - for(auto *obj : lValue) - obj->_addBackLink(static_cast(getContainer())); + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + for(auto *obj : lValue) + obj->_addBackLink(parent); + } } #endif @@ -688,17 +721,21 @@ void PropertyLinkSubList::setValue(DocumentObject* lValue, const std::vectorisDerivedFrom(App::DocumentObject::getClassTypeId())) { + if (getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + //_lValueList can contain items multiple times, but we trust the document + //object to ensure that this works + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); - //_lValueList can contain items multiple times, but we trust the document - //object to ensure that this works - for(auto *obj : _lValueList) - obj->_removeBackLink(static_cast(getContainer())); - - //maintain backlinks. lValue can contain items multiple times, but we trust the document - //object to ensure that the backlink is only added once - if(lValue) - lValue->_addBackLink(static_cast(getContainer())); + //maintain backlinks. lValue can contain items multiple times, but we trust the document + //object to ensure that the backlink is only added once + if (lValue) + lValue->_addBackLink(parent); + } } #endif