11 changed files with 390 additions and 3 deletions
After Width: | Height: | Size: 3.2 KiB |
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Input; |
||||
|
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ICSharpCode.SharpDevelop.Gui.Pads |
||||
{ |
||||
public sealed class JumpToAddressCommand : 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.KeyUp += (s, ea) => { if (ea.Key == Key.Enter) Run(); }; |
||||
comboBox.IsEditable = true; |
||||
comboBox.Width = 130; |
||||
|
||||
base.OnOwnerChanged(e); |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
if (this.pad != null && this.comboBox != null) { |
||||
pad.JumpToAddress(comboBox.Text); |
||||
} |
||||
base.Run(); |
||||
} |
||||
} |
||||
|
||||
public sealed class RefreshMemoryCommand : AbstractCommand |
||||
{ |
||||
MemoryPad pad; |
||||
|
||||
protected override void OnOwnerChanged(EventArgs e) |
||||
{ |
||||
this.pad = this.Owner as MemoryPad; |
||||
if (this.pad == null) |
||||
return; |
||||
|
||||
base.OnOwnerChanged(e); |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
if (this.pad == null) |
||||
return; |
||||
|
||||
this.pad.Refresh(true); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,169 @@
@@ -0,0 +1,169 @@
|
||||
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
|
||||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Globalization; |
||||
using System.Text; |
||||
using System.Text.RegularExpressions; |
||||
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 |
||||
{ |
||||
public sealed class MemoryPad : DebuggerPad |
||||
{ |
||||
Dictionary<long, int> addressesMapping = new Dictionary<long, int>(); |
||||
ConsoleControl console; |
||||
int addressStep = 16; |
||||
|
||||
Process debuggedProcess; |
||||
|
||||
public MemoryPad() |
||||
{ |
||||
this.console = new ConsoleControl(); |
||||
this.panel.Children.Add(console); |
||||
this.console.Encoding = Encoding.Default; |
||||
RefreshPad(); |
||||
this.console.SetReadonly(); |
||||
} |
||||
|
||||
protected override ToolBar BuildToolBar() |
||||
{ |
||||
return ToolBarService.CreateToolBar(panel, this, "/SharpDevelop/Pads/MemoryPad/ToolBar"); |
||||
} |
||||
|
||||
protected override void SelectProcess(Process process) |
||||
{ |
||||
if (debuggedProcess != null) { |
||||
debuggedProcess.Paused -= OnProcessPaused; |
||||
} |
||||
debuggedProcess = process; |
||||
if (debuggedProcess != null) { |
||||
debuggedProcess.Paused += OnProcessPaused; |
||||
} |
||||
} |
||||
|
||||
public override void RefreshPad() |
||||
{ |
||||
Refresh(); |
||||
base.RefreshPad(); |
||||
} |
||||
|
||||
public void JumpToAddress(string address) |
||||
{ |
||||
try { |
||||
if (address.StartsWith("0x")) |
||||
address = address.Substring(2); |
||||
|
||||
long addr = Int64.Parse(address, NumberStyles.AllowHexSpecifier); |
||||
long mod = addr % addressStep; |
||||
|
||||
int line; |
||||
if (addressesMapping.ContainsKey(addr - mod)) |
||||
line = addressesMapping[addr - mod]; |
||||
else |
||||
line = 1; |
||||
|
||||
console.SelectText(line, 0, 8); |
||||
console.JumpToLine(line); |
||||
} catch (System.Exception ex) { |
||||
#if DEBUG
|
||||
LoggingService.Error(ex.Message); |
||||
#endif
|
||||
} |
||||
} |
||||
|
||||
public void Refresh(bool force = false) |
||||
{ |
||||
if (debuggedProcess == null || debugger.IsProcessRunning) |
||||
return; |
||||
|
||||
if (!force && addressesMapping.Count > 0) |
||||
return; |
||||
|
||||
if (force) { |
||||
addressesMapping.Clear(); |
||||
console.Clear(); |
||||
} |
||||
|
||||
long address; |
||||
byte[] memory = debuggedProcess.ReadProcessMemory(out address); |
||||
|
||||
if (memory == null) |
||||
return; |
||||
|
||||
int index = 0; |
||||
int div = memory.Length / addressStep; |
||||
int mod = memory.Length % addressStep; |
||||
|
||||
while (index < div) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
addressesMapping.Add(address, index + 1); |
||||
// write address
|
||||
sb.Append(address.ToString("X8"));address += addressStep; |
||||
sb.Append(" "); |
||||
|
||||
// write bytes
|
||||
for (int i = 0; i < addressStep; ++i) { |
||||
sb.Append(memory[index * addressStep + i].ToString("X2") + " "); |
||||
} |
||||
// write chars
|
||||
StringBuilder sb1 = new StringBuilder(); |
||||
for (int i = 0; i < addressStep; ++i) { |
||||
sb1.Append(((char)memory[index * addressStep + i]).ToString()); |
||||
} |
||||
string s = sb1.ToString(); |
||||
s = Regex.Replace(s, @"\r\n", string.Empty); |
||||
s = Regex.Replace(s, @"\n", string.Empty); |
||||
s = Regex.Replace(s, @"\r", string.Empty); |
||||
sb.Append(s); |
||||
sb.Append(Environment.NewLine); |
||||
|
||||
// start writing in console
|
||||
console.Append(sb.ToString()); |
||||
|
||||
index++; |
||||
} |
||||
|
||||
if (mod != 0) { |
||||
// write the rest of memory
|
||||
StringBuilder sb = new StringBuilder(); |
||||
addressesMapping.Add(address, index + 1); |
||||
// write address
|
||||
sb.Append(address.ToString("X8")); |
||||
sb.Append(" "); |
||||
|
||||
// write bytes
|
||||
for (int i = 0; i < mod; ++i) { |
||||
sb.Append(memory[index * addressStep + i].ToString("X2") + " "); |
||||
} |
||||
// write chars
|
||||
StringBuilder sb1 = new StringBuilder(); |
||||
for (int i = 0; i < mod; ++i) { |
||||
sb1.Append(((char)memory[index * addressStep + i]).ToString()); |
||||
} |
||||
string s = sb1.ToString(); |
||||
s = Regex.Replace(s, @"\r\n", string.Empty); |
||||
s = Regex.Replace(s, @"\n", string.Empty); |
||||
s = Regex.Replace(s, @"\r", string.Empty); |
||||
sb.Append(s); |
||||
|
||||
sb.Append(Environment.NewLine); |
||||
|
||||
// start writing in console
|
||||
console.Append(sb.ToString()); |
||||
} |
||||
} |
||||
|
||||
private void OnProcessPaused(object sender, ProcessEventArgs e) |
||||
{ |
||||
Refresh(); |
||||
} |
||||
} |
||||
} |
Binary file not shown.
Loading…
Reference in new issue