diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs index 604e33e76e..ed38b87499 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Control/Process.cs @@ -171,6 +171,31 @@ namespace Debugger } } } + + /// Read the specified amount of memory at the given memory address + /// The content of the memory. The amount of the read memory may be less then requested. + public unsafe byte[] ReadMemory(ulong address, int size) + { + byte[] buffer = new byte[size]; + int readCount; + fixed(byte* pBuffer = buffer) { + readCount = (int)corProcess.ReadMemory(address, (uint)size, new IntPtr(pBuffer)); + } + if (readCount != size) Array.Resize(ref buffer, readCount); + return buffer; + } + + /// Writes the given buffer at the specified memory address + /// The number of bytes written + public unsafe int WriteMemory(ulong address, byte[] buffer) + { + if (buffer.Length == 0) return 0; + int written; + fixed(byte* pBuffer = buffer) { + written = (int)corProcess.WriteMemory(address, (uint)buffer.Length, new IntPtr(pBuffer)); + } + return written; + } } [Serializable] diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugProcess.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugProcess.cs index 32a263c8d3..4fffcab784 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugProcess.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Interop/CorDebug/ICorDebugProcess.cs @@ -55,7 +55,7 @@ namespace Debugger.Interop.CorDebug [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] void ReadMemory([In] ulong address, [In] uint size, [Out] IntPtr buffer, [ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] out uint read); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] - void WriteMemory([In] ulong address, [In] uint size, [In] ref byte buffer, [ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] out uint written); + void WriteMemory([In] ulong address, [In] uint size, [In] IntPtr buffer, [ComAliasName("Debugger.Interop.CorDebug.ULONG_PTR")] out uint written); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] void ClearCurrentException([In] uint threadID); [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs index ee64abce02..90023d8469 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Values/Value.cs @@ -91,6 +91,16 @@ namespace Debugger } } + /// + /// Gets the address in memory where this value is stored + /// + [Debugger.Tests.IgnoreAttribute] + public ulong Address { + get { + return corValue.Address; + } + } + /// Gets value indication whether the value is a reference /// Value types also return true if they are boxed public bool IsReference { diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugProcess.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugProcess.cs index fbd6c41fd9..000d7fd919 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugProcess.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Wrappers/CorDebug/Autogenerated/ICorDebugProcess.cs @@ -1,4 +1,4 @@ -// +// // // // @@ -237,10 +237,10 @@ namespace Debugger.Wrappers.CorDebug return read; } - public uint WriteMemory(ulong address, uint size, ref byte buffer) + public uint WriteMemory(ulong address, uint size, System.IntPtr buffer) { uint written; - this.WrappedObject.WriteMemory(address, size, ref buffer, out written); + this.WrappedObject.WriteMemory(address, size, buffer, out written); return written; } diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj index a848676e8b..93f58590fe 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj +++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Debugger.Tests.csproj @@ -60,6 +60,7 @@ + diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/MemoryReadWrite.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/MemoryReadWrite.cs new file mode 100644 index 0000000000..40b78f4b20 --- /dev/null +++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/TestPrograms/MemoryReadWrite.cs @@ -0,0 +1,85 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace Debugger.Tests.TestPrograms +{ + public class MemoryReadWrite + { + public static void Main() + { + string hello = "Hello"; + string world = " !"; + System.Diagnostics.Debugger.Break(); + System.Diagnostics.Debug.WriteLine(hello + " " + world); + } + } +} + +#if TEST_CODE +namespace Debugger.Tests { + public partial class DebuggerTests + { + [NUnit.Framework.Test] + public void MemoryReadWrite() + { + StartTest("MemoryReadWrite.cs"); + + ulong addrHello = process.SelectedStackFrame.GetLocalVariableValue("hello").Address; + ulong addrWorld = process.SelectedStackFrame.GetLocalVariableValue("world").Address; + + addrHello = DeRef(process.ReadMemory(addrHello, 4)); + addrWorld = DeRef(process.ReadMemory(addrWorld, 4)); + + byte[] hello = process.ReadMemory(addrHello, 22); + byte[] world = process.ReadMemory(addrWorld, 24); + + ObjectDump("hello", ToHex(hello)); + ObjectDump("world", ToHex(world)); + + process.WriteMemory(addrWorld + 12, new byte[] {0x77, 0x0, 0x6F, 0x0, 0x72, 0x0, 0x6C, 0x0, 0x64, 0x0}); + + EndTest(); + } + + ulong DeRef(byte[] ptr) + { + return (ulong)(ptr[0] + (ptr[1] << 8) + (ptr[2] << 16) + (ptr[3] << 24)); + } + + string ToHex(byte[] buffer) + { + string hex = ""; + foreach(byte b in buffer) { + hex += b.ToString("X") + " "; + } + return hex; + } + } +} +#endif + +#if EXPECTED_OUTPUT + + + + + mscorlib.dll (No symbols) + MemoryReadWrite.exe (Has symbols) + System.dll (No symbols) + Break MemoryReadWrite.cs:18,4-18,40 + EC 8 33 79 6 0 0 0 5 0 0 0 48 0 65 0 6C 0 6C 0 6F 0 + EC 8 33 79 7 0 0 0 6 0 0 0 20 0 20 0 20 0 20 0 20 0 21 0 + System.Configuration.dll (No symbols) + System.Xml.dll (No symbols) + Hello world!\r\n + + + +#endif // EXPECTED_OUTPUT \ No newline at end of file