//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public DebuggeeStackFrame(DebugEngine engine, DebuggeeThread thread, string frameName) { m_debugEngine = engine; m_thread = thread; m_codeContext = null; m_documentContext = null; m_property = new DebuggeeProperty(engine, this, frameName, string.Empty); m_stackRegisters = new ConcurrentDictionary <string, DebuggeeProperty> (); m_stackArguments = new ConcurrentDictionary <string, DebuggeeProperty> (); m_stackLocals = new ConcurrentDictionary <string, DebuggeeProperty> (); m_customExpressions = new ConcurrentDictionary <string, DebuggeeProperty> (); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public DebuggeeProperty(DebugEngine engine, DebuggeeStackFrame stackFrame, string expression, string value) { m_debugEngine = engine; m_stackFrame = stackFrame; if (string.IsNullOrEmpty(expression)) { throw new ArgumentNullException(nameof(expression)); } m_expression = expression; m_value = value; m_parent = null; m_children = new List <DebuggeeProperty> (); // // Compound parental expressions to evaluate this property's full identifier. // StringBuilder expressionBuilder = new StringBuilder(2048); DebuggeeProperty parent = m_parent; while (parent != null) { expressionBuilder.Append(parent.m_expression + "."); parent = parent.m_parent; } expressionBuilder.Append(m_expression); m_fullExpression = expressionBuilder.ToString(); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public DebuggeeProperty EvaluateCustomExpression(enum_EVALFLAGS evaluateFlags, string expression, uint radix) { // // Evaluates a custom property lookup, and registers a new entry for this expression if one can't be found. // LoggingUtils.PrintFunction(); DebuggeeProperty property = null; try { if (m_stackRegisters.TryGetValue(expression, out property)) { return(property); } if (m_stackArguments.TryGetValue(expression, out property)) { return(property); } if (m_stackLocals.TryGetValue(expression, out property)) { return(property); } if (m_customExpressions.TryGetValue(expression, out property)) { return(property); } // // Check if this expression has already been queried via a child property. // // TODO. // // Couldn't find a pre-registered matching property for this expression, creating a new custom one. // MiVariable customExpressionVariable = m_debugger.VariableManager.CreateVariableFromExpression(this, expression); if (customExpressionVariable != null) { property = m_debugger.VariableManager.CreatePropertyFromVariable(this, customExpressionVariable); if (property != null) { m_customExpressions.TryAdd(expression, property); LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property })); } } } catch (Exception e) { LoggingUtils.HandleException(e); } return(property); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugProperty2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public virtual int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum) { // // Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or fields of a class or struct. // LoggingUtils.PrintFunction(); try { List <DEBUG_PROPERTY_INFO> childPropertyInfo = new List <DEBUG_PROPERTY_INFO> (); List <DebuggeeProperty> childRegisterProperties = new List <DebuggeeProperty> (); foreach (DebuggeeProperty child in m_children) { bool displayProperty = false; DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1]; LoggingUtils.RequireOk(child.GetPropertyInfo(dwFields, dwRadix, dwTimeout, null, 0, infoArray)); if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) || (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters)) { if ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_STORAGE_REGISTER) != 0) { childRegisterProperties.Add(child); } } else if ((guidFilter == DebuggeeProperty.Filters.guidFilterArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs)) { displayProperty |= ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_DATA) != 0); } else if ((guidFilter == DebuggeeProperty.Filters.guidFilterAllLocals) || (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocals) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs)) { displayProperty |= ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_DATA) != 0); } else { displayProperty = true; } /*if ((infoArray [0].dwAttrib & dwAttribFilter) != 0) * { * displayProperty = false; * }*/ if (displayProperty) { childPropertyInfo.Add(infoArray [0]); } } if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) || (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters)) { // // // Registers must be specified in a collection/list as children of a 'CPU' property. // // Other types documented: https://msdn.microsoft.com/en-us/library/aa290860(v=vs.71).aspx // DebuggeeProperty registersProperty = new DebuggeeProperty(m_debugEngine, m_stackFrame, "CPU", string.Empty); LoggingUtils.RequireOk(registersProperty.AddChildren(childRegisterProperties.ToArray())); DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1]; LoggingUtils.RequireOk(registersProperty.GetPropertyInfo(dwFields, dwRadix, dwTimeout, null, 0, infoArray)); childPropertyInfo.Add(infoArray [0]); } ppEnum = new DebuggeeProperty.Enumerator(childPropertyInfo); return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); ppEnum = null; return(Constants.E_FAIL); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public DebuggeeProperty(DebuggeeProperty parent, string expression) : this(parent.m_debugEngine, parent.m_stackFrame, expression, string.Empty) { m_parent = parent; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #region IDebugStackFrame2 Members //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public virtual int EnumProperties(enum_DEBUGPROP_INFO_FLAGS requestedFields, uint radix, ref Guid guidFilter, uint timeout, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumDebugProperty) { // // Creates an enumerator for properties associated with the stack frame, such as local variables. // LoggingUtils.PrintFunction(); try { uint numEnumeratedProperties; IEnumDebugPropertyInfo2 enumeratedProperties; LoggingUtils.RequireOk(m_property.EnumChildren(requestedFields, radix, ref guidFilter, enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_ALL, string.Empty, timeout, out enumeratedProperties)); LoggingUtils.RequireOk(enumeratedProperties.GetCount(out numEnumeratedProperties)); elementsReturned = numEnumeratedProperties; enumDebugProperty = enumeratedProperties; #if false //List<DEBUG_PROPERTY_INFO> filteredProperties; if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) || (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters)) { // // Registers must be specified in a collection/list as children of a 'CPU' property. // DEBUG_PROPERTY_INFO [] debugProperties = new DEBUG_PROPERTY_INFO [numEnumeratedProperties]; LoggingUtils.RequireOk(enumeratedProperties.Next(numEnumeratedProperties, debugProperties, out numEnumeratedProperties)); DebuggeeProperty registersProperty = new DebuggeeProperty(m_debugEngine, this, "CPU", string.Empty); for (uint i = 0; i < numEnumeratedProperties; ++i) { DebuggeeProperty register; if (m_stackRegisters.TryGetValue(debugProperties [i].bstrName, out register)) { registersProperty.AddChildren(new DebuggeeProperty [] { register }); } } DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1]; LoggingUtils.RequireOk(registersProperty.GetPropertyInfo(requestedFields, radix, timeout, null, 0, infoArray)); elementsReturned = (uint)infoArray.Length; enumDebugProperty = new DebuggeeProperty.Enumerator(infoArray); } /*DEBUG_PROPERTY_INFO [] debugProperties = new DEBUG_PROPERTY_INFO [numProperties]; * * LoggingUtils.RequireOk (enumeratedProperties.Next (numProperties, debugProperties, out numProperties)); * * if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) || (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters)) * { * // * // Registers must be specified in a collection/list as children of a 'CPU' property. * // * * DebuggeeProperty registersProperty = new DebuggeeProperty (m_debugEngine, this, "CPU", string.Empty); * * for (uint i = 0; i < numProperties; ++i) * { * DebuggeeProperty register; * * if (m_stackRegisters.TryGetValue (debugProperties [i].bstrName, out register)) * { * registersProperty.AddChildren (new DebuggeeProperty [] { register }); * } * } * * DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1]; * * LoggingUtils.RequireOk (registersProperty.GetPropertyInfo (requestedFields, radix, timeout, null, 0, infoArray)); * * filteredProperties = new List<DEBUG_PROPERTY_INFO> (1); * * filteredProperties.Add (infoArray [0]); * } * else * { * filteredProperties = new List<DEBUG_PROPERTY_INFO> ((int)numProperties); * * for (uint i = 0; i < numProperties; ++i) * { * // * // Determine whether this property should be filtered in/out. * // * * bool displayProperty = false; * * DEBUG_PROPERTY_INFO prop = debugProperties [i]; * * if ((guidFilter == DebuggeeProperty.Filters.guidFilterAllLocals) || (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs)) || { || displayProperty |= true; || } || || if ((guidFilter == DebuggeeProperty.Filters.guidFilterArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs)) || { || displayProperty |= m_stackArguments.ContainsKey (prop.bstrName); || } || || if ((guidFilter == DebuggeeProperty.Filters.guidFilterAllLocals) || (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocals) || (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs)) || { || displayProperty |= m_stackLocals.ContainsKey (prop.bstrName); || } || || if (displayProperty) || { || filteredProperties.Add (prop); || } ||} ||}*/ #endif return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); elementsReturned = 0; enumDebugProperty = null; return(Constants.E_FAIL); } }