From f25aa3cf30723bf02d30933cc8c601bcfe54dc4d Mon Sep 17 00:00:00 2001 From: Mike McLaughlin Date: Fri, 4 Jan 2019 10:29:59 -0800 Subject: [PATCH] Actually fix issue #21484 reported by the customer. GC heap globals like ephemeral_heap_segment and finalize_queue are null/invalid for a server GC. Add a check to skip the workstation GC memory enumeration if server. The server memory enumeration already skips if workstation GC. The dynamic module fix is still needed, createdump would have still hit this problem after the GC heap fix. Report the entire generation table in EnumWksGlobalMemoryRegions and EnumSvrGlobalMemoryRegions (#20233). --- src/debug/daccess/request.cpp | 20 ++++++++++++++------ src/debug/daccess/request_svr.cpp | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp index 377e008fd470..9c9cca622d8b 100644 --- a/src/debug/daccess/request.cpp +++ b/src/debug/daccess/request.cpp @@ -2814,11 +2814,14 @@ ClrDataAccess::GetGCHeapStaticData(struct DacpGcHeapDetails *detailsData) detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)alloc_context->alloc_limit; } - DPTR(dac_finalize_queue) fq = Dereference(g_gcDacGlobals->finalize_queue); - DPTR(uint8_t*) fillPointersTable = dac_cast(fq) + offsetof(dac_finalize_queue, m_FillPointers); - for (unsigned int i = 0; i<(*g_gcDacGlobals->max_gen + 2 + dac_finalize_queue::ExtraSegCount); i++) + if (g_gcDacGlobals->finalize_queue.IsValid()) { - detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*)); + DPTR(dac_finalize_queue) fq = Dereference(g_gcDacGlobals->finalize_queue); + DPTR(uint8_t*) fillPointersTable = dac_cast(fq) + offsetof(dac_finalize_queue, m_FillPointers); + for (unsigned int i = 0; i<(*g_gcDacGlobals->max_gen + 2 + dac_finalize_queue::ExtraSegCount); i++) + { + detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS)*TableIndex(fillPointersTable, i, sizeof(uint8_t*)); + } } SOSDacLeave(); @@ -3805,13 +3808,19 @@ ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags) { SUPPORTS_DAC; +#ifdef FEATURE_SVR_GC + // If server GC, skip enumeration + if (g_gcDacGlobals->g_heaps != nullptr) + return; +#endif + Dereference(g_gcDacGlobals->ephemeral_heap_segment).EnumMem(); g_gcDacGlobals->alloc_allocated.EnumMem(); g_gcDacGlobals->gc_structures_invalid_cnt.EnumMem(); Dereference(g_gcDacGlobals->finalize_queue).EnumMem(); // Enumerate the entire generation table, which has variable size - size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1); + size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 2); DacEnumMemoryRegion(dac_cast(g_gcDacGlobals->generation_table), gen_table_size); if (g_gcDacGlobals->generation_table.IsValid()) @@ -3826,7 +3835,6 @@ ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags) while (seg) { DacEnumMemoryRegion(dac_cast(seg), sizeof(dac_heap_segment)); - seg = seg->next; } } diff --git a/src/debug/daccess/request_svr.cpp b/src/debug/daccess/request_svr.cpp index 40e3600f9f26..8b3f11fd4db9 100644 --- a/src/debug/daccess/request_svr.cpp +++ b/src/debug/daccess/request_svr.cpp @@ -224,7 +224,7 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags) { DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, i); - size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1); + size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 2); DacEnumMemoryRegion(dac_cast(pHeap), sizeof(dac_gc_heap)); DacEnumMemoryRegion(dac_cast(pHeap->finalize_queue), sizeof(dac_finalize_queue)); DacEnumMemoryRegion(dac_cast(pHeap->generation_table), gen_table_size);