Skip to content

Commit

Permalink
Actually fix issue #21484 reported by the customer.
Browse files Browse the repository at this point in the history
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 (dotnet#20233).
  • Loading branch information
mikem8361 committed Jan 4, 2019
1 parent c382b48 commit f25aa3c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
20 changes: 14 additions & 6 deletions src/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TADDR>(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<TADDR>(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();
Expand Down Expand Up @@ -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<TADDR>(g_gcDacGlobals->generation_table), gen_table_size);

if (g_gcDacGlobals->generation_table.IsValid())
Expand All @@ -3826,7 +3835,6 @@ ClrDataAccess::EnumWksGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
while (seg)
{
DacEnumMemoryRegion(dac_cast<TADDR>(seg), sizeof(dac_heap_segment));

seg = seg->next;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/debug/daccess/request_svr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TADDR>(pHeap), sizeof(dac_gc_heap));
DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(dac_finalize_queue));
DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->generation_table), gen_table_size);
Expand Down

0 comments on commit f25aa3c

Please sign in to comment.