void ParseMemoryListStream() { var strmDir = rdr_.ReadStreamType(MINIDUMP_STREAM_TYPE.MemoryListStream); var locStream = strmDir.location; if (locStream.Rva != 0) { var addrStream = rdr_.MapStream(locStream); var NumberOfMemoryRanges = Marshal.ReadInt32(addrStream); var ndescSize = (uint)(Marshal.SizeOf <MINIDUMP_MEMORY_DESCRIPTOR>()); var locRva = new MINIDUMP_LOCATION_DESCRIPTOR() { Rva = (uint)(locStream.Rva + Marshal.SizeOf <uint>()), DataSize = ndescSize }; _memories.NumberOfMemoryRanges = (uint)NumberOfMemoryRanges; _memories.MemoryRanges = new MINIDUMP_MEMORY_DESCRIPTOR[NumberOfMemoryRanges]; for (int i = 0; i < NumberOfMemoryRanges; i++) { var ptr = rdr_.MapStream(locRva); _memories.MemoryRanges[i] = Marshal.PtrToStructure <MINIDUMP_MEMORY_DESCRIPTOR>(ptr); locRva.Rva += ndescSize; } } }
public static MINIDUMP_LOCATION_DESCRIPTOR parse_mld(BinaryReader fileBinaryReader) { MINIDUMP_LOCATION_DESCRIPTOR mld = new MINIDUMP_LOCATION_DESCRIPTOR(); mld.Size = Helpers.ReadUInt32(fileBinaryReader); mld.Rva = Helpers.ReadUInt32(fileBinaryReader); return(mld); }
// get a string from a relative address in the dump public string GetStringFromRva(uint rva) { var retstr = string.Empty; if (rva != 0) { var locDesc = new MINIDUMP_LOCATION_DESCRIPTOR() { Rva = rva, DataSize = 1024 }; var locname = MapStream(locDesc); retstr = Marshal.PtrToStringBSTR(locname + 4); // ' skip length } return(retstr); }
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); }
static void Main(string[] args) { try { var dumpFileName = @"c:\lbsymbol\2006.dmp"; using (var rdr = new MiniDumpReader(dumpFileName)) { foreach (MINIDUMP_STREAM_TYPE strmType in Enum.GetValues(typeof(MINIDUMP_STREAM_TYPE))) { var strmDir = rdr.ReadStreamType(strmType); var locStream = strmDir.location; if (locStream.Rva != 0) { var addrStream = rdr.MapStream(locStream); switch (strmType) { case MINIDUMP_STREAM_TYPE.ModuleListStream: var moduleStream = rdr.MapStream(strmDir.location); var NumberOfModules = Marshal.ReadInt32(moduleStream); var ndescSize = (uint)(Marshal.SizeOf <MINIDUMP_MODULE>() - 4); var locRva = new MINIDUMP_LOCATION_DESCRIPTOR() { Rva = (uint)(locStream.Rva + Marshal.SizeOf <uint>()), DataSize = (uint)(ndescSize + 4) }; for (int i = 0; i < NumberOfModules; i++) { var ptr = rdr.MapStream(locRva); var moduleinfo = Marshal.PtrToStructure <MINIDUMP_MODULE>(ptr); var moduleName = rdr.GetStringFromRva(moduleinfo.ModuleNameRva); Console.WriteLine(string.Format(" {0}", moduleName)); locRva.Rva += ndescSize; } break; default: Console.WriteLine( string.Format( "got {0} {1} Sz={2} Addr={3:x8}", strmType, locStream.Rva, locStream.DataSize, addrStream.ToInt32())); break; } } else { Console.WriteLine( string.Format( "zero {0}", strmType )); } } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }
internal MiniDumpLocationDescriptor(MINIDUMP_LOCATION_DESCRIPTOR locationDescriptor) { _locationDescriptor = locationDescriptor; }
// map a section of the dump specified by a location into memory // return the address of the section public IntPtr MapStream(MINIDUMP_LOCATION_DESCRIPTOR loc) { IntPtr retval = IntPtr.Zero; ulong newbaseOffset = (uint)(loc.Rva / AllocationGranularity) * AllocationGranularity; uint mapViewSize = AllocationGranularity * 4; var nLeftover = loc.Rva - newbaseOffset; var fAlreadyMapped = loc.Rva >= _mapCurrentOffset && loc.Rva + loc.DataSize < _mapCurrentOffset + _mappedCurrentSize; if (!fAlreadyMapped) { // try to reuse the same address var preferredAddress = _addrFileMapping; if (_addrFileMapping != IntPtr.Zero) // unmap prior { var res = UnmapViewOfFile(_addrFileMapping); if (!res) { throw new InvalidOperationException("Couldn't unmap view of file"); } } _addrFileMapping = IntPtr.Zero; uint hiPart = (uint)((newbaseOffset >> 32) & uint.MaxValue); uint loPart = (uint)newbaseOffset; if (loc.DataSize + nLeftover > mapViewSize) { mapViewSize = (uint)(loc.DataSize + nLeftover); } if (newbaseOffset + mapViewSize >= _minidumpFileSize) { mapViewSize = Math.Min((uint)(loc.DataSize + nLeftover), (uint)_minidumpFileSize); } while (_addrFileMapping == IntPtr.Zero) { _addrFileMapping = MapViewOfFileEx( _hFileMapping, FILE_MAP_READ, hiPart, loPart, mapViewSize, preferredAddress ); if (_addrFileMapping == IntPtr.Zero) // failure { // if we spec'd a preferred address, that addr might now be in use // so try again with no preferene if (preferredAddress != IntPtr.Zero) { preferredAddress = IntPtr.Zero; // loop } else { var hr = Marshal.GetHRForLastWin32Error(); var ex = Marshal.GetExceptionForHR(hr); throw ex; } } } _mapCurrentOffset = newbaseOffset; _mappedCurrentSize = mapViewSize; } retval = _addrFileMapping + (int)(newbaseOffset - _mapCurrentOffset + nLeftover); return(retval); }