/// <summary> /// Initializes the this instance with the specified memory location ranges. /// </summary> /// <param name="ranges">The memory location ranges.</param> protected void Initialize(MemoryLocation[] ranges) { int newEnd = 0; for (int i = 1; i < ranges.Length; i++) { if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd) { ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd; } else { ranges[++newEnd] = ranges[i]; } } newEnd++; Array.Resize(ref ranges, newEnd); this.ranges = ranges; finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion { BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd }).ToList()); }
public DumpFileMemoryReader(string dumpFilePath) { bool dispose = true; FileStream fileStream = null; MemoryMappedFile memoryMappedFile = null; MemoryMappedViewStream stream = null; try { fileStream = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read); memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false); stream = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read); stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer); IntPtr streamPointer = IntPtr.Zero; uint streamSize = 0; MINIDUMP_DIRECTORY directory = new MINIDUMP_DIRECTORY(); if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize)) throw new Exception("Unable to read mini dump stream"); var data = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST)); ulong lastEnd = data.BaseRva; ranges = new MemoryLocation[data.NumberOfMemoryRanges]; for (int i = 0; i < ranges.Length; i++) { var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64)); ranges[i] = new MemoryLocation() { MemoryStart = descriptor.StartOfMemoryRange, MemoryEnd = descriptor.StartOfMemoryRange + descriptor.DataSize, FilePosition = lastEnd, }; lastEnd += descriptor.DataSize; } int newEnd = 0; for (int i = 1; i < ranges.Length; i++) if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd) ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd; else ranges[++newEnd] = ranges[i]; newEnd++; Array.Resize(ref ranges, newEnd); finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion { BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd }).ToArray()); dispose = false; } finally { if (dispose) { stream.SafeMemoryMappedViewHandle.ReleasePointer(); if (stream != null) { stream.Dispose(); } if (memoryMappedFile != null) { memoryMappedFile.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } else { this.fileStream = fileStream; this.stream = stream; this.memoryMappedFile = memoryMappedFile; } } }
public DumpFileMemoryReader(string dumpFilePath) { bool dispose = true; FileStream fileStream = null; MemoryMappedFile memoryMappedFile = null; MemoryMappedViewStream stream = null; try { fileStream = new FileStream(dumpFilePath, FileMode.Open, FileAccess.Read); memoryMappedFile = MemoryMappedFile.CreateFromFile(fileStream, Guid.NewGuid().ToString(), fileStream.Length, MemoryMappedFileAccess.Read, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, false); stream = memoryMappedFile.CreateViewStream(0, fileStream.Length, MemoryMappedFileAccess.Read); stream.SafeMemoryMappedViewHandle.AcquirePointer(ref basePointer); IntPtr streamPointer = IntPtr.Zero; uint streamSize = 0; MINIDUMP_DIRECTORY directory = new MINIDUMP_DIRECTORY(); if (!MiniDumpReadDumpStream((IntPtr)basePointer, MINIDUMP_STREAM_TYPE.Memory64ListStream, ref directory, ref streamPointer, ref streamSize)) { throw new Exception("Unable to read mini dump stream"); } var data = (MINIDUMP_MEMORY64_LIST)Marshal.PtrToStructure(streamPointer, typeof(MINIDUMP_MEMORY64_LIST)); ulong lastEnd = data.BaseRva; ranges = new MemoryLocation[data.NumberOfMemoryRanges]; for (int i = 0; i < ranges.Length; i++) { var descriptor = (MINIDUMP_MEMORY_DESCRIPTOR64)Marshal.PtrToStructure(streamPointer + sizeof(MINIDUMP_MEMORY64_LIST) + i * sizeof(MINIDUMP_MEMORY_DESCRIPTOR64), typeof(MINIDUMP_MEMORY_DESCRIPTOR64)); ranges[i] = new MemoryLocation() { MemoryStart = descriptor.StartOfMemoryRange, MemoryEnd = descriptor.StartOfMemoryRange + descriptor.DataSize, FilePosition = lastEnd, }; lastEnd += descriptor.DataSize; } int newEnd = 0; for (int i = 1; i < ranges.Length; i++) { if (ranges[i].MemoryStart == ranges[newEnd].MemoryEnd) { ranges[newEnd].MemoryEnd = ranges[i].MemoryEnd; } else { ranges[++newEnd] = ranges[i]; } } newEnd++; Array.Resize(ref ranges, newEnd); finder = new MemoryRegionFinder(ranges.Select(r => new MemoryRegion { BaseAddress = r.MemoryStart, MemoryEnd = r.MemoryEnd }).ToArray()); dispose = false; } finally { if (dispose) { stream.SafeMemoryMappedViewHandle.ReleasePointer(); if (stream != null) { stream.Dispose(); } if (memoryMappedFile != null) { memoryMappedFile.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } else { this.fileStream = fileStream; this.stream = stream; this.memoryMappedFile = memoryMappedFile; } } }