public MiniDumpHeader ReadHeader() { // Both SIGNATURE & VERSION are from minidumpapiset.h const UInt32 MINIDUMP_SIGNATURE = 0x504d444d; // PMDM, P = 0x50, M = 0x4d, D = 0x44, M = 0x4d const UInt32 MINIDUMP_VERSION = 42899; using (var viewAccessor = _minidumpMappedFile.CreateViewAccessor(0, Marshal.SizeOf(typeof(MINIDUMP_HEADER)), MemoryMappedFileAccess.Read)) { MINIDUMP_HEADER header; viewAccessor.Read <MINIDUMP_HEADER>(0, out header); if (header.Signature != MINIDUMP_SIGNATURE) { return(null); } if (windows.LoWord(header.Version) != MINIDUMP_VERSION) { return(null); } MINIDUMP_DIRECTORY[] directoryEntries = new MINIDUMP_DIRECTORY[header.NumberOfStreams]; _mappedFileView.ReadArray <MINIDUMP_DIRECTORY>(header.StreamDirectoryRva, directoryEntries, 0, (int)header.NumberOfStreams); return(new MiniDumpHeader(header, directoryEntries, this)); } }
public static List <MINIDUMP_DIRECTORY> ParseDirectory(Program.MiniDump minidump) { List <MINIDUMP_DIRECTORY> directories = new List <Directory.MINIDUMP_DIRECTORY>(); for (int i = 0; i < (int)minidump.header.NumberOfStreams; i++) { minidump.fileBinaryReader.BaseStream.Seek(minidump.header.StreamDirectoryRva + i * 12, 0); UInt32 raw_stream_type_value = Helpers.ReadUInt32(minidump.fileBinaryReader); bool is_user_stream = (int)raw_stream_type_value > (int)MINIDUMP_STREAM_TYPE.LastReservedStream; bool is_stream_supported = Enum.IsDefined(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value); if (is_user_stream && !is_stream_supported) { continue; } MINIDUMP_DIRECTORY md = new MINIDUMP_DIRECTORY(); md.StreamType = (MINIDUMP_STREAM_TYPE)Enum.Parse(typeof(MINIDUMP_STREAM_TYPE), Enum.GetName(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value)); // Enum.GetName(typeof(MINIDUMP_STREAM_TYPE), (int)raw_stream_type_value); md.Size = Helpers.ReadUInt32(minidump.fileBinaryReader); md.Offset = Helpers.ReadUInt32(minidump.fileBinaryReader); directories.Add(md); } return(directories); }
public WindowsDumpFileMemoryReader(string dumpFilePath) : base(dumpFilePath) { bool dispose = true; try { 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; MemoryLocation[] 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; } Initialize(ranges); dispose = false; } finally { if (dispose) { stream.SafeMemoryMappedViewHandle.ReleasePointer(); if (stream != null) { stream.Dispose(); } if (memoryMappedFile != null) { memoryMappedFile.Dispose(); } if (fileStream != null) { fileStream.Dispose(); } } } }
protected unsafe bool ReadStream <T>(MINIDUMP_STREAM_TYPE streamToRead, out T streamData, out IntPtr streamPointer, out uint streamSize) { MINIDUMP_DIRECTORY directory = new MINIDUMP_DIRECTORY(); streamData = default(T); streamPointer = IntPtr.Zero; streamSize = 0; try { byte *baseOfView = null; _mappedFileView.AcquirePointer(ref baseOfView); if (baseOfView == null) { throw new Exception("Unable to aquire pointer to memory mapped view"); } if (!NativeMethods.MiniDumpReadDumpStream((IntPtr)baseOfView, streamToRead, ref directory, ref streamPointer, ref streamSize)) { int lastError = Marshal.GetLastWin32Error(); if (lastError == DbgHelpErrors.ERR_ELEMENT_NOT_FOUND) { return(false); } else { throw new Win32Exception(lastError); } } streamData = (T)Marshal.PtrToStructure(streamPointer, typeof(T)); } finally { _mappedFileView.ReleasePointer(); } return(true); }
public MINIDUMP_DIRECTORY ReadStreamType(MINIDUMP_STREAM_TYPE strmType) { MINIDUMP_DIRECTORY dir = new MINIDUMP_DIRECTORY(); var initloc = new MINIDUMP_LOCATION_DESCRIPTOR() { Rva = 0, DataSize = AllocationGranularity }; if (MapStream(initloc) == IntPtr.Zero) { throw new InvalidOperationException("MapViewOfFileFailed"); } var dirPtr = IntPtr.Zero; dir.location = initloc; var _strmPtr = IntPtr.Zero; var _strmSize = 0u; if (MiniDumpReadDumpStream( _addrFileMapping, strmType, ref dirPtr, ref _strmPtr, ref _strmSize )) { dir = Marshal.PtrToStructure <MINIDUMP_DIRECTORY>(dirPtr); } else { dir.streamType = strmType; dir.location.Rva = 0; dir.location.DataSize = 0; } return(dir); }
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; } } }
private static extern bool MiniDumpReadDumpStream( IntPtr BaseOfDump, MINIDUMP_STREAM_TYPE StreamNumber, ref MINIDUMP_DIRECTORY Dir, ref IntPtr StreamPointer, ref uint StreamSize);
internal MiniDumpDirectory(MINIDUMP_DIRECTORY directory) { _directory = directory; _location = new MiniDumpLocationDescriptor(directory.Location); }
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); var minValue = ranges[0].MemoryStart; var maxValue = ranges[ranges.Length - 1].MemoryEnd; triesStartBits = 64 - BucketSizeBits; triesStartMask = ((1UL << BucketSizeBits) - 1) << triesStartBits; while ((triesStartMask & (maxValue - 1)) == 0) { triesStartMask >>= BucketSizeBits; triesStartBits -= BucketSizeBits; } var rangesTuple = new Tuple <int, MemoryLocation> [ranges.Length]; for (int i = 0; i < rangesTuple.Length; i++) { rangesTuple[i] = Tuple.Create(i, ranges[i]); } var element = new TriesElement(rangesTuple, triesStartMask, triesStartBits); buckets = element.buckets; dispose = false; } catch (Exception ex) { Console.Error.WriteLine(ex); throw; } 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; } } }