public Minidump(string crashDump) { if (!File.Exists(crashDump)) { throw new FileNotFoundException(crashDump); } _crashDump = crashDump; FileStream stream = File.Open(crashDump, FileMode.Open, FileAccess.Read, FileShare.Read); // Load header MinidumpHeader header = Read <MinidumpHeader>(stream); if (!header.IsValid) { throw new InvalidDataException($"File '{crashDump}' is not a Minidump."); } _directories = new MinidumpDirectory[header.NumberOfStreams]; stream.Position = header.StreamDirectoryRva; if (!Read(stream, _directories)) { throw new InvalidDataException($"Unable to read directories from minidump '{crashDump} offset 0x{header.StreamDirectoryRva:x}"); } (int systemInfoIndex, int moduleListIndex) = FindImportantStreams(crashDump); // Architecture is the first entry in MINIDUMP_SYSTEM_INFO. We need nothing else out of that struct, // so we only read the first entry. // https://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_system_info Architecture = Read <MinidumpProcessorArchitecture>(stream, _directories[systemInfoIndex].Rva); // Initialize modules. DataTarget will need a module list immediately, so there's no reason to delay // filling in the module list. long rva = _directories[moduleListIndex].Rva; uint count = Read <uint>(stream, rva); rva += sizeof(uint); MinidumpModule[] modules = new MinidumpModule[count]; if (Read(stream, rva, modules)) { Modules = modules.AsImmutableArray(); } else { Modules = ImmutableArray <MinidumpModule> .Empty; } // Read segments async. _memoryTask = GetMemoryReader(); _threadTask = ReadThreadData(stream); }
public Minidump(string crashDump, FileStream stream, CacheOptions cacheOptions) { if (!File.Exists(crashDump)) { throw new FileNotFoundException(crashDump); } _crashDump = crashDump; // Load header MinidumpHeader header = Read <MinidumpHeader>(stream); if (!header.IsValid) { throw new InvalidDataException($"File '{crashDump}' is not a Minidump."); } _directories = new MinidumpDirectory[header.NumberOfStreams]; stream.Position = header.StreamDirectoryRva; if (!Read(stream, _directories)) { throw new InvalidDataException($"Unable to read directories from minidump '{crashDump} offset 0x{header.StreamDirectoryRva:x}"); } (int systemInfoIndex, int moduleListIndex) = FindImportantStreams(crashDump); // Architecture is the first entry in MINIDUMP_SYSTEM_INFO. We need nothing else out of that struct, // so we only read the first entry. // https://docs.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_system_info Architecture = Read <MinidumpProcessorArchitecture>(stream, _directories[systemInfoIndex].Rva); // Initialize modules. DataTarget will need a module list immediately, so there's no reason to delay // filling in the module list. long rva = _directories[moduleListIndex].Rva; uint count = Read <uint>(stream, rva); rva += sizeof(uint); MinidumpModule[] modules = new MinidumpModule[count]; if (Read(stream, rva, modules)) { Modules = modules.AsImmutableArray(); } else { Modules = ImmutableArray <MinidumpModule> .Empty; } // Read segments async. //_nativeMemory = new CachedMemoryReader(pointerSize, dumpPath, cacheSize, CacheTechnology.ArrayPool, _segments.ToImmutableArray()); ImmutableArray <MinidumpSegment> segments = GetSegments(stream); int cacheSize = cacheOptions.MaxDumpCacheSize > int.MaxValue ? int.MaxValue : (int)cacheOptions.MaxDumpCacheSize; bool isTinyDump = new FileInfo(crashDump).Length <= cacheSize; if (isTinyDump) { _file = MemoryMappedFile.CreateFromFile(stream, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.None, leaveOpen: false); MemoryMappedViewStream mmStream = _file.CreateViewStream(0, 0, MemoryMappedFileAccess.Read); MemoryReader = new UncachedMemoryReader(segments, mmStream, PointerSize); } else if (cacheSize < CachedMemoryReader.MinimumCacheSize) { // this will be very slow MemoryReader = new UncachedMemoryReader(segments, stream, PointerSize); } else { CacheTechnology technology = cacheOptions.UseOSMemoryFeatures ? CacheTechnology.AWE : CacheTechnology.ArrayPool; MemoryReader = new CachedMemoryReader(segments, crashDump, stream, cacheSize, technology, PointerSize); } _threadTask = ReadThreadData(stream); }