diff --git a/src/MIDebugEngine/AD7.Impl/AD7Engine.cs b/src/MIDebugEngine/AD7.Impl/AD7Engine.cs
index e204d153e..f3f404244 100755
--- a/src/MIDebugEngine/AD7.Impl/AD7Engine.cs
+++ b/src/MIDebugEngine/AD7.Impl/AD7Engine.cs
@@ -35,7 +35,7 @@ namespace Microsoft.MIDebugEngine
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.Guid("0fc2f352-2fc1-4f80-8736-51cd1ab28f16")]
- sealed public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugEngine3, IDebugProgram3, IDebugEngineProgram2, IDebugMemoryBytes2, IDebugEngine110, IDebugProgramDAP, IDisposable
+ sealed public class AD7Engine : IDebugEngine2, IDebugEngineLaunch2, IDebugEngine3, IDebugProgram3, IDebugEngineProgram2, IDebugMemoryBytes2, IDebugEngine110, IDebugProgramDAP, IDebugMemoryBytesDAP, IDisposable
{
// used to send events to the debugger. Some examples of these events are thread create, exception thrown, module load.
private EngineCallback _engineCallback;
@@ -1138,6 +1138,16 @@ public int WriteAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte[] rgbM
#endregion
+ #region IDebugMemoryBytesDAP
+
+ int IDebugMemoryBytesDAP.CreateMemoryContext(ulong address, out IDebugMemoryContext2 ppResult)
+ {
+ ppResult = new AD7MemoryAddress(this, address, null);
+ return Constants.S_OK;
+ }
+
+ #endregion
+
#region IDebugEngine110
public int SetMainThreadSettingsCallback110(IDebugSettingsCallback110 pCallback)
{
diff --git a/src/Microsoft.VisualStudio.Debugger.Interop.DAP/Microsoft.VisualStudio.Debugger.Interop.DAP.cs b/src/Microsoft.VisualStudio.Debugger.Interop.DAP/Microsoft.VisualStudio.Debugger.Interop.DAP.cs
index ab3e588c7..b433c33aa 100644
--- a/src/Microsoft.VisualStudio.Debugger.Interop.DAP/Microsoft.VisualStudio.Debugger.Interop.DAP.cs
+++ b/src/Microsoft.VisualStudio.Debugger.Interop.DAP/Microsoft.VisualStudio.Debugger.Interop.DAP.cs
@@ -52,4 +52,20 @@ public interface IDebugProgramDAP
/// [PreserveSig]
int GetPointerSize([Out] out int pResult);
}
+
+ ///
+ /// IDebugMemoryBytesDAP for Debug Adapter Protocol
+ ///
+ [ComImport()]
+ [ComVisible(true)]
+ [Guid("CF4FADE1-3252-4680-9E70-8B44CA92DD3F")]
+ [InterfaceType(1)]
+ public interface IDebugMemoryBytesDAP
+ {
+ ///
+ /// This method will create an IDebugMemoryContext from a given address.
+ ///
+ [PreserveSig]
+ int CreateMemoryContext([In] ulong address, [Out, MarshalAs(UnmanagedType.Interface)] out IDebugMemoryContext2 ppResult);
+ }
}
diff --git a/src/OpenDebugAD7/AD7DebugSession.cs b/src/OpenDebugAD7/AD7DebugSession.cs
index c369b04bf..315a70396 100644
--- a/src/OpenDebugAD7/AD7DebugSession.cs
+++ b/src/OpenDebugAD7/AD7DebugSession.cs
@@ -619,7 +619,8 @@ protected override void HandleInitializeRequestAsync(IRequestResponder new ExceptionBreakpointsFilter() { Default = item.@default, Filter = item.filter, Label = item.label }).ToList(),
SupportsClipboardContext = m_engineConfiguration.ClipboardContext,
- SupportsLogPoints = true
+ SupportsLogPoints = true,
+ SupportsReadMemoryRequest = true
};
responder.SetResponse(initializeResponse);
@@ -1371,7 +1372,8 @@ protected override void HandleVariablesRequestAsync(IRequestResponder variablesDictionary = new Dictionary();
for (uint c = 0; c < count; c++)
{
- var variable = m_variableManager.CreateVariable(ref childProperties[c], variableEvaluationData.propertyInfoFlags);
+ string memoryReference = AD7Utils.GetMemoryReferenceFromIDebugProperty(childProperties[c].pProperty);
+ var variable = m_variableManager.CreateVariable(ref childProperties[c], variableEvaluationData.propertyInfoFlags, memoryReference);
int uniqueCounter = 2;
string variableName = variable.Name;
string variableNameFormat = "{0} #{1}";
@@ -1388,8 +1390,9 @@ protected override void HandleVariablesRequestAsync(IRequestResponder responder)
+ {
+ int hr;
+ ReadMemoryArguments rma = responder.Arguments;
+ ErrorBuilder eb = new ErrorBuilder(() => AD7Resources.Error_Scenario_ReadMemory);
+ try
+ {
+ if (string.IsNullOrEmpty(rma.MemoryReference))
+ {
+ throw new ArgumentException("ReadMemoryArguments.MemoryReference is null or empty.");
+ }
+ ulong address;
+ if (rma.MemoryReference.StartsWith("0x", StringComparison.Ordinal))
+ {
+ address = Convert.ToUInt64(rma.MemoryReference.Substring(2), 16);
+ }
+ else
+ {
+ address = Convert.ToUInt64(rma.MemoryReference, 10);
+ }
+
+ if (rma.Offset.HasValue && rma.Offset.Value != 0)
+ {
+ if (rma.Offset < 0)
+ {
+ address += (ulong)rma.Offset.Value;
+ }
+ else
+ {
+ address -= (ulong)-rma.Offset.Value;
+ }
+ }
+
+ hr = ((IDebugMemoryBytesDAP)m_engine).CreateMemoryContext(address, out IDebugMemoryContext2 memoryContext);
+ eb.CheckHR(hr);
+
+ byte[] data = new byte[rma.Count];
+ uint unreadableBytes = 0;
+ uint bytesRead = 0;
+
+ if (rma.Count != 0)
+ {
+ hr = m_program.GetMemoryBytes(out IDebugMemoryBytes2 debugMemoryBytes);
+ eb.CheckHR(hr);
+
+ hr = debugMemoryBytes.ReadAt(memoryContext, (uint)rma.Count, data, out bytesRead, ref unreadableBytes);
+ eb.CheckHR(hr);
+ }
+
+ responder.SetResponse(new ReadMemoryResponse()
+ {
+ Address = string.Format(CultureInfo.InvariantCulture, "0x{0:X}", address),
+ Data = Convert.ToBase64String(data, 0, (int)bytesRead),
+ UnreadableBytes = (int?)unreadableBytes
+ });
+ }
+ catch (Exception e)
+ {
+ responder.SetError(new ProtocolException(e.Message));
+ }
}
#endregion
diff --git a/src/OpenDebugAD7/AD7Resources.Designer.cs b/src/OpenDebugAD7/AD7Resources.Designer.cs
index 10f875757..c8a973fef 100644
--- a/src/OpenDebugAD7/AD7Resources.Designer.cs
+++ b/src/OpenDebugAD7/AD7Resources.Designer.cs
@@ -271,6 +271,15 @@ internal static string Error_Scenario_Launch {
}
}
+ ///
+ /// Looks up a localized string similar to Unable to read memory. {0}.
+ ///
+ internal static string Error_Scenario_ReadMemory {
+ get {
+ return ResourceManager.GetString("Error_Scenario_ReadMemory", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Unable to step in. {0}.
///
diff --git a/src/OpenDebugAD7/AD7Resources.resx b/src/OpenDebugAD7/AD7Resources.resx
index 264016e09..b100bbd55 100644
--- a/src/OpenDebugAD7/AD7Resources.resx
+++ b/src/OpenDebugAD7/AD7Resources.resx
@@ -282,4 +282,7 @@
Failed to get property information.
+
+ Unable to read memory. {0}
+
\ No newline at end of file
diff --git a/src/OpenDebugAD7/AD7Utils.cs b/src/OpenDebugAD7/AD7Utils.cs
index 63931eb21..6933256d1 100644
--- a/src/OpenDebugAD7/AD7Utils.cs
+++ b/src/OpenDebugAD7/AD7Utils.cs
@@ -17,5 +17,22 @@ public static bool IsAnnotatedFrame(ref FRAMEINFO frameInfo)
enum_FRAMEINFO_FLAGS_VALUES flags = unchecked((enum_FRAMEINFO_FLAGS_VALUES)frameInfo.m_dwFlags);
return flags.HasFlag(enum_FRAMEINFO_FLAGS_VALUES.FIFV_ANNOTATEDFRAME);
}
+
+ public static string GetMemoryReferenceFromIDebugProperty(IDebugProperty2 property)
+ {
+ if (property != null && property.GetMemoryContext(out IDebugMemoryContext2 memoryContext) == HRConstants.S_OK)
+ {
+ CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
+ if (memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo) == HRConstants.S_OK)
+ {
+ if (contextInfo[0].dwFields.HasFlag(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS))
+ {
+ return contextInfo[0].bstrAddress;
+ }
+ }
+ }
+
+ return null;
+ }
}
}
diff --git a/src/OpenDebugAD7/VariableManager.cs b/src/OpenDebugAD7/VariableManager.cs
index 7641d4e6b..553ef9e06 100644
--- a/src/OpenDebugAD7/VariableManager.cs
+++ b/src/OpenDebugAD7/VariableManager.cs
@@ -49,10 +49,12 @@ internal Variable CreateVariable(IDebugProperty2 property, enum_DEBUGPROP_INFO_F
DEBUG_PROPERTY_INFO[] propertyInfo = new DEBUG_PROPERTY_INFO[1];
property.GetPropertyInfo(propertyInfoFlags, Constants.EvaluationRadix, Constants.EvaluationTimeout, null, 0, propertyInfo);
- return CreateVariable(ref propertyInfo[0], propertyInfoFlags);
+ string memoryReference = AD7Utils.GetMemoryReferenceFromIDebugProperty(property);
+
+ return CreateVariable(ref propertyInfo[0], propertyInfoFlags, memoryReference);
}
- internal Variable CreateVariable(ref DEBUG_PROPERTY_INFO propertyInfo, enum_DEBUGPROP_INFO_FLAGS propertyInfoFlags)
+ internal Variable CreateVariable(ref DEBUG_PROPERTY_INFO propertyInfo, enum_DEBUGPROP_INFO_FLAGS propertyInfoFlags, string memoryReference)
{
string name = propertyInfo.bstrName;
string val = propertyInfo.bstrValue;
@@ -72,6 +74,7 @@ internal Variable CreateVariable(ref DEBUG_PROPERTY_INFO propertyInfo, enum_DEBU
Type = type,
VariablesReference = handle,
EvaluateName = propertyInfo.bstrFullName,
+ MemoryReference = memoryReference
};
}