// This method evaluates the expression asynchronously. // This method should return immediately after it has started the expression evaluation. // When the expression is successfully evaluated, an IDebugExpressionEvaluationCompleteEvent2 // must be sent to the IDebugEventCallback2 event callback int IDebugExpression2.EvaluateAsync(enum_EVALFLAGS dwFlags, IDebugEventCallback2 pExprCallback) { _tokenSource = new CancellationTokenSource(); _frame.StackFrame.ExecuteTextAsync(_expression, _tokenSource.Token) .ContinueWith(p => { try { IDebugProperty2 property; if (p.Exception != null && p.Exception.InnerException != null) { property = new AD7EvalErrorProperty(p.Exception.InnerException.Message); } else if (p.IsCanceled) { property = new AD7EvalErrorProperty("Evaluation canceled"); } else if (p.IsFaulted || p.Result == null) { property = new AD7EvalErrorProperty("Error"); } else { property = new AD7Property(_frame, p.Result); } _tokenSource.Token.ThrowIfCancellationRequested(); _frame.Engine.Send( new AD7ExpressionEvaluationCompleteEvent(this, property), AD7ExpressionEvaluationCompleteEvent.IID, _frame.Engine, _frame.Thread); } finally { _tokenSource.Dispose(); _tokenSource = null; } }, _tokenSource.Token); return VSConstants.S_OK; }
// Construct an instance of IEnumDebugPropertyInfo2 for the parameters collection only. private List <DEBUG_PROPERTY_INFO> CreateParameterProperties(uint radix) { var properties = new List <DEBUG_PROPERTY_INFO>(); var parameters = this._stackFrame.Parameters; for (var i = 0; i < parameters.Count; i++) { var property = new AD7Property(this, parameters[i]); properties.Add( property.ConstructDebugPropertyInfo( radix, enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_STANDARD | enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME ) ); } return(properties); }
// Construct an instance of IEnumDebugPropertyInfo2 for the locals collection only. private List <DEBUG_PROPERTY_INFO> CreateLocalProperties(uint radix) { var properties = new List <DEBUG_PROPERTY_INFO>(); IList <NodeEvaluationResult> locals = _stackFrame.Locals; for (int i = 0; i < locals.Count; i++) { var property = new AD7Property(this, locals[i]); properties.Add( property.ConstructDebugPropertyInfo( radix, enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_STANDARD | enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME ) ); } return(properties); }
// This method evaluates the expression asynchronously. // This method should return immediately after it has started the expression evaluation. // When the expression is successfully evaluated, an IDebugExpressionEvaluationCompleteEvent2 // must be sent to the IDebugEventCallback2 event callback int IDebugExpression2.EvaluateAsync(enum_EVALFLAGS dwFlags, IDebugEventCallback2 pExprCallback) { this._tokenSource = new CancellationTokenSource(); this._frame.StackFrame.ExecuteTextAsync(this._expression, this._tokenSource.Token) .ContinueWith(p => { try { IDebugProperty2 property; if (p.Exception != null && p.Exception.InnerException != null) { property = new AD7EvalErrorProperty(p.Exception.InnerException.Message); } else if (p.IsCanceled) { property = new AD7EvalErrorProperty("Evaluation canceled"); } else if (p.IsFaulted || p.Result == null) { property = new AD7EvalErrorProperty("Error"); } else { property = new AD7Property(this._frame, p.Result); } this._tokenSource.Token.ThrowIfCancellationRequested(); this._frame.Engine.Send( new AD7ExpressionEvaluationCompleteEvent(this, property), AD7ExpressionEvaluationCompleteEvent.IID, this._frame.Engine, this._frame.Thread); } finally { this._tokenSource.Dispose(); this._tokenSource = null; } }, this._tokenSource.Token); return(VSConstants.S_OK); }
public AD7Property(AD7StackFrame frame, NodeEvaluationResult evaluationResult, AD7Property parent = null) { _evaluationResult = evaluationResult; _parent = parent; _frame = frame; }
// 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 Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum) { TimeSpan timeout = TimeSpan.FromMilliseconds(dwTimeout); var tokenSource = new CancellationTokenSource(timeout); List<NodeEvaluationResult> children = _evaluationResult.GetChildrenAsync(tokenSource.Token) .WaitAsync(timeout, tokenSource.Token).Result; DEBUG_PROPERTY_INFO[] properties; if (children == null || children.Count == 0) { properties = new[] { new DEBUG_PROPERTY_INFO { dwFields = enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME, bstrValue = "No children" } }; } else { properties = new DEBUG_PROPERTY_INFO[children.Count]; for (int i = 0; i < children.Count; i++) { properties[i] = new AD7Property(_frame, children[i], this).ConstructDebugPropertyInfo(dwRadix, dwFields); } } if (dwFields.HasFlag(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_NAME)) { properties = properties.OrderBy(p => p.bstrName, _comparer).ToArray(); } ppEnum = new AD7PropertyEnum(properties); return VSConstants.S_OK; }
public AD7Property(AD7StackFrame frame, NodeEvaluationResult evaluationResult, AD7Property parent = null) { this._evaluationResult = evaluationResult; this._parent = parent; this._frame = frame; }
// Construct an instance of IEnumDebugPropertyInfo2 for the parameters collection only. private List<DEBUG_PROPERTY_INFO> CreateParameterProperties(uint radix) { var properties = new List<DEBUG_PROPERTY_INFO>(); IList<NodeEvaluationResult> parameters = _stackFrame.Parameters; for (int i = 0; i < parameters.Count; i++) { var property = new AD7Property(this, parameters[i]); properties.Add( property.ConstructDebugPropertyInfo( radix, enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_STANDARD | enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_FULLNAME ) ); } return properties; }
// This method evaluates the expression synchronously. int IDebugExpression2.EvaluateSync(enum_EVALFLAGS dwFlags, uint dwTimeout, IDebugEventCallback2 pExprCallback, out IDebugProperty2 ppResult) { TimeSpan timeout = TimeSpan.FromMilliseconds(dwTimeout); var tokenSource = new CancellationTokenSource(timeout); ppResult = null; NodeEvaluationResult result; try { result = _frame.StackFrame.ExecuteTextAsync(_expression, tokenSource.Token).WaitAsync(timeout, tokenSource.Token).WaitAndUnwrapExceptions(); } catch (DebuggerCommandException ex) { ppResult = new AD7EvalErrorProperty(ex.Message); return VSConstants.S_OK; } catch (OperationCanceledException) { return DebuggerConstants.E_EVALUATE_TIMEOUT; } if (result == null) { return VSConstants.E_FAIL; } ppResult = new AD7Property(_frame, result); return VSConstants.S_OK; }