diff --git a/lib/icingadb/icingadb-objects.cpp b/lib/icingadb/icingadb-objects.cpp index 948751460df..63ee0d0728b 100644 --- a/lib/icingadb/icingadb-objects.cpp +++ b/lib/icingadb/icingadb-objects.cpp @@ -559,14 +559,27 @@ std::vector>> IcingaDB::ChunkObjects(std chunks.reserve((std::distance(offset, end) + chunkSize - 1) / chunkSize); + auto emplaceChunk ([&chunks](decltype(objects)::const_iterator from, decltype(objects)::const_iterator to) { + chunks.emplace_back(std::vector()); + + // If we encounter not yet activated objects, i.e. they are currently being loaded and are about to + // be activated, but are still partially initialised, we want to exclude them from the config dump + // before we end up in a nullptr deference and crash the Icinga 2 process. Should these excluded objects + // later reach the activation process, they will be captured via the `OnActiveChanged` event and processed + // in IcingaDB::VersionChangedHandler() as runtime updates. + std::copy_if(from, to, std::back_inserter(chunks.back()), [](const ConfigObject::Ptr& obj) { + return obj->IsActive(); + }); + }); + while (std::distance(offset, end) >= chunkSize) { auto until (offset + chunkSize); - chunks.emplace_back(offset, until); + emplaceChunk(offset, until); offset = until; } if (offset != end) { - chunks.emplace_back(offset, end); + emplaceChunk(offset, end); } return chunks;