From 0222575d86294ec10ee1aa1c52f25209499b5d6a Mon Sep 17 00:00:00 2001 From: Matesic Darko Date: Fri, 13 Mar 2026 11:48:01 +0100 Subject: [PATCH] fix crash after diff and closing app --- libs/libcore/src/baseobject.cpp | 6 +++++- libs/libcore/src/databasemodel.cpp | 14 +++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/libs/libcore/src/baseobject.cpp b/libs/libcore/src/baseobject.cpp index 35f6caa3d..8f73e5258 100644 --- a/libs/libcore/src/baseobject.cpp +++ b/libs/libcore/src/baseobject.cpp @@ -1630,7 +1630,11 @@ void BaseObject::clearDependencies() void BaseObject::clearReferences() { - for(auto &obj : object_refs) + /* Iterate over a snapshot: unsetDependency calls back into this->unsetReference + * which erases from object_refs, invalidating the range-for iterator. */ + auto refs_snapshot = object_refs; + + for(auto &obj : refs_snapshot) obj->unsetDependency(this); object_refs.clear(); diff --git a/libs/libcore/src/databasemodel.cpp b/libs/libcore/src/databasemodel.cpp index c0c8d3980..46edfedd8 100644 --- a/libs/libcore/src/databasemodel.cpp +++ b/libs/libcore/src/databasemodel.cpp @@ -836,10 +836,22 @@ void DatabaseModel::destroyObjects() ritr = objects.rbegin(); ritr_end = objects.rend(); + /* Pass 1: clear all deps/refs across every object before any deletion. + * This prevents dangling pointers when Relationship::destroyObjects() later + * frees intermediate columns/constraints that are still referenced by other objects. */ + while(ritr != ritr_end) + { + ritr->second->clearAllDepsRefs(); + ritr++; + } + + ritr = objects.rbegin(); + ritr_end = objects.rend(); + + /* Pass 2: now safe to delete — no object can hold live pointers to another. */ while(ritr != ritr_end) { object = ritr->second; - object->clearAllDepsRefs(); ritr++; // We ignore the database itself, permission objects (destroyed separetely) and table children objects