summaryrefslogtreecommitdiff
path: root/src/debug/daccess/request_svr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/daccess/request_svr.cpp')
-rw-r--r--src/debug/daccess/request_svr.cpp171
1 files changed, 72 insertions, 99 deletions
diff --git a/src/debug/daccess/request_svr.cpp b/src/debug/daccess/request_svr.cpp
index 1fe20e2b60..6a1de35ff9 100644
--- a/src/debug/daccess/request_svr.cpp
+++ b/src/debug/daccess/request_svr.cpp
@@ -18,13 +18,11 @@
#include <sigformat.h>
#include <win32threadpool.h>
-
-#include <gceesvr.cpp>
-
+#include "request_common.h"
int GCHeapCount()
{
- return SVR::gc_heap::n_heaps;
+ return *g_gcDacGlobals->n_heaps;
}
HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
@@ -37,8 +35,7 @@ HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
}
// marshal the segment from target to host
- SVR::heap_segment *pHeapSegment =
- __DPtr<SVR::heap_segment>(TO_TADDR(addr));
+ dac_heap_segment *pHeapSegment = __DPtr<dac_heap_segment>(TO_TADDR(addr));
// initialize fields by copying from the marshaled segment (note that these are all target addresses)
pSegment->segmentAddr = addr;
@@ -48,7 +45,7 @@ HRESULT GetServerHeapData(CLRDATA_ADDRESS addr, DacpHeapSegmentData *pSegment)
pSegment->used = (CLRDATA_ADDRESS)(ULONG_PTR) pHeapSegment->used;
pSegment->mem = (CLRDATA_ADDRESS)(ULONG_PTR) (pHeapSegment->mem);
pSegment->next = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeapSegment->next);
- pSegment->gc_heap = (CLRDATA_ADDRESS)(ULONG_PTR) pHeapSegment->heap;
+ pSegment->gc_heap = (CLRDATA_ADDRESS)pHeapSegment->heap;
return S_OK;
}
@@ -64,42 +61,20 @@ HRESULT GetServerHeaps(CLRDATA_ADDRESS pGCHeaps[], ICorDebugDataTarget * pTarget
// a DAC global (__GlobalPtr). The __GlobalPtr<...>::GetAddr() function gets the starting address of that global, but
// be sure to note this is a target address. We'll use this as our source for getting our local list of
// heap addresses.
- TADDR ptr = SVR::gc_heap::g_heaps.GetAddr();
- ULONG32 bytesRead = 0;
-
- for (int i=0;i<GCHeapCount();i++)
+ for (int i = 0; i < GCHeapCount(); i++)
{
-
- LPVOID pGCHeapAddr;
-
- // read the i-th element of g_heaps into pGCHeapAddr
- // @todo Microsoft: Again, if we capture the HRESULT from ReadVirtual, we can print a more explanatory
- // failure message.
- if (pTarget->ReadVirtual(ptr + i*sizeof(TADDR),
- (PBYTE) &pGCHeapAddr, sizeof(TADDR),
- &bytesRead) != S_OK)
- {
- return E_FAIL;
- }
- if (bytesRead != sizeof(LPVOID))
- {
- return E_FAIL;
- }
-
- // store the heap's starting address in our array.
- pGCHeaps[i] = (CLRDATA_ADDRESS)(ULONG_PTR) pGCHeapAddr;
+ pGCHeaps[i] = (CLRDATA_ADDRESS)HeapTableIndex(g_gcDacGlobals->g_heaps, i).GetAddr();
}
+
return S_OK;
}
#define PTR_CDADDR(ptr) TO_CDADDR(PTR_TO_TADDR(ptr))
#define HOST_CDADDR(host) TO_CDADDR(PTR_HOST_TO_TADDR(host))
-typedef DPTR(class SVR::gc_heap) PTR_SVR_gc_heap;
-
HRESULT ClrDataAccess::GetServerAllocData(unsigned int count, struct DacpGenerationAllocData *data, unsigned int *pNeeded)
{
- unsigned int heaps = (unsigned int)SVR::gc_heap::n_heaps;
+ unsigned int heaps = (unsigned int)GCHeapCount();
if (pNeeded)
*pNeeded = heaps;
@@ -108,13 +83,14 @@ HRESULT ClrDataAccess::GetServerAllocData(unsigned int count, struct DacpGenerat
if (count > heaps)
count = heaps;
- for (int n=0;n<SVR::gc_heap::n_heaps;n++)
+ for (unsigned int n=0; n < heaps; n++)
{
- PTR_SVR_gc_heap pHeap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[n]);
+ DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, n);
for (int i=0;i<NUMBERGENERATIONS;i++)
{
- data[n].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_bytes;
- data[n].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_bytes_loh;
+ dac_generation generation = *ServerGenerationTableIndex(pHeap, i);
+ data[n].allocData[i].allocBytes = (CLRDATA_ADDRESS)(ULONG_PTR) generation.allocation_context.alloc_bytes;
+ data[n].allocData[i].allocBytesLoh = (CLRDATA_ADDRESS)(ULONG_PTR) generation.allocation_context.alloc_bytes_loh;
}
}
}
@@ -130,7 +106,7 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
return E_INVALIDARG;
}
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(heapAddr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));
int i;
//get global information first
@@ -142,35 +118,25 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
// now get information specific to this heap (server mode gives us several heaps; we're getting
// information about only one of them.
- detailsData->alloc_allocated = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->alloc_allocated;
- detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->ephemeral_heap_segment;
+ detailsData->alloc_allocated = (CLRDATA_ADDRESS)pHeap->alloc_allocated;
+ detailsData->ephemeral_heap_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeap->ephemeral_heap_segment);
// get bounds for the different generations
for (i=0; i<NUMBERGENERATIONS; i++)
{
- detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(pHeap->generation_table[i].start_segment);
- detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_start;
- detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_ptr;
- detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->generation_table[i].allocation_context.alloc_limit;
+ DPTR(dac_generation) generation = ServerGenerationTableIndex(pHeap, i);
+ detailsData->generation_table[i].start_segment = (CLRDATA_ADDRESS)dac_cast<TADDR>(generation->start_segment);
+ detailsData->generation_table[i].allocation_start = (CLRDATA_ADDRESS)(ULONG_PTR)generation->allocation_start;
+ DPTR(gc_alloc_context) alloc_context = dac_cast<TADDR>(generation) + offsetof(dac_generation, allocation_context);
+ detailsData->generation_table[i].allocContextPtr = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_ptr;
+ detailsData->generation_table[i].allocContextLimit = (CLRDATA_ADDRESS)(ULONG_PTR) alloc_context->alloc_limit;
}
- // since these are all TADDRS, we have to compute the address of the m_FillPointers field explicitly
- TADDR pFillPointerArray = dac_cast<TADDR>(pHeap->finalize_queue) + offsetof(SVR::CFinalize,m_FillPointers);
-
- for(i=0; i<(NUMBERGENERATIONS+SVR::CFinalize::ExtraSegCount); i++)
+ DPTR(dac_finalize_queue) fq = pHeap->finalize_queue;
+ DPTR(uint8_t*) pFillPointerArray= dac_cast<TADDR>(fq) + offsetof(dac_finalize_queue, m_FillPointers);
+ for(i=0; i<(NUMBERGENERATIONS+dac_finalize_queue::ExtraSegCount); i++)
{
- ULONG32 returned = 0;
- size_t pValue;
- HRESULT hr = m_pTarget->ReadVirtual(pFillPointerArray+(i*sizeof(TADDR)),
- (PBYTE)&pValue,
- sizeof(TADDR),
- &returned);
- if (FAILED(hr) || (returned != sizeof(TADDR)))
- {
- return E_FAIL;
- }
-
- detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pValue;
+ detailsData->finalization_fill_pointers[i] = (CLRDATA_ADDRESS) pFillPointerArray[i];
}
return S_OK;
@@ -179,16 +145,16 @@ HRESULT ClrDataAccess::ServerGCHeapDetails(CLRDATA_ADDRESS heapAddr, DacpGcHeapD
HRESULT
ClrDataAccess::ServerOomData(CLRDATA_ADDRESS addr, DacpOomData *oomData)
{
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(addr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(addr));
- oom_history* pOOMInfo = (oom_history*)((TADDR)pHeap + offsetof(SVR::gc_heap,oom_info));
- oomData->reason = pOOMInfo->reason;
- oomData->alloc_size = pOOMInfo->alloc_size;
- oomData->available_pagefile_mb = pOOMInfo->available_pagefile_mb;
- oomData->gc_index = pOOMInfo->gc_index;
- oomData->fgm = pOOMInfo->fgm;
- oomData->size = pOOMInfo->size;
- oomData->loh_p = pOOMInfo->loh_p;
+ oom_history pOOMInfo = pHeap->oom_info;
+ oomData->reason = pOOMInfo.reason;
+ oomData->alloc_size = pOOMInfo.alloc_size;
+ oomData->available_pagefile_mb = pOOMInfo.available_pagefile_mb;
+ oomData->gc_index = pOOMInfo.gc_index;
+ oomData->fgm = pOOMInfo.fgm;
+ oomData->size = pOOMInfo.size;
+ oomData->loh_p = pOOMInfo.loh_p;
return S_OK;
}
@@ -197,7 +163,7 @@ HRESULT
ClrDataAccess::ServerGCInterestingInfoData(CLRDATA_ADDRESS addr, DacpGCInterestingInfoData *interestingInfoData)
{
#ifdef GC_CONFIG_DRIVEN
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(addr));
+ dac_gc_heap *pHeap = __DPtr<dac_gc_heap>(TO_TADDR(addr));
size_t* dataPoints = (size_t*)&(pHeap->interesting_data_per_heap);
for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
@@ -226,11 +192,11 @@ HRESULT ClrDataAccess::ServerGCHeapAnalyzeData(CLRDATA_ADDRESS heapAddr, DacpGcH
return E_INVALIDARG;
}
- SVR::gc_heap *pHeap = PTR_SVR_gc_heap(TO_TADDR(heapAddr));
+ DPTR(dac_gc_heap) pHeap = __DPtr<dac_gc_heap>(TO_TADDR(heapAddr));
analyzeData->heapAddr = heapAddr;
- analyzeData->internal_root_array = (CLRDATA_ADDRESS)(ULONG_PTR) pHeap->internal_root_array;
- analyzeData->internal_root_array_index = (size_t) pHeap->internal_root_array_index;
+ analyzeData->internal_root_array = (CLRDATA_ADDRESS)pHeap->internal_root_array;
+ analyzeData->internal_root_array_index = (size_t)pHeap->internal_root_array_index;
analyzeData->heap_analyze_success = (BOOL)pHeap->heap_analyze_success;
return S_OK;
@@ -240,30 +206,33 @@ void
ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
{
SUPPORTS_DAC;
- SVR::gc_heap::n_heaps.EnumMem();
- DacEnumMemoryRegion(SVR::gc_heap::g_heaps.GetAddr(),
- sizeof(TADDR) * SVR::gc_heap::n_heaps);
+ g_gcDacGlobals->n_heaps.EnumMem();
+ DacEnumMemoryRegion(g_gcDacGlobals->g_heaps.GetAddr(),
+ sizeof(TADDR) * *g_gcDacGlobals->n_heaps);
- SVR::gc_heap::g_heaps.EnumMem();
+ g_gcDacGlobals->gc_structures_invalid_cnt.EnumMem();
+ g_gcDacGlobals->g_heaps.EnumMem();
- for (int i=0;i<SVR::gc_heap::n_heaps;i++)
+ for (int i=0; i < *g_gcDacGlobals->n_heaps; i++)
{
- PTR_SVR_gc_heap pHeap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[i]);
+ DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
- DacEnumMemoryRegion(dac_cast<TADDR>(pHeap), sizeof(SVR::gc_heap));
- DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(SVR::CFinalize));
+ size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1);
+ 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);
// enumerating the generations from max (which is normally gen2) to max+1 gives you
// the segment list for all the normal segements plus the large heap segment (max+1)
// this is the convention in the GC so it is repeated here
- for (ULONG i = GCHeapUtilities::GetMaxGeneration(); i <= GCHeapUtilities::GetMaxGeneration()+1; i++)
+ for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++)
{
- __DPtr<SVR::heap_segment> seg = dac_cast<TADDR>(pHeap->generation_table[i].start_segment);
+ DPTR(dac_heap_segment) seg = ServerGenerationTableIndex(pHeap, i)->start_segment;
while (seg)
{
- DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(SVR::heap_segment));
+ DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(dac_heap_segment));
- seg = __DPtr<SVR::heap_segment>(dac_cast<TADDR>(seg->next));
+ seg = seg->next;
}
}
}
@@ -271,9 +240,9 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
DWORD DacGetNumHeaps()
{
- if (GCHeapUtilities::IsServerHeap())
- return (DWORD)SVR::gc_heap::n_heaps;
-
+ if (g_heap_type == GC_HEAP_SVR)
+ return (DWORD)*g_gcDacGlobals->n_heaps;
+
// workstation gc
return 1;
}
@@ -281,7 +250,7 @@ DWORD DacGetNumHeaps()
HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
{
// Scrape basic heap details
- int heaps = SVR::gc_heap::n_heaps;
+ int heaps = *g_gcDacGlobals->n_heaps;
pCount = heaps;
pHeaps = new (nothrow) HeapData[heaps];
if (pHeaps == NULL)
@@ -290,18 +259,22 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
for (int i = 0; i < heaps; ++i)
{
// Basic heap info.
- PTR_SVR_gc_heap heap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[i]);
+ DPTR(dac_gc_heap) heap = HeapTableIndex(g_gcDacGlobals->g_heaps, i);
+ dac_generation gen0 = *ServerGenerationTableIndex(heap, 0);
+ dac_generation gen1 = *ServerGenerationTableIndex(heap, 1);
+ dac_generation gen2 = *ServerGenerationTableIndex(heap, 2);
+ dac_generation loh = *ServerGenerationTableIndex(heap, 3);
- pHeaps[i].YoungestGenPtr = (CORDB_ADDRESS)heap->generation_table[0].allocation_context.alloc_ptr;
- pHeaps[i].YoungestGenLimit = (CORDB_ADDRESS)heap->generation_table[0].allocation_context.alloc_limit;
+ pHeaps[i].YoungestGenPtr = (CORDB_ADDRESS)gen0.allocation_context.alloc_ptr;
+ pHeaps[i].YoungestGenLimit = (CORDB_ADDRESS)gen0.allocation_context.alloc_limit;
- pHeaps[i].Gen0Start = (CORDB_ADDRESS)heap->generation_table[0].allocation_start;
+ pHeaps[i].Gen0Start = (CORDB_ADDRESS)gen0.allocation_start;
pHeaps[i].Gen0End = (CORDB_ADDRESS)heap->alloc_allocated;
- pHeaps[i].Gen1Start = (CORDB_ADDRESS)heap->generation_table[1].allocation_start;
+ pHeaps[i].Gen1Start = (CORDB_ADDRESS)gen1.allocation_start;
// Segments
- int count = GetSegmentCount(heap->generation_table[NUMBERGENERATIONS-1].start_segment);
- count += GetSegmentCount(heap->generation_table[NUMBERGENERATIONS-2].start_segment);
+ int count = GetSegmentCount(loh.start_segment);
+ count += GetSegmentCount(gen2.start_segment);
pHeaps[i].SegmentCount = count;
pHeaps[i].Segments = new (nothrow) SegmentData[count];
@@ -309,12 +282,12 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
return E_OUTOFMEMORY;
// Small object heap segments
- SVR::PTR_heap_segment seg = heap->generation_table[NUMBERGENERATIONS-2].start_segment;
+ DPTR(dac_heap_segment) seg = gen2.start_segment;
int j = 0;
for (; seg && (j < count); ++j)
{
pHeaps[i].Segments[j].Start = (CORDB_ADDRESS)seg->mem;
- if (seg.GetAddr() == TO_TADDR(heap->ephemeral_heap_segment))
+ if (seg.GetAddr() == heap->ephemeral_heap_segment.GetAddr())
{
pHeaps[i].Segments[j].End = (CORDB_ADDRESS)heap->alloc_allocated;
pHeaps[i].EphemeralSegment = j;
@@ -331,7 +304,7 @@ HRESULT DacHeapWalker::InitHeapDataSvr(HeapData *&pHeaps, size_t &pCount)
// Large object heap segments
- seg = heap->generation_table[NUMBERGENERATIONS-1].start_segment;
+ seg = loh.start_segment;
for (; seg && (j < count); ++j)
{
pHeaps[i].Segments[j].Generation = 3;