diff options
Diffstat (limited to 'src/debug/daccess/request_svr.cpp')
-rw-r--r-- | src/debug/daccess/request_svr.cpp | 171 |
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; |