internal ICorDebugGCHeapSegment(ICorDebugGCHeap heap, ref COR_SEGMENT corSegment) { Debug.Assert(heap.m_process != null); // Only call this on live heaps. m_heap = heap; m_start = corSegment.start; m_end = corSegment.end; m_heapNum = (int)corSegment.heap; }
public ICorDebugGCHeap(ICorDebugProcess process) { int isRunning; process.IsRunning(out isRunning); if (isRunning != 0) { throw new InvalidOperationException("The process must be stopped to dump the GC "); } m_typeTable = new Dictionary <COR_TYPEID, ICorDebugGCHeapType>(); m_types = new List <ICorDebugGCHeapType>(); // Type index 0 is reserverd for the 'Bad Type' var badType = new ICorDebugGCHeapType(this, "!BAD_TYPE!", ""); badType.m_size = 4; // We use the bad type as a way of filling holes in the heap, // Setting these fields marks this as the 'live heap' case. // GCHeapSegment is 'smart' and only fetches the information it // needs from the big blob of data in the segement. m_process = process; m_process5 = process as ICorDebugProcess5; if (m_process5 == null) { throw new Exception("The process is not running V4.5 of the .NET Framework (or V5.0 of silverlight), can't dump the GC Heap."); } COR_HEAPINFO heapInfo; m_process5.GetGCHeapInformation(out heapInfo); if (heapInfo.areGCStructuresValid == 0) { throw new Exception("The process is at a point where the GC structures are being updated. A heap dump is not possible at this time."); } m_pointerSize = (int)heapInfo.pointerSize; Debug.Assert(PointerSize == 4 || PointerSize == 8); // Create the segments (but this leaves the data in the segments // alone) var segmentList = new List <ICorDebugGCHeapSegment>(); ICorDebugHeapSegmentEnum regionEnum; m_process5.EnumerateHeapRegions(out regionEnum); uint fetched; COR_SEGMENT[] corSegment = new COR_SEGMENT[1]; for (; ;) { regionEnum.Next(1, corSegment, out fetched); if (fetched == 0) { break; } segmentList.Add(new ICorDebugGCHeapSegment(this, ref corSegment[0])); } m_icorDebugSegments = segmentList.ToArray(); // Create the segments. UpdateSegments(m_icorDebugSegments); // This is used in FetchIntPtrAt m_data = new byte[1024]; m_pinningHandle = GCHandle.Alloc(m_data, GCHandleType.Pinned); fixed(byte *ptr = m_data) { m_dataPtr = ptr; } }