/// <summary> /// Scans the Memory64Stream looking for a single descriptor that contains a range of memory. /// </summary> /// <param name="memory64Stream">The Memory64Stream to search.</param> /// <param name="startAddress">Start address of the range being searched for.</param> /// <param name="endAddress">End address of the range being searched for.</param> /// <returns>The offset (relative to the start of the minidump) to start reading from if a descriptor was found, 0 otherwise.</returns> /// <remarks> /// This function searches for memory descriptors that contain the entire range of memory being searched for. If /// the range being searched for spans more than one descriptor <see cref="System.Diagnostics.Debug.Fail(string)"/> will run /// and execution will halt. If a matching range is not found then 0 will be returned. /// </remarks> public static ulong FindMemory64Block(MiniDumpMemory64Stream memory64Stream, ulong startAddress, ulong endAddress) { ulong offsetToReadFrom = memory64Stream.BaseRva; bool matchFound = false; foreach (var memoryDescriptor in memory64Stream.MemoryRanges) { // This method only caters for full blocks of memory at the moment, thus any matching block will be an exact match // to the startAddress/endAddress passed in. if ((startAddress == memoryDescriptor.StartOfMemoryRange) && (endAddress == memoryDescriptor.EndOfMemoryRange)) { // This can be used later for memory ranges that span more than one descriptor. if (endAddress > memoryDescriptor.EndOfMemoryRange) { System.Diagnostics.Debug.Fail($"Found descriptor for {memoryDescriptor.DataSize} bytes starting at {memoryDescriptor.StartOfMemoryRange}, but needed {endAddress - startAddress} bytes."); } // This method only caters for full blocks of memory at the moment, so no need to read within a region. //offsetToReadFrom += (startAddress - memoryDescriptor.StartOfMemoryRange); matchFound = true; break; } offsetToReadFrom += memoryDescriptor.DataSize; } if (matchFound) { return(offsetToReadFrom); } else { return(0); } }
private void CmdDisplayStream(string streamName) { UserControl viewToDisplay = null; int numberOfItems = 0; string nodeText = String.Empty; // Quick fix for duplicated item counts in node text switch (streamName) { case "Summary": nodeText = string.Empty; viewToDisplay = new SummaryView(_miniDumpFile); break; case "Handles": nodeText = "Handles"; MiniDumpHandleDescriptor[] handleData = this._miniDumpFile.ReadHandleData(); numberOfItems = handleData.Length; viewToDisplay = new HandleDataView(handleData); break; case "Modules": nodeText = "Modules"; MiniDumpModule[] moduleData = this._miniDumpFile.ReadModuleList(); numberOfItems = moduleData.Length; viewToDisplay = new ModulesView(moduleData); break; case "Threads": nodeText = "Threads"; MiniDumpThread[] threadData = this._miniDumpFile.ReadThreadList(); numberOfItems = threadData.Length; viewToDisplay = new ThreadListView(threadData); break; case "ThreadInfo": nodeText = "ThreadInfo"; MiniDumpThreadInfo[] threadInfoData = this._miniDumpFile.ReadThreadInfoList(); numberOfItems = threadInfoData.Length; viewToDisplay = new ThreadInfoListView(threadInfoData); break; case "ThreadNames": nodeText = "ThreadNames"; MiniDumpThreadNamesStream threadNamesStream = this._miniDumpFile.ReadThreadNamesStream(); numberOfItems = threadNamesStream.Entries.Count; viewToDisplay = new ThreadNamesView(threadNamesStream); break; case "Memory": nodeText = "Memory"; MiniDumpMemoryDescriptor[] memoryData = this._miniDumpFile.ReadMemoryList(); numberOfItems = memoryData.Length; viewToDisplay = new MemoryListView(memoryData); break; case "Memory64": nodeText = "Memory64"; MiniDumpMemory64Stream memory64Data = this._miniDumpFile.ReadMemory64List(); numberOfItems = memory64Data.MemoryRanges.Length; viewToDisplay = new MemoryList64View(memory64Data.MemoryRanges); break; case "MemoryInfo": nodeText = "MemoryInfo"; MiniDumpMemoryInfoStream memoryInfo = this._miniDumpFile.ReadMemoryInfoList(); numberOfItems = memoryInfo.Entries.Length; viewToDisplay = new MemoryInfoView(memoryInfo, _miniDumpFile); break; case "MiscInfo": nodeText = "MiscInfo"; MiniDumpMiscInfo miscInfo = this._miniDumpFile.ReadMiscInfo(); numberOfItems = 1; viewToDisplay = new MiscInfoView(miscInfo); break; case "SystemInfo": nodeText = "SystemInfo"; MiniDumpSystemInfoStream systemInfo = this._miniDumpFile.ReadSystemInfo(); numberOfItems = 1; viewToDisplay = new SystemInfoView(systemInfo); break; case "Exception": nodeText = "Exception"; MiniDumpExceptionStream exceptionStream = this._miniDumpFile.ReadExceptionStream(); numberOfItems = (exceptionStream == null) ? 0 : 1; viewToDisplay = new ExceptionStreamView(exceptionStream); break; case "UnloadedModules": nodeText = "UnloadedModules"; MiniDumpUnloadedModulesStream unloadedModulesStream = this._miniDumpFile.ReadUnloadedModuleList(); numberOfItems = (int)unloadedModulesStream.NumberOfEntries; viewToDisplay = new UnloadedModulesView(unloadedModulesStream); break; case "SystemMemoryInfo": nodeText = "SystemMemoryInfo"; MiniDumpSystemMemoryInfo systemMemoryInfo = this._miniDumpFile.ReadSystemMemoryInfo(); numberOfItems = 1; viewToDisplay = new SystemMemoryInfoView(systemMemoryInfo); break; case "CommentW": nodeText = "CommentW"; MiniDumpCommentStreamW commentWStream = this._miniDumpFile.ReadCommentStreamW(); numberOfItems = string.IsNullOrEmpty(commentWStream.Comment) ? 0 : 1; viewToDisplay = new CommentStreamWView(commentWStream); break; } if (viewToDisplay != null) { if (nodeText != string.Empty) { treeView1.SelectedNode.Text = nodeText + " (" + numberOfItems + (numberOfItems == 1 ? " item" : " items") + ")"; } if (this.splitContainer1.Panel2.Controls.Count > 0) { this.splitContainer1.Panel2.Controls.RemoveAt(0); } viewToDisplay.Dock = DockStyle.Fill; this.splitContainer1.Panel2.Controls.Add(viewToDisplay); } }