/// <summary> /// Thread responsible for evaluating expressions asynchronously. /// </summary> public void evaluatingAsync() { VariableInfo vi = VariableInfo.get(exp, m_eventDispatcher, m_frame); AD7Property ppResult = new AD7Property(vi); m_frame.m_engine.Callback.Send(new AD7ExpressionEvaluationCompleteEvent(this, ppResult), AD7ExpressionEvaluationCompleteEvent.IID, m_frame.m_engine, m_frame.m_thread); }
/// <summary> /// Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or /// fields of a class or struct. (http://msdn.microsoft.com/en-us/library/bb161791.aspx) /// </summary> /// <param name="dwFields"> A combination of flags from the DEBUGPROP_INFO_FLAGS enumeration that specifies which fields in /// the enumerated DEBUG_PROPERTY_INFO structures are to be filled in. </param> /// <param name="dwRadix"> Specifies the radix to be used in formatting any numerical information. </param> /// <param name="guidFilter"> GUID of the filter used with the dwAttribFilter and pszNameFilter parameters to select which /// DEBUG_PROPERTY_INFO children are to be enumerated. For example, guidFilterLocals filters for local variables. </param> /// <param name="dwAttribFilter"> A combination of flags from the DBG_ATTRIB_FLAGS enumeration that specifies what type of /// objects to enumerate, for example DBG_ATTRIB_METHOD for all methods that might be children of this property. Used in /// combination with the guidFilter and pszNameFilter parameters. </param> /// <param name="pszNameFilter"> The name of the filter used with the guidFilter and dwAttribFilter parameters to select which /// DEBUG_PROPERTY_INFO children are to be enumerated. For example, setting this parameter to "MyX" filters for all children /// with the name "MyX." </param> /// <param name="dwTimeout"> Specifies the maximum time, in milliseconds, to wait before returning from this method. Use /// INFINITE to wait indefinitely. </param> /// <param name="ppEnum"> Returns an IEnumDebugPropertyInfo2 object containing a list of the child properties. </param> /// <returns> If successful, returns S_OK; otherwise returns S_FALSE. </returns> 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 (_variableInfo != null) { if (_variableInfo._children != null) { if (_variableInfo._children.Count == 0) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. /// Some VS variable names cannot be used by GDB. When that happens, it is added the prefix VsNdK_ to the GDB variable /// name and it is stored in the GDBNames array. At the same time, the VS name is stored in the VSNames array using the /// same index position. This bool variable just indicate if this prefix is used or not. bool hasVsNdK_ = false; string numChildren = AD7StackFrame.m_dispatcher.createVar(_variableInfo._name, ref hasVsNdK_); ArrayList GDBNames = new ArrayList(); ArrayList VSNames = new ArrayList(); if (hasVsNdK_) { _variableInfo._GDBName = "VsNdK_" + _variableInfo._name; GDBNames.Add("VsNdK_" + _variableInfo._name); VSNames.Add(_variableInfo._name); } try // Catch non-numerical data { if (Convert.ToInt32(numChildren) > 0) // If the variable has children evaluate { if (_variableInfo._type.Contains("struct")) if (_variableInfo._type[_variableInfo._type.Length - 1] == '*') _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("[")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); else _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("[")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("*")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "", GDBNames, VSNames, hasVsNdK_, null); } } catch (FormatException e) { } AD7StackFrame.m_dispatcher.deleteVar(_variableInfo._name, hasVsNdK_); } DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[_variableInfo._children.Count]; int i = 0; foreach (VariableInfo child in _variableInfo._children) { VariableInfo.evaluateExpression(child._name, ref child._value, child._GDBName); properties[i] = new AD7Property(child).ConstructDebugPropertyInfo(dwFields); i++; } ppEnum = new AD7PropertyEnum(properties); return VSConstants.S_OK; } } else if (_stackFrame != null) { uint elementsReturned = 0; _stackFrame.CreateLocalsPlusArgsProperties(dwFields, out elementsReturned, out ppEnum); return VSConstants.S_OK; } return VSConstants.S_FALSE; }
/// <summary> /// This method evaluates the expression synchronously. (http://msdn.microsoft.com/en-ca/library/bb146982.aspx) /// </summary> /// <param name="dwFlags"> A combination of flags from the EVALFLAGS enumeration that control expression evaluation. </param> /// <param name="dwTimeout"> Maximum time, in milliseconds, to wait before returning from this method. Use INFINITE to wait /// indefinitely. </param> /// <param name="pExprCallback"> This parameter is always a null value. </param> /// <param name="ppResult"> Returns the IDebugProperty2 object that contains the result of the expression evaluation. </param> /// <returns> VSConstants.S_OK. </returns> int IDebugExpression2.EvaluateSync(enum_EVALFLAGS dwFlags, uint dwTimeout, IDebugEventCallback2 pExprCallback, out IDebugProperty2 ppResult) { VariableInfo vi = VariableInfo.get(exp, m_eventDispatcher, m_frame); ppResult = new AD7Property(vi); m_frame._lastEvaluatedExpression = vi; return VSConstants.S_OK; }
// Construct an instance of IEnumDebugPropertyInfo2 for the parameters collection only. private void CreateParameterProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumObject) { elementsReturned = (uint)_arguments.Count; DEBUG_PROPERTY_INFO[] propInfo = new DEBUG_PROPERTY_INFO[_arguments.Count]; int i = 0; foreach (VariableInfo arg in _arguments) { AD7Property property = new AD7Property(arg); propInfo[i] = property.ConstructDebugPropertyInfo(dwFields); i++; } enumObject = new AD7PropertyInfoEnum(propInfo); }
// Construct an instance of IEnumDebugPropertyInfo2 for the combined locals and parameters. private void CreateLocalsPlusArgsProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumObject) { elementsReturned = 0; int localsLength = 0; if (_locals != null) { localsLength = _locals.Count; elementsReturned += (uint)localsLength; } if (_arguments != null) { elementsReturned += (uint)_arguments.Count; } DEBUG_PROPERTY_INFO[] propInfo = new DEBUG_PROPERTY_INFO[elementsReturned]; if (_locals != null) { int i = 0; foreach(VariableInfo var in _locals) { AD7Property property = new AD7Property(var); propInfo[i] = property.ConstructDebugPropertyInfo(dwFields); i++; } } if (_arguments != null) { int i = 0; foreach (VariableInfo arg in _arguments) { AD7Property property = new AD7Property(arg); propInfo[localsLength + i] = property.ConstructDebugPropertyInfo(dwFields); i++; } } enumObject = new AD7PropertyInfoEnum(propInfo); }
/// <summary> /// Gets a description of the properties associated with a stack frame. /// (http://msdn.microsoft.com/en-us/library/bb144920.aspx) /// </summary> /// <param name="property"> Returns an IDebugProperty2 object that describes the properties of this stack frame. </param> /// <returns> VSConstants.S_OK. </returns> int IDebugStackFrame2.GetDebugProperty(out IDebugProperty2 property) { property = new AD7Property(this); return VSConstants.S_OK; }
// 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 (_variableInfo._children != null) { if (_variableInfo._children.Count == 0) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. bool hasVsNdK_ = false; string numChildren = AD7StackFrame.m_dispatcher.createVar(_variableInfo._name, ref hasVsNdK_); ArrayList GDBNames = new ArrayList(); ArrayList VSNames = new ArrayList(); if (hasVsNdK_) { _variableInfo._GDBName = "VsNdK_" + _variableInfo._name; GDBNames.Add("VsNdK_" + _variableInfo._name); VSNames.Add(_variableInfo._name); } try // Catch non-numerical data { if (Convert.ToInt32(numChildren) > 0) // If the variable has children evaluate { if (_variableInfo._type.Contains("struct")) if (_variableInfo._type[_variableInfo._type.Length - 1] == '*') _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("[")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); else _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("[")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); else if (_variableInfo._type.Contains("*")) _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); else _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "", GDBNames, VSNames, hasVsNdK_, null); } } catch (FormatException e) { } AD7StackFrame.m_dispatcher.deleteVar(_variableInfo._name, hasVsNdK_); } DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[_variableInfo._children.Count]; int i = 0; foreach (VariableInfo child in _variableInfo._children) { VariableInfo.evaluateExpression(child._name, ref child._value, child._GDBName); properties[i] = new AD7Property(child).ConstructDebugPropertyInfo(dwFields); i++; } ppEnum = new AD7PropertyEnum(properties); return VSConstants.S_OK; } return VSConstants.S_FALSE; }
/// <summary> /// Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or /// fields of a class or struct. (http://msdn.microsoft.com/en-us/library/bb161791.aspx) /// </summary> /// <param name="dwFields"> A combination of flags from the DEBUGPROP_INFO_FLAGS enumeration that specifies which fields in /// the enumerated DEBUG_PROPERTY_INFO structures are to be filled in. </param> /// <param name="dwRadix"> Specifies the radix to be used in formatting any numerical information. </param> /// <param name="guidFilter"> GUID of the filter used with the dwAttribFilter and pszNameFilter parameters to select which /// DEBUG_PROPERTY_INFO children are to be enumerated. For example, guidFilterLocals filters for local variables. </param> /// <param name="dwAttribFilter"> A combination of flags from the DBG_ATTRIB_FLAGS enumeration that specifies what type of /// objects to enumerate, for example DBG_ATTRIB_METHOD for all methods that might be children of this property. Used in /// combination with the guidFilter and pszNameFilter parameters. </param> /// <param name="pszNameFilter"> The name of the filter used with the guidFilter and dwAttribFilter parameters to select which /// DEBUG_PROPERTY_INFO children are to be enumerated. For example, setting this parameter to "MyX" filters for all children /// with the name "MyX." </param> /// <param name="dwTimeout"> Specifies the maximum time, in milliseconds, to wait before returning from this method. Use /// INFINITE to wait indefinitely. </param> /// <param name="ppEnum"> Returns an IEnumDebugPropertyInfo2 object containing a list of the child properties. </param> /// <returns> If successful, returns S_OK; otherwise returns S_FALSE. </returns> 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 (_variableInfo != null) { if (_variableInfo._children != null) { if (_variableInfo._children.Count == 0) { // This is an array, struct, union, or pointer. // Create a variable object so we can list this variable's children. /// Some VS variable names cannot be used by GDB. When that happens, it is added the prefix VsNdK_ to the GDB variable /// name and it is stored in the GDBNames array. At the same time, the VS name is stored in the VSNames array using the /// same index position. This bool variable just indicate if this prefix is used or not. bool hasVsNdK_ = false; string numChildren = AD7StackFrame.m_dispatcher.createVar(_variableInfo._name, ref hasVsNdK_); ArrayList GDBNames = new ArrayList(); ArrayList VSNames = new ArrayList(); if (hasVsNdK_) { _variableInfo._GDBName = "VsNdK_" + _variableInfo._name; GDBNames.Add("VsNdK_" + _variableInfo._name); VSNames.Add(_variableInfo._name); } try // Catch non-numerical data { if (Convert.ToInt32(numChildren) > 0) // If the variable has children evaluate { if (_variableInfo._type.Contains("struct")) { if (_variableInfo._type[_variableInfo._type.Length - 1] == '*') { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); } else if (_variableInfo._type.Contains("[")) { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct[]", GDBNames, VSNames, hasVsNdK_, null); } else { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "struct", GDBNames, VSNames, hasVsNdK_, null); } } else if (_variableInfo._type.Contains("[")) { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "[]", GDBNames, VSNames, hasVsNdK_, null); } else if (_variableInfo._type.Contains("*")) { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "*", GDBNames, VSNames, hasVsNdK_, null); } else { _variableInfo.listChildren(AD7StackFrame.m_dispatcher, "", GDBNames, VSNames, hasVsNdK_, null); } } } catch (FormatException e) { } AD7StackFrame.m_dispatcher.deleteVar(_variableInfo._name, hasVsNdK_); } DEBUG_PROPERTY_INFO[] properties = new DEBUG_PROPERTY_INFO[_variableInfo._children.Count]; int i = 0; foreach (VariableInfo child in _variableInfo._children) { VariableInfo.evaluateExpression(child._name, ref child._value, child._GDBName); properties[i] = new AD7Property(child).ConstructDebugPropertyInfo(dwFields); i++; } ppEnum = new AD7PropertyEnum(properties); return(VSConstants.S_OK); } } else if (_stackFrame != null) { uint elementsReturned = 0; _stackFrame.CreateLocalsPlusArgsProperties(dwFields, out elementsReturned, out ppEnum); return(VSConstants.S_OK); } return(VSConstants.S_FALSE); }