diff --git a/src/jrd/trace/TraceConfigStorage.cpp b/src/jrd/trace/TraceConfigStorage.cpp index 6afb453dbc..9027db21e8 100644 --- a/src/jrd/trace/TraceConfigStorage.cpp +++ b/src/jrd/trace/TraceConfigStorage.cpp @@ -470,6 +470,9 @@ void ConfigStorage::compact() ULONG check_used, check_size; check_used = check_size = sizeof(TraceCSHeader); + // Track undeleted slots from dead processes + Firebird::SortedArray> deadProcesses; + // collect used slots, sort them by offset for (TraceCSHeader::Slot* slot = header->slots; slot < header->slots + header->slots_cnt; slot++) { @@ -477,8 +480,10 @@ void ConfigStorage::compact() ((slot->ses_flags & trs_system) == 0) && // System sessions are shared for multiple connections so they may live without the original process !ISC_check_process_existence(slot->ses_pid)) { - fb_assert(header->cnt_uses != 0); - header->cnt_uses--; // Process that created trace session disappeared, count it out + // A SUPER server may shut down, but its Storage shared memory continues to live due to an embedded user session. + // The process might allocate multiple slots, so count them carefully. + deadProcesses.add(slot->ses_pid); + markDeleted(slot); } @@ -491,6 +496,11 @@ void ConfigStorage::compact() data.add(item); } + // Process that created storages disappeared, count it out + fb_assert(header->cnt_uses > deadProcesses.getCount()); + header->cnt_uses -= deadProcesses.getCount(); + deadProcesses.clear(); + fb_assert(check_used == header->mem_used); fb_assert(check_size == header->mem_offset);