From 4405e279c0b1c3ce38dc9aefde307227d1735b49 Mon Sep 17 00:00:00 2001 From: Eusebiu Marcu Date: Mon, 4 Apr 2011 19:23:55 +0300 Subject: [PATCH] add display byte size. --- data/resources/StringResources.resx | 15 +++ .../Debugger.AddIn/Debugger.AddIn.addin | 9 ++ .../Pads/Commands/MemoryPadCommands.cs | 38 ++++++ .../Debugger/Debugger.AddIn/Pads/MemoryPad.cs | 127 +++++++++++++----- .../Debugger.Core/Interop/NativeMethods.cs | 13 +- 5 files changed, 158 insertions(+), 44 deletions(-) diff --git a/data/resources/StringResources.resx b/data/resources/StringResources.resx index c4f3dcf887..f370224778 100644 --- a/data/resources/StringResources.resx +++ b/data/resources/StringResources.resx @@ -5746,6 +5746,21 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension< Previous virtual addresses + + Display bytes size: + + + Reading from {0} to {1} - size {2}. + + + Unable to read at address {0} of size {1}. + + + Not debugging or process is running! + + + No mappings for memory addresses! + Parallel Stacks diff --git a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin index b300cf7f33..ac1aee7b5b 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin +++ b/src/AddIns/Debugger/Debugger.AddIn/Debugger.AddIn.addin @@ -225,6 +225,15 @@ icon="Icons.16x16.Refresh" tooltip="${res:MainWindow.Windows.Debug.MemoryPad.Refresh}" class="ICSharpCode.SharpDevelop.Gui.Pads.RefreshAddressCommand"/> + + + diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs index 58bc7e716d..3b99fcb177 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/Commands/MemoryPadCommands.cs @@ -86,4 +86,42 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads this.pad.MoveToPreviousAddress(); } } + + public sealed class DisplayByteSizeCommand : AbstractComboBoxCommand + { + MemoryPad pad; + ComboBox comboBox; + + protected override void OnOwnerChanged(EventArgs e) + { + this.pad = this.Owner as MemoryPad; + if (this.pad == null) + return; + + comboBox = this.ComboBox as ComboBox; + + if (this.comboBox == null) + return; + + comboBox.SelectionChanged += (s, ea) => { Run(); }; + + comboBox.Items.Add(2); + comboBox.Items.Add(4); + comboBox.Items.Add(8); + comboBox.Text = "2"; + comboBox.Width = 33; + comboBox.IsEditable = false; + + base.OnOwnerChanged(e); + } + + public override void Run() + { + if (this.pad != null && this.comboBox != null) { + pad.DisplayByteSize = Convert.ToByte(this.comboBox.SelectedValue); + pad.Refresh(); + } + base.Run(); + } + } } diff --git a/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs b/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs index a19975fa9b..491bf64f62 100644 --- a/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs +++ b/src/AddIns/Debugger/Debugger.AddIn/Pads/MemoryPad.cs @@ -6,15 +6,12 @@ using System.ComponentModel; using System.Globalization; using System.Text; using System.Text.RegularExpressions; -using System.Threading.Tasks; -using System.Windows; using System.Windows.Controls; using Debugger; using Debugger.Interop; using ICSharpCode.Core; using ICSharpCode.Core.Presentation; -using ICSharpCode.SharpDevelop.Debugging; namespace ICSharpCode.SharpDevelop.Gui.Pads { @@ -22,11 +19,44 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads { int currentAddressIndex; ConsoleControl console; - int addressStep = 16; + int columnsNumber = 16; + byte displayByteSize = 2; + + /// + /// Gets or sets the number of columns in the display + /// + [DefaultValue(16)] + public int ColumnsNumber { + get { return columnsNumber; } + set { + if (value != columnsNumber) { + columnsNumber = value; + } + } + } + + /// + /// Gets or sets the display byte size: 2, 4, 8 + /// + [DefaultValue(2)] + public byte DisplayByteSize { + get { return displayByteSize; } + set { + // check is value is a power of 2 between 1 and 8. + if ((value & (value - 1)) != 0) + return; + if (value <= 1 || value > 8) + return; + + if (displayByteSize != value) { + displayByteSize = value; + } + } + } Process debuggedProcess; List> memoryAddresses = new List>(); - Dictionary addressesMapping = new Dictionary(); + Dictionary addressesMapping = new Dictionary(); public MemoryPad() { @@ -48,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads return; debuggedProcess = process; - memoryAddresses = debuggedProcess.GetMemoryAddresses(); + memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses(); currentAddressIndex = 0; } @@ -66,7 +96,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads long addr = Int64.Parse(address, NumberStyles.AllowHexSpecifier); - memoryAddresses = debuggedProcess.GetMemoryAddresses(); + memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses(); // find index for the address or the near addess currentAddressIndex = memoryAddresses.BinarySearch(addr); if (currentAddressIndex == -1) { @@ -83,16 +113,17 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads return; // find line - long mod = addr % addressStep; + long mod = addr % (columnsNumber * displayByteSize); int line; - string key = (addr - mod).ToString("X8"); + long key = addr - mod; + //int index = addressesMapping.BinarySearch(key); if (addressesMapping.ContainsKey(key)) line = addressesMapping[key]; else line = 1; // jump - console.SelectText(line, 0, 8); + console.SelectText(line + 1, 0, 8); console.JumpToLine(line); } catch (System.Exception ex) { @@ -104,29 +135,31 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads public bool Refresh(bool refreshMemoryAddresses = false) { - console.Clear(); + if (console == null) + return false; + console.Clear(); if (debuggedProcess == null || debugger.IsProcessRunning) { - console.Append("Not debugging or process is running!"); + console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NotDebuggingOrProcessRunning")); return false; } if (currentAddressIndex <= -1) { - console.Append("No mappings for memory addresses!"); + console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings")); currentAddressIndex = -1; return false; } if (refreshMemoryAddresses) - memoryAddresses = debuggedProcess.GetMemoryAddresses(); + memoryAddresses = debuggedProcess.GetVirtualMemoryAddresses(); if (memoryAddresses.Count == 0) { - console.Append("No mappings for memory addresses!"); + console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings")); return false; } if (currentAddressIndex >= memoryAddresses.Count) { - console.Append("No mappings for memory addresses!"); + console.Append(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.NoMappings")); currentAddressIndex = memoryAddresses.Count ; return false; } @@ -146,27 +179,43 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads long size = item.Item2; byte[] memory = debuggedProcess.ReadProcessMemory(address, size); - System.Diagnostics.Debug.Assert(memory != null); + if (memory == null) { + return string.Format(ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.UnableToReadFormat"), address.ToString("X8"), size); + } + + int bytesNr = displayByteSize / 2; + int totalBytesPerRow = columnsNumber * bytesNr; + int numberOfLines = memory.Length / totalBytesPerRow; + int remainingMemory = memory.Length % totalBytesPerRow; - int numberOfLines = memory.Length / addressStep; - int mod = memory.Length % addressStep; - int currentLine = 0; StringBuilder sb = new StringBuilder(); + sb.Append(string.Format( + ResourceService.GetString("MainWindow.Windows.Debug.MemoryPad.ReadingFromFormat"), + address.ToString("X8"), (address + memory.Length).ToString("X8"), memory.Length)); + sb.Append(Environment.NewLine); + + int currentLine = 2; // line in the console + int index = 0; // index in memory arrray of current line - while (currentLine < numberOfLines) { - addressesMapping.Add(address.ToString("X8"), currentLine + 1); + while (index < numberOfLines) { + addressesMapping.Add(address, currentLine); // write address - sb.Append(address.ToString("X8")); address += (long)addressStep; + sb.Append(address.ToString("X8")); address += (long)totalBytesPerRow; sb.Append(" "); + int start = index * totalBytesPerRow; // write bytes - for (int i = 0; i < addressStep; ++i) { - sb.Append(memory[currentLine * addressStep + i].ToString("X2") + " "); + for (int i = 0; i < columnsNumber; ++i) { + for (int j = 0; j < bytesNr; ++j) { + sb.Append(memory[start++].ToString("X2")); + } + sb.Append(" "); } // write chars + start = index * totalBytesPerRow; StringBuilder sb1 = new StringBuilder(); - for (int i = 0; i < addressStep; ++i) { - sb1.Append(((char)memory[currentLine * addressStep + i]).ToString()); + for (int i = 0; i < totalBytesPerRow; ++i) { + sb1.Append(((char)memory[start++]).ToString()); } string s = sb1.ToString(); s = Regex.Replace(s, @"\r\n", string.Empty); @@ -176,23 +225,31 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads sb.Append(Environment.NewLine); currentLine++; + index++; } - if (mod != 0) { + if (remainingMemory != 0) { // write the rest of memory - addressesMapping.Add(address.ToString("X8"), currentLine + 1); + addressesMapping.Add(address, currentLine); + // write address sb.Append(address.ToString("X8")); sb.Append(" "); // write bytes - for (int i = 0; i < mod; ++i) { - sb.Append(memory[currentLine * addressStep + i].ToString("X2") + " "); + int start = index * remainingMemory * bytesNr; + for (int i = 0; i < remainingMemory; ++i) { + for (int j = 0; j < bytesNr; j++) { + sb.Append(memory[start++].ToString("X2")); + } + sb.Append(" "); } + // write chars + start = index * remainingMemory * bytesNr; StringBuilder sb1 = new StringBuilder(); - for (int i = 0; i < mod; ++i) { - sb1.Append(((char)memory[currentLine * addressStep + i]).ToString()); + for (int i = 0; i < remainingMemory * bytesNr; ++i) { + sb1.Append(((char)memory[start++]).ToString()); } string s = sb1.ToString(); s = Regex.Replace(s, @"\r\n", string.Empty); @@ -224,8 +281,8 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads /// /// Source of data. /// Item to search. - /// The nearast index. - internal static int BinarySearch(this List> source, long item1) + /// The nearest index. + internal static int BinarySearch(this List> source, long item1) { // base checks if (source == null) diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs b/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs index 02acbede0e..1c65879a1f 100644 --- a/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs +++ b/src/AddIns/Debugger/Debugger.Core/Interop/NativeMethods.cs @@ -134,7 +134,7 @@ namespace Debugger.Interop [DllImport("kernel32.dll", SetLastError = true)] public static extern void GetSystemInfo(out SYSTEM_INFO lpSystemInfo); - public static List> GetMemoryAddresses(this Process process) + public static List> GetVirtualMemoryAddresses(this Process process) { var result = new List>(); SYSTEM_INFO sysinfo = new SYSTEM_INFO(); @@ -148,16 +148,9 @@ namespace Debugger.Interop while (address < sysinfo.lpMaximumApplicationAddress.ToInt64()) { - if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m))) - break; - try { - byte[] temp = new byte[m.RegionSize.ToInt64()]; - int outSize; - if (!ReadProcessMemory(openedProcess, new IntPtr(address), temp, temp.Length, out outSize)) + if (!VirtualQueryEx(openedProcess, new IntPtr(address), out m, (uint)Marshal.SizeOf(m))) continue; - } catch { - continue; } finally { // next address address = m.BaseAddress.ToInt64() + m.RegionSize.ToInt64(); @@ -188,6 +181,8 @@ namespace Debugger.Interop var proc = System.Diagnostics.Process.GetProcessById((int)process.Id); return process.ReadProcessMemory(proc.MainModule.BaseAddress.ToInt64(), (long)4096); } + } catch { + return null; } finally { if (openedProcess != IntPtr.Zero) CloseHandle(openedProcess);