HRESULT ClrDataAccess::GetServerAllocData(unsigned int count, struct DacpGenerationAllocData *data, unsigned int *pNeeded) { unsigned int heaps = (unsigned int)GCHeapCount(); if (pNeeded) *pNeeded = heaps; if (data) { if (count > heaps) count = heaps; for (unsigned int n=0; n < heaps; n++) { DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, n); for (int i=0;i<NUMBERGENERATIONS;i++) { 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; } } } return S_OK; }
HRESULT GetServerHeaps(CLRDATA_ADDRESS pGCHeaps[], ICorDebugDataTarget * pTarget) { // @todo Microsoft: It would be good to have an assert here to ensure pGCHeaps is large enough to // hold all the addresses. Currently we check that in the only caller, but if we were to call this from // somewhere else in the future, we could have a buffer overrun. // The runtime declares its own global array of gc heap addresses for multiple heap scenarios. We need to get // its starting address. This expression is a little tricky to parse, but in DAC builds, g_heaps is // 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. for (int i = 0; i < GCHeapCount(); i++) { pGCHeaps[i] = (CLRDATA_ADDRESS)HeapTableIndex(g_gcDacGlobals->g_heaps, i).GetAddr(); } return S_OK; }
HRESULT GetServerHeaps(CLRDATA_ADDRESS pGCHeaps[], ICLRDataTarget* pTarget) { TADDR ptr = SVR::gc_heap::g_heaps.GetAddr(); ULONG32 bytesRead = 0; CLRDATA_ADDRESS pDataAddr = (CLRDATA_ADDRESS) ptr; for (int i=0;i<GCHeapCount();i++) { LPVOID pGCHeapAddr; if (pTarget->ReadVirtual(pDataAddr + (sizeof(LPVOID)*i), (PBYTE) &pGCHeapAddr, sizeof(LPVOID), &bytesRead) != S_OK) { return E_FAIL; } if (bytesRead != sizeof(LPVOID)) { return E_FAIL; } pGCHeaps[i] = (CLRDATA_ADDRESS)(ULONG_PTR) pGCHeapAddr; } return S_OK; }