Cosmos/source2/Debug/Cosmos.Debug.VSDebugEngine/AD7.Impl/AD7Property.cs
AlfaOmega08_cp 030c3ea8ef
2011-02-11 17:28:24 +00:00

198 lines
9.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Debugger.Interop;
namespace Cosmos.Debug.VSDebugEngine
{
// An implementation of IDebugProperty2
// This interface represents a stack frame property, a program document property, or some other property.
// The property is usually the result of an expression evaluation.
//
// The sample engine only supports locals and parameters for functions that have symbols loaded.
class AD7Property : IDebugProperty2
{
private DebugLocalInfo m_variableInformation;
private AD7Process mProcess;
private AD7StackFrame mStackFrame;
public AD7Property(DebugLocalInfo localInfo, AD7Process process, AD7StackFrame stackFrame)
{
m_variableInformation = localInfo;
mProcess = process;
mStackFrame = stackFrame;
}
// Construct a DEBUG_PROPERTY_INFO representing this local or parameter.
public DEBUG_PROPERTY_INFO ConstructDebugPropertyInfo(enum_DEBUGPROP_INFO_FLAGS dwFields)
{
DEBUG_PROPERTY_INFO propertyInfo = new DEBUG_PROPERTY_INFO();
if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME))
{
propertyInfo.bstrFullName = m_variableInformation.Name;
propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME;
}
if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME))
{
propertyInfo.bstrName = m_variableInformation.Name;
propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME;
}
if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE))
{
// todo: add support for types of properties
propertyInfo.bstrType = "System.Byte[]";
propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_TYPE;
}
if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE))
{
StringBuilder sb = new StringBuilder();//m_variableInformation.m_value);
// retrieve property value:
// todo: corect size of data, datatypes, refactor to move to some dedicated class etc
byte[] xData;
if (m_variableInformation.IsLocal)
{
xData = mProcess.mDbgConnector.GetStackData(mStackFrame.mLocalInfos[m_variableInformation.Index].Offset, 4);
}
else
{
xData = mProcess.mDbgConnector.GetStackData(mStackFrame.mArgumentInfos[m_variableInformation.Index].Offset, 4);
}
// for now, dump as hex
sb.Append("0x");
if (xData == null)
{
sb.Append("(xData == null)");
}
else
{
for (int i = xData.Length - 1; i >= 0; i--)
{
sb.Append(xData[i].ToString("X2").ToUpper());
}
}
propertyInfo.bstrValue = sb.ToString();
propertyInfo.dwFields |= enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE;
}
if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ATTRIB))
{
// The sample does not support writing of values displayed in the debugger, so mark them all as read-only.
propertyInfo.dwAttrib = enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_VALUE_READONLY;
//if (this.m_variableInformation.child != null)
{
//propertyInfo.dwAttrib |= DBG_ATTRIB_FLAGS.DBG_ATTRIB_OBJ_IS_EXPANDABLE;
}
}
// If the debugger has asked for the property, or the property has children (meaning it is a pointer in the sample)
// then set the pProperty field so the debugger can call back when the chilren are enumerated.
//if (((dwFields & (uint)enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP) != 0)
//|| (this.m_variableInformation.child != null))
{
//propertyInfo.pProperty = (IDebugProperty2)this;
//propertyInfo.dwFields |= (uint)(DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_PROP);
}
return propertyInfo;
}
#region IDebugProperty2 Members
// Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or fields of a class or struct.
// The sample debugger only supports pointer dereferencing as children. This means there is only ever one child.
public int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref System.Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum)
{
ppEnum = null;
//if (this.m_variableInformation.child != null)
//{
// DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[1];
// properties[0] = (new AD7Property(this.m_variableInformation.child)).ConstructDebugPropertyInfo(dwFields);
// ppEnum = new AD7PropertyEnum(properties);
// return VSConstants.S_OK;
//}
return VSConstants.S_FALSE;
}
// Returns the property that describes the most-derived property of a property
// This is called to support object oriented languages. It allows the debug engine to return an IDebugProperty2 for the most-derived
// object in a hierarchy. This engine does not support this.
public int GetDerivedMostProperty(out IDebugProperty2 ppDerivedMost)
{
throw new Exception("The method or operation is not implemented.");
}
// This method exists for the purpose of retrieving information that does not lend itself to being retrieved by calling the IDebugProperty2::GetPropertyInfo
// method. This includes information about custom viewers, managed type slots and other information.
// The sample engine does not support this.
public int GetExtendedInfo(ref System.Guid guidExtendedInfo, out object pExtendedInfo)
{
throw new Exception("The method or operation is not implemented.");
}
// Returns the memory bytes for a property value.
public int GetMemoryBytes(out IDebugMemoryBytes2 ppMemoryBytes)
{
throw new Exception("The method or operation is not implemented.");
}
// Returns the memory context for a property value.
public int GetMemoryContext(out IDebugMemoryContext2 ppMemory)
{
throw new Exception("The method or operation is not implemented.");
}
// Returns the parent of a property.
// The sample engine does not support obtaining the parent of properties.
public int GetParent(out IDebugProperty2 ppParent)
{
throw new Exception("The method or operation is not implemented.");
}
// Fills in a DEBUG_PROPERTY_INFO structure that describes a property.
public int GetPropertyInfo(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, uint dwTimeout, IDebugReference2[] rgpArgs, uint dwArgCount, DEBUG_PROPERTY_INFO[] pPropertyInfo)
{
pPropertyInfo[0] = new DEBUG_PROPERTY_INFO();
rgpArgs = null;
pPropertyInfo[0] = ConstructDebugPropertyInfo(dwFields);
return VSConstants.S_OK;
}
// Return an IDebugReference2 for this property. An IDebugReference2 can be thought of as a type and an address.
public int GetReference(out IDebugReference2 ppReference)
{
throw new Exception("The method or operation is not implemented.");
}
// Returns the size, in bytes, of the property value.
public int GetSize(out uint pdwSize)
{
throw new Exception("The method or operation is not implemented.");
}
// The debugger will call this when the user tries to edit the property's values
// the sample has set the read-only flag on its properties, so this should not be called.
public int SetValueAsReference(IDebugReference2[] rgpArgs, uint dwArgCount, IDebugReference2 pValue, uint dwTimeout)
{
throw new Exception("The method or operation is not implemented.");
}
// The debugger will call this when the user tries to edit the property's values in one of the debugger windows.
// the sample has set the read-only flag on its properties, so this should not be called.
public int SetValueAsString(string pszValue, uint dwRadix, uint dwTimeout)
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
}
}