示例#1
0
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     if (formatSpecifiers == null)
     {
         formatSpecifiers = Formatter.NoFormatSpecifiers;
     }
     if (resultFullName != null)
     {
         ReadOnlyCollection<string> otherSpecifiers;
         resultFullName = FullNameProvider.GetClrExpressionAndFormatSpecifiers(inspectionContext, resultFullName, out otherSpecifiers);
         foreach (var formatSpecifier in otherSpecifiers)
         {
             formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, formatSpecifier);
         }
     }
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     wl.ContinueWith(
         () => GetRootResultAndContinue(
             value,
             wl,
             declaredType,
             declaredTypeInfo,
             inspectionContext,
             resultName,
             resultFullName,
             formatSpecifiers,
             result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result)))));
 }
 /// <summary>
 /// This method is called by the debug engine to get the text representation of the return
 /// value of a stack frame.
 /// </summary>
 /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
 /// to be used during compilation. It also contains the InspectionSession.  The inspection
 /// session is the object that provides lifetime management for our objects.  When the user
 /// steps or continues the process, the debug engine will dispose of the inspection session</param>
 /// <param name="workList">The current work list.  This is used to batch asynchronous
 /// work items.  If any asynchronous calls are needed later, this is the work list to pass
 /// to the asynchronous call.  It's not needed in our case.</param>
 /// <param name="frame">The frame to get the text representation of the return value for</param>
 /// <param name="completionRoutine">Completion routine to call when work is completed</param>
 void IDkmLanguageFrameDecoder.GetFrameReturnType(
     DkmInspectionContext inspectionContext,
     DkmWorkList workList,
     DkmStackWalkFrame frame,
     DkmCompletionRoutine<DkmGetFrameReturnTypeAsyncResult> completionRoutine)
 {
     string name = TryGetFrameReturnTypeHelper(inspectionContext, frame) ?? "<Unknown>";
     completionRoutine(new DkmGetFrameReturnTypeAsyncResult(name));
 }
示例#3
0
 public void GetChildren(DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     InspectionContext.InspectionSession.InvokeResultProvider(
         MethodId.GetChildren,
         r =>
         {
             r.GetChildren(this, workList, initialRequestSize, inspectionContext, completionRoutine);
             return (object)null;
         });
 }
 /// <summary>
 /// This method is called by the debug engine to get the text representation of a stack
 /// frame.
 /// </summary>
 /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
 /// to be used during compilation. It also contains the InspectionSession.  The inspection
 /// session is the object that provides lifetime management for our objects.  When the user
 /// steps or continues the process, the debug engine will dispose of the inspection session</param>
 /// <param name="workList">The current work list.  This is used to batch asynchronous
 /// work items.  If any asynchronous calls are needed later, this is the work list to pass
 /// to the asynchronous call.  It's not needed in our case.</param>
 /// <param name="frame">The frame to get the text representation for</param>
 /// <param name="argumentFlags">Option flags to change the way we format frames</param>
 /// <param name="completionRoutine">Completion routine to call when work is completed</param>
 void IDkmLanguageFrameDecoder.GetFrameName(
     DkmInspectionContext inspectionContext,
     DkmWorkList workList,
     DkmStackWalkFrame frame,
     DkmVariableInfoFlags argumentFlags,
     DkmCompletionRoutine<DkmGetFrameNameAsyncResult> completionRoutine)
 {
     string name = TryGetFrameNameHelper(inspectionContext, frame, argumentFlags) ?? "<Unknown Method>";
     completionRoutine(new DkmGetFrameNameAsyncResult(name));
 }
 public void GetItems(DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     InspectionContext.InspectionSession.InvokeResultProvider(
         MethodId.GetItems,
         r =>
         {
             r.GetItems(this, workList, startIndex, count, completionRoutine);
             return (object)null;
         });
 }
示例#6
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            completionRoutine(GetChildren(inspectionContext, evaluationResult, dataItem, initialRequestSize));
        }
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     // TODO: Use full name
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     GetRootResultAndContinue(
         value,
         wl,
         declaredType,
         declaredTypeInfo,
         inspectionContext,
         resultName,
         result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result))));
     wl.Execute();
 }
示例#8
0
        public void GetFrameLocals(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmGetFrameLocalsAsyncResult> completionRoutine) {
            var pythonFrame = PyFrameObject.TryCreate(stackFrame);
            if (pythonFrame == null) {
                Debug.Fail("Non-Python frame passed to GetFrameLocals.");
                throw new NotSupportedException();
            }

            var cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
            var evalResults = new List<DkmEvaluationResult>();

            var f_code = pythonFrame.f_code.Read();
            var f_localsplus = pythonFrame.f_localsplus;

            // Process cellvars and freevars first, because function arguments can appear in both cellvars and varnames if the argument is captured by a closure,
            // in which case we want to use the cellvar because the regular var slot will then be unused by Python (and in Python 3.4+, nulled out).
            var namesSeen = new HashSet<string>();
            var cellNames = f_code.co_cellvars.Read().ReadElements().Concat(f_code.co_freevars.Read().ReadElements());
            var cellSlots = f_localsplus.Skip(f_code.co_nlocals.Read());
            foreach (var pair in cellNames.Zip(cellSlots, (nameObj, cellSlot) => new { nameObj, cellSlot = cellSlot })) {
                var nameObj = pair.nameObj;
                var cellSlot = pair.cellSlot;

                var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                if (name == null) {
                    continue;
                }
                namesSeen.Add(name);

                if (cellSlot.IsNull) {
                    continue;
                }

                var cell = cellSlot.Read() as PyCellObject;
                if (cell == null) {
                    continue;
                }

                var localPtr = cell.ob_ref;
                if (localPtr.IsNull) {
                    continue;
                }

                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(localPtr, name), cppEval);
                evalResults.Add(evalResult);
            }

            PyTupleObject co_varnames = f_code.co_varnames.Read();
            foreach (var pair in co_varnames.ReadElements().Zip(f_localsplus, (nameObj, varSlot) => new { nameObj, cellSlot = varSlot })) {
                var nameObj = pair.nameObj;
                var varSlot = pair.cellSlot;

                var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                if (name == null) {
                    continue;
                }

                // Check for function argument that was promoted to a cell.
                if (!namesSeen.Add(name)) {
                    continue;
                }

                if (varSlot.IsNull) {
                    continue;
                }

                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(varSlot, name), cppEval);
                evalResults.Add(evalResult);
            }

            var globals = pythonFrame.f_globals.TryRead();
            if (globals != null) {
                var globalsEvalResult = new GlobalsEvaluationResult { Globals = globals };
                DkmEvaluationResult evalResult = DkmSuccessEvaluationResult.Create(
                    inspectionContext, stackFrame, "[Globals]", null,
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    null, null, null,
                    DkmEvaluationResultCategory.Property,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    null, null, null, globalsEvalResult);

                // If it is a top-level module frame, show globals inline; otherwise, show them under the [Globals] node.
                if (f_code.co_name.Read().ToStringOrNull() == "<module>") {
                    evalResults.AddRange(globalsEvalResult.GetChildren(this, evalResult, inspectionContext));
                } else {
                    evalResults.Add(evalResult);

                    // Show any globals that are directly referenced by the function inline even in local frames.
                    var globalVars = (from pair in globals.ReadElements()
                                      let nameObj = pair.Key as IPyBaseStringObject
                                      where nameObj != null
                                      select new { Name = nameObj.ToString(), Value = pair.Value }
                                     ).ToLookup(v => v.Name, v => v.Value);

                    PyTupleObject co_names = f_code.co_names.Read();
                    foreach (var nameObj in co_names.ReadElements()) {
                        var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                        if (name == null) {
                            continue;
                        }

                        // If this is a used name but it was not in varnames or freevars, it is a directly referenced global.
                        if (!namesSeen.Add(name)) {
                            continue;
                        }

                        var varSlot = globalVars[name].FirstOrDefault();
                        if (varSlot.Process != null) {
                            evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(varSlot, name), cppEval);
                            evalResults.Add(evalResult);
                        }
                    }
                }
            }

            var enumContext = DkmEvaluationResultEnumContext.Create(evalResults.Count, stackFrame, inspectionContext,
                new EvaluationResults { Results = evalResults.OrderBy(er => er.Name) });
            completionRoutine(new DkmGetFrameLocalsAsyncResult(enumContext));
        }
示例#9
0
 public void GetChildren(DkmEvaluationResult result, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) {
     CppEvaluationResult.GetChildren(workList, initialRequestSize, CppEvaluationResult.InspectionContext, (cppResult) => {
         completionRoutine(cppResult);
     });
 }
示例#10
0
        /// <remarks>
        /// Very simple expression evaluation (may not support all syntax supported by Concord).
        /// </remarks>
        public void EvaluateDebuggerDisplayString(DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string formatString, DkmCompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine)
        {
            Debug.Assert(!this.IsNull, "Not supported by VIL");

            if (inspectionContext == null)
            {
                throw new ArgumentNullException(nameof(inspectionContext));
            }

            var pooled = PooledStringBuilder.GetInstance();
            var builder = pooled.Builder;

            int openPos = -1;
            int length = formatString.Length;
            for (int i = 0; i < length; i++)
            {
                char ch = formatString[i];
                if (ch == '{')
                {
                    if (openPos >= 0)
                    {
                        throw new ArgumentException(string.Format("Nested braces in '{0}'", formatString));
                    }
                    openPos = i;
                }
                else if (ch == '}')
                {
                    if (openPos < 0)
                    {
                        throw new ArgumentException(string.Format("Unmatched closing brace in '{0}'", formatString));
                    }

                    string name = formatString.Substring(openPos + 1, i - openPos - 1);
                    openPos = -1;

                    var formatSpecifiers = Formatter.NoFormatSpecifiers;
                    int commaIndex = name.IndexOf(',');
                    if (commaIndex >= 0)
                    {
                        var rawFormatSpecifiers = name.Substring(commaIndex + 1).Split(',');
                        var trimmedFormatSpecifiers = ArrayBuilder<string>.GetInstance(rawFormatSpecifiers.Length);
                        trimmedFormatSpecifiers.AddRange(rawFormatSpecifiers.Select(fs => fs.Trim()));
                        formatSpecifiers = trimmedFormatSpecifiers.ToImmutableAndFree();
                        foreach (var formatSpecifier in formatSpecifiers)
                        {
                            if (formatSpecifier == "nq")
                            {
                                inspectionContext = new DkmInspectionContext(inspectionContext.InspectionSession, inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoQuotes, inspectionContext.Radix, inspectionContext.RuntimeInstance);
                            }
                            // If we need to support additional format specifiers, add them here...
                        }

                        name = name.Substring(0, commaIndex);
                    }

                    var type = ((TypeImpl)this.Type.GetLmrType()).Type;
                    const System.Reflection.BindingFlags bindingFlags =
                        System.Reflection.BindingFlags.Public |
                        System.Reflection.BindingFlags.NonPublic |
                        System.Reflection.BindingFlags.Instance |
                        System.Reflection.BindingFlags.Static;

                    DkmClrValue exprValue;
                    var appDomain = this.Type.AppDomain;

                    var field = type.GetField(name, bindingFlags);
                    if (field != null)
                    {
                        var fieldValue = field.GetValue(RawValue);
                        exprValue = new DkmClrValue(
                            fieldValue,
                            fieldValue,
                            DkmClrType.Create(appDomain, (TypeImpl)((fieldValue == null) ? field.FieldType : fieldValue.GetType())),
                            alias: null,
                            evalFlags: GetEvaluationResultFlags(fieldValue),
                            valueFlags: DkmClrValueFlags.None);
                    }
                    else
                    {
                        var property = type.GetProperty(name, bindingFlags);
                        if (property != null)
                        {
                            var propertyValue = property.GetValue(RawValue);
                            exprValue = new DkmClrValue(
                                propertyValue,
                                propertyValue,
                                DkmClrType.Create(appDomain, (TypeImpl)((propertyValue == null) ? property.PropertyType : propertyValue.GetType())),
                                alias: null,
                                evalFlags: GetEvaluationResultFlags(propertyValue),
                                valueFlags: DkmClrValueFlags.None);
                        }
                        else
                        {
                            var openParenIndex = name.IndexOf('(');
                            if (openParenIndex >= 0)
                            {
                                name = name.Substring(0, openParenIndex);
                            }

                            var method = type.GetMethod(name, bindingFlags);
                            // The real implementation requires parens on method invocations, so
                            // we'll return error if there wasn't at least an open paren...
                            if ((openParenIndex >= 0) && method != null)
                            {
                                var methodValue = method.Invoke(RawValue, new object[] { });
                                exprValue = new DkmClrValue(
                                    methodValue,
                                    methodValue,
                                    DkmClrType.Create(appDomain, (TypeImpl)((methodValue == null) ? method.ReturnType : methodValue.GetType())),
                                    alias: null,
                                    evalFlags: GetEvaluationResultFlags(methodValue),
                                    valueFlags: DkmClrValueFlags.None);
                            }
                            else
                            {
                                var stringValue = "Problem evaluating expression";
                                var stringType = DkmClrType.Create(appDomain, (TypeImpl)typeof(string));
                                exprValue = new DkmClrValue(
                                    stringValue,
                                    stringValue,
                                    stringType,
                                    alias: null,
                                    evalFlags: DkmEvaluationResultFlags.None,
                                    valueFlags: DkmClrValueFlags.Error);
                            }
                        }
                    }

                    builder.Append(exprValue.GetValueString(inspectionContext, formatSpecifiers)); // Re-enter the formatter.
                }
                else if (openPos < 0)
                {
                    builder.Append(ch);
                }
            }

            if (openPos >= 0)
            {
                throw new ArgumentException(string.Format("Unmatched open brace in '{0}'", formatString));
            }

            workList.AddWork(() => completionRoutine(new DkmEvaluateDebuggerDisplayStringAsyncResult(pooled.ToStringAndFree())));
        }
示例#11
0
 private void GetChild(
     DkmEvaluationResult parent,
     WorkList workList,
     EvalResult row,
     DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     var inspectionContext = row.InspectionContext;
     if ((row.Kind != ExpansionKind.Default) || (row.Value == null))
     {
         CreateEvaluationResultAndContinue(
             row,
             workList,
             row.InspectionContext,
             parent.StackFrame,
             child => completionRoutine(new DkmEvaluationAsyncResult(child)));
     }
     else
     {
         var typeDeclaringMember = row.TypeDeclaringMemberAndInfo;
         var name = (typeDeclaringMember.Type == null) ?
             row.Name :
             GetQualifiedMemberName(row.InspectionContext, typeDeclaringMember, row.Name, FullNameProvider);
         row.Value.GetResult(
             workList.InnerWorkList,
             row.DeclaredTypeAndInfo.ClrType,
             row.DeclaredTypeAndInfo.Info,
             row.InspectionContext,
             Formatter.NoFormatSpecifiers,
             name,
             row.FullName,
             result => workList.ContinueWith(() => completionRoutine(result)));
     }
 }
 public virtual void GetItems(DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     throw new NotImplementedException();
 }
示例#13
0
        private void EvaluateExpressionViaInterpreter(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
            var thread = stackFrame.Thread;
            var process = thread.Process;

            if (_evalLoopThreadId.Read() != (ulong)thread.SystemPart.Id) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text,
                    "Arbitrary Python expressions can only be evaluated on a thread which is stopped in Python code at a breakpoint or " +
                    "after a step-in or a step-over operation. Only expressions involving global and local variables, object field access, " +
                    "and indexing of built-in collection types with literals can be evaluated in the current context.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            var pythonFrame = PyFrameObject.TryCreate(stackFrame);
            if (pythonFrame == null) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Could not obtain a Python frame object for the current frame.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            byte[] input = Encoding.UTF8.GetBytes(expression.Text + "\0");
            if (input.Length > ExpressionEvaluationBufferSize) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Expression is too long.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            _evalLoopFrame.Write(pythonFrame.Address);
            process.WriteMemory(_evalLoopInput.Address, input);

            bool timedOut;
            using (_evalCompleteEvent = new AutoResetEvent(false)) {
                thread.BeginFuncEvalExecution(DkmFuncEvalFlags.None);
                timedOut = !_evalCompleteEvent.WaitOne(ExpressionEvaluationTimeout);
                _evalCompleteEvent = null;
            }

            if (timedOut) {
                new RemoteComponent.AbortingEvalExecutionRequest().SendLower(process);

                // We need to stop the process before we can report end of func eval completion
                using (_evalAbortedEvent = new AutoResetEvent(false)) {
                    process.AsyncBreak(false);

                    if (!_evalAbortedEvent.WaitOne(20000)) {
                        // This is a catastrophic error, since we can't report func eval completion unless we can stop the process,
                        // and VS will hang until we do report completion. At this point we can only kill the debuggee so that the
                        // VS at least gets back to a reasonable state.
                        _evalAbortedEvent = null;
                        process.Terminate(1);

                        completionRoutine(DkmEvaluateExpressionAsyncResult.CreateErrorResult(new Exception("Couldn't abort a failed expression evaluation.")));
                        return;
                    }

                    _evalAbortedEvent = null;
                }

                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Evaluation timed out.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            ulong objPtr = _evalLoopResult.Read();
            var obj = PyObject.FromAddress(process, objPtr);
            var exc_type = PyObject.FromAddress(process, _evalLoopExcType.Read());
            var exc_value = PyObject.FromAddress(process, _evalLoopExcValue.Read());
            var exc_str = (PyObject.FromAddress(process, _evalLoopExcStr.Read()) as IPyBaseStringObject).ToStringOrNull();
            var sehCode = _evalLoopSEHCode.Read();

            if (obj != null) {
                var cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
                var pyEvalResult =  new PythonEvaluationResult(obj, expression.Text) { Flags = DkmEvaluationResultFlags.SideEffect };
                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, pyEvalResult, cppEval, null, hasCppView: true, isOwned: true);
                _evalLoopResult.Write(0); // don't let the eval loop decref the object - we will do it ourselves later, when eval result is closed
                completionRoutine(new DkmEvaluateExpressionAsyncResult(evalResult));
            } else if (sehCode != 0) {
                string errorText = string.Format("Structured exception {0:x08} ", sehCode);
                if (Enum.IsDefined(typeof(EXCEPTION_CODE), sehCode)) {
                    errorText += "(" + (EXCEPTION_CODE)sehCode + ") ";
                }
                errorText += "raised while evaluating expression";
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, errorText,
                    DkmEvaluationResultFlags.Invalid, null)));
            } else if (exc_type != null) {
                string typeName;
                var typeObject = exc_type as PyTypeObject;
                if (typeObject != null) {
                    typeName = typeObject.tp_name.Read().ReadUnicode();
                } else {
                    typeName = "<unknown exception type>";
                }

                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, typeName + " raised while evaluating expression: " + exc_str,
                    DkmEvaluationResultFlags.Invalid, null)));
            } else {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Unknown error occurred while evaluating expression.",
                    DkmEvaluationResultFlags.Invalid, null)));
            }
        }
示例#14
0
 public void EvaluateExpression(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
     var name = expression.Text;
     GetFrameLocals(inspectionContext, workList, stackFrame, getFrameLocalsResult => {
         getFrameLocalsResult.EnumContext.GetItems(workList, 0, int.MaxValue, localGetItemsResult => {
             var vars = localGetItemsResult.Items.OfType<DkmSuccessEvaluationResult>();
             var globals = vars.FirstOrDefault(er => er.Name == "[Globals]");
             if (globals == null) {
                 if (!EvaluateExpressionByWalkingObjects(vars, inspectionContext, workList, expression, stackFrame, completionRoutine)) {
                     EvaluateExpressionViaInterpreter(inspectionContext, workList, expression, stackFrame, completionRoutine);
                 }
             } else {
                 globals.GetChildren(workList, 0, inspectionContext, globalsGetChildrenResult => {
                     globalsGetChildrenResult.EnumContext.GetItems(workList, 0, int.MaxValue, globalsGetItemsResult => {
                         vars = vars.Concat(globalsGetItemsResult.Items.OfType<DkmSuccessEvaluationResult>());
                         if (!EvaluateExpressionByWalkingObjects(vars, inspectionContext, workList, expression, stackFrame, completionRoutine)) {
                             EvaluateExpressionViaInterpreter(inspectionContext, workList, expression, stackFrame, completionRoutine);
                         }
                     });
                 });
             }
         });
     });
 }
示例#15
0
 void IDkmClrResultProvider.GetResult(DkmClrValue clrValue, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo customTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     clrValue.GetResult(
         workList,
         declaredType,
         customTypeInfo,
         inspectionContext,
         formatSpecifiers,
         resultName,
         resultFullName,
         result =>
         {
             var type = declaredType.GetLmrType();
             if (type.IsPointer)
             {
                 var r = (DkmSuccessEvaluationResult)result.Result;
                 // TODO: Why aren't modopts for & properties included?
                 r.GetChildren(
                     workList,
                     1,
                     inspectionContext,
                     children =>
                     {
                         var c = (DkmSuccessEvaluationResult)children.InitialChildren[0];
                         r = DkmSuccessEvaluationResult.Create(
                             c.InspectionContext,
                             c.StackFrame,
                             r.Name,
                             r.FullName,
                             c.Flags,
                             c.Value,
                             r.EditableValue,
                             r.Type,
                             r.Category,
                             r.Access,
                             r.StorageType,
                             r.TypeModifierFlags,
                             null,
                             r.CustomUIVisualizers,
                             null,
                             null);
                         completionRoutine(new DkmEvaluationAsyncResult(r));
                     });
             }
             else
             {
                 completionRoutine(result);
             }
         });
 }
示例#16
0
 void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     enumContext.GetItems(workList, startIndex, count, completionRoutine);
 }
示例#17
0
 void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
 }
示例#18
0
 public void GetFrameReturnType(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmCompletionRoutine<DkmGetFrameReturnTypeAsyncResult> completionRoutine) {
     completionRoutine(new DkmGetFrameReturnTypeAsyncResult(null));
 }
示例#19
0
        public void GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine<DkmGetFrameNameAsyncResult> completionRoutine) {
            var insAddr = frame.InstructionAddress as DkmCustomInstructionAddress;
            if (insAddr == null) {
                Debug.Fail("GetFrameName called on a Python frame without a proper instruction address.");
                throw new InvalidOperationException();
            }

            var loc = new SourceLocation(insAddr.AdditionalData, frame.Process);
            completionRoutine(new DkmGetFrameNameAsyncResult(loc.FunctionName));
        }
示例#20
0
        public void GetChildren(DkmEvaluationResult result, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) {
            var asyncEvalResult = result.GetDataItem<CppViewEvaluationResult>();
            if (asyncEvalResult != null) {
                asyncEvalResult.GetChildren(result, workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var pyEvalResult =
                (IPythonEvaluationResult)result.GetDataItem<PyObjectEvaluationResult>() ??
                (IPythonEvaluationResult)result.GetDataItem<GlobalsEvaluationResult>();
            if (pyEvalResult != null) {
                var childResults = pyEvalResult.GetChildren(this, result, inspectionContext);
                completionRoutine(
                    new DkmGetChildrenAsyncResult(
                        new DkmEvaluationResult[0],
                        DkmEvaluationResultEnumContext.Create(
                            childResults.Count,
                            result.StackFrame,
                            inspectionContext,
                            new EvaluationResults { Results = childResults.ToArray() })));
                return;
            }

            Debug.Fail("GetChildren called on an unsupported DkmEvaluationResult.");
            throw new NotSupportedException();
        }
示例#21
0
        public void GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine) {
            var evalResults = enumContext.GetDataItem<EvaluationResults>();
            if (evalResults == null) {
                Debug.Fail("GetItems called on a DkmEvaluationResultEnumContext without an associated EvaluationResults.");
                throw new NotSupportedException();
            }

            var result = evalResults.Results.Skip(startIndex).Take(count).ToArray();
            completionRoutine(new DkmEvaluationEnumAsyncResult(result));
        }
示例#22
0
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            try
            {
                var dataItem = enumContext.GetDataItem<EnumContextDataItem>();
                if (dataItem == null)
                {
                    // We don't know about this result.  Call next implementation
                    enumContext.GetItems(workList, startIndex, count, completionRoutine);
                    return;
                }

                completionRoutine(GetItems(enumContext.InspectionContext, dataItem.EvalResultDataItem, startIndex, count));
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
示例#23
0
        /// <summary>
        /// Tries to evaluate the given expression by treating it as a chain of member access and indexing operations (e.g. <c>fob[0].oar.baz['abc'].blah</c>),
        /// and looking up the corresponding members in data model provided by <see cref="GetFrameLocals"/>.
        /// </summary>
        /// <param name="vars">List of variables, in the context of which the expression is evaluated.</param>
        /// <returns>
        /// <c>true</c> if evaluation was successful, or if it failed and no fallback is possible (e.g. expression is invalid).
        /// <c>false</c> if evaluation was not successful due to the limitations of this evaluator, and it may be possible to evaluate it correctly by other means.
        /// </returns>
        private bool EvaluateExpressionByWalkingObjects(IEnumerable<DkmSuccessEvaluationResult> vars, DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
            var pyrtInfo = stackFrame.Thread.Process.GetPythonRuntimeInfo();

            var parserOptions = new ParserOptions { ErrorSink = new StringErrorSink() };
            var parser = Parser.CreateParser(new StringReader(expression.Text), pyrtInfo.LanguageVersion, parserOptions);

            var expr = ((ReturnStatement)parser.ParseTopExpression().Body).Expression;
            string errorText = parserOptions.ErrorSink.ToString();
            if (!string.IsNullOrEmpty(errorText)) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text,
                    errorText, DkmEvaluationResultFlags.Invalid, null)));
                return true;
            }

            // Unroll the AST into a sequence of member access and indexing operations, if possible.
            var path = new Stack<string>();
            var reprBuilder = new ReprBuilder(new ReprOptions(stackFrame.Thread.Process));
            while (true) {
                var memberExpr = expr as MemberExpression;
                if (memberExpr != null) {
                    path.Push(memberExpr.Name);
                    expr = memberExpr.Target;
                    continue;
                }

                var indexingExpr = expr as IndexExpression;
                if (indexingExpr != null) {
                    var indexExpr = indexingExpr.Index as ConstantExpression;
                    if (indexExpr != null) {
                        reprBuilder.Clear();
                        reprBuilder.AppendFormat("[{0:PY}]", indexExpr.Value);
                        path.Push(reprBuilder.ToString());
                        expr = indexingExpr.Target;
                        continue;
                    }
                }

                break;
            }

            var varExpr = expr as NameExpression;
            if (varExpr == null) {
                return false;
            }
            path.Push(varExpr.Name);

            // Walk the path through Locals
            while (true) {
                var name = path.Pop();

                var evalResult = vars.FirstOrDefault(er => er.Name == name);
                if (evalResult == null) {
                    return false;
                }

                if (path.Count == 0) {
                    // Clone the evaluation result, but use expression text as its name.
                    DkmDataItem dataItem =
                        (DkmDataItem)evalResult.GetDataItem<PyObjectEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<GlobalsEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<CppViewEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<RawEvaluationResult>();
                    evalResult = DkmSuccessEvaluationResult.Create(
                        evalResult.InspectionContext,
                        evalResult.StackFrame,
                        expression.Text,
                        expression.Text,
                        evalResult.Flags,
                        evalResult.Value,
                        evalResult.EditableValue,
                        evalResult.Type,
                        evalResult.Category,
                        evalResult.Access,
                        evalResult.StorageType,
                        evalResult.TypeModifierFlags,
                        evalResult.Address,
                        evalResult.CustomUIVisualizers,
                        evalResult.ExternalModules,
                        dataItem);

                    completionRoutine(new DkmEvaluateExpressionAsyncResult(evalResult));
                    return true;
                }

                var childWorkList = DkmWorkList.Create(null);
                evalResult.GetChildren(childWorkList, 0, inspectionContext, getChildrenResult =>
                    getChildrenResult.EnumContext.GetItems(childWorkList, 0, int.MaxValue, getItemsResult =>
                        vars = getItemsResult.Items.OfType<DkmSuccessEvaluationResult>()));
                childWorkList.Execute();
            }
        }
 private void GetChildrenAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmStackWalkFrame stackFrame, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     int index = 0;
     if (expansion != null)
     {
         expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
     }
     var numRows = rows.Count;
     Debug.Assert(index >= numRows);
     Debug.Assert(initialRequestSize >= numRows);
     var initialChildren = new DkmEvaluationResult[numRows];
     var wl = new WorkList(workList, e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, initialChildren, 0, numRows, wl, inspectionContext, stackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 var enumContext = DkmEvaluationResultEnumContext.Create(index, stackFrame, inspectionContext, new EnumContextDataItem(dataItem));
                 completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                 rows.Free();
             }));
     wl.Execute();
 }
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var dataItem = enumContext.GetDataItem<EnumContextDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                enumContext.GetItems(workList, startIndex, count, completionRoutine);
                return;
            }

            GetItemsAndContinue(dataItem.EvalResultDataItem, workList, startIndex, count, enumContext.InspectionContext, completionRoutine);
        }
示例#26
0
        void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
        {
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var expansion = dataItem.Expansion;
            if (expansion == null)
            {
                var enumContext = DkmEvaluationResultEnumContext.Create(0, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], enumContext));
                return;
            }

            // Evaluate children with InspectionContext that is not the root.
            inspectionContext = inspectionContext.With(NotRoot);

            var rows = ArrayBuilder<EvalResult>.GetInstance();
            int index = 0;
            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index);
            var numRows = rows.Count;
            Debug.Assert(index >= numRows);
            Debug.Assert(initialRequestSize >= numRows);
            var initialChildren = new DkmEvaluationResult[numRows];
            CompletionRoutine<Exception> onException = e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);
            wl.ContinueWith(() =>
                GetEvaluationResultsAndContinue(evaluationResult, rows, initialChildren, 0, numRows, wl, inspectionContext,
                    () =>
                    wl.ContinueWith(
                        () =>
                        {
                            var enumContext = DkmEvaluationResultEnumContext.Create(index, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult));
                            completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                            rows.Free();
                        }),
                    onException));
        }
 private void GetItemsAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, int startIndex, int count, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var value = dataItem.Value;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     if (expansion != null)
     {
         int index = 0;
         expansion.GetRows(this, rows, inspectionContext, dataItem, value, startIndex, count, visitAll: false, index: ref index);
     }
     var numRows = rows.Count;
     Debug.Assert(count >= numRows);
     var results = new DkmEvaluationResult[numRows];
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, results, 0, numRows, wl, inspectionContext, value.StackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                 rows.Free();
             }));
     wl.Execute();
 }
示例#28
0
 public void GetResult(
     DkmWorkList WorkList,
     DkmClrType DeclaredType,
     DkmClrCustomTypeInfo CustomTypeInfo,
     DkmInspectionContext InspectionContext,
     ReadOnlyCollection<string> FormatSpecifiers,
     string ResultName,
     string ResultFullName,
     DkmCompletionRoutine<DkmEvaluationAsyncResult> CompletionRoutine)
 {
     InspectionContext.InspectionSession.InvokeResultProvider(
         this,
         MethodId.GetResult,
         r =>
         {
             r.GetResult(
                 this,
                 WorkList,
                 DeclaredType,
                 CustomTypeInfo,
                 InspectionContext,
                 FormatSpecifiers,
                 ResultName,
                 ResultFullName,
                 CompletionRoutine);
             return (object)null;
         });
 }
 public virtual void GetChildren(DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     throw new NotImplementedException();
 }
示例#30
0
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var enumContextDataItem = enumContext.GetDataItem<EnumContextDataItem>();
            if (enumContextDataItem == null)
            {
                // We don't know about this result.  Call next implementation
                enumContext.GetItems(workList, startIndex, count, completionRoutine);
                return;
            }

            var evaluationResult = enumContextDataItem.Result;
            var dataItem = evaluationResult.GetDataItem<EvalResultDataItem>();
            var expansion = dataItem.Expansion;
            if (expansion == null)
            {
                completionRoutine(new DkmEvaluationEnumAsyncResult(new DkmEvaluationResult[0]));
                return;
            }

            var inspectionContext = enumContext.InspectionContext;

            var rows = ArrayBuilder<EvalResult>.GetInstance();
            int index = 0;
            expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, startIndex, count, visitAll: false, index: ref index);
            var numRows = rows.Count;
            Debug.Assert(count >= numRows);
            var results = new DkmEvaluationResult[numRows];
            CompletionRoutine<Exception> onException = e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e));
            var wl = new WorkList(workList, onException);
            wl.ContinueWith(() =>
                GetEvaluationResultsAndContinue(evaluationResult, rows, results, 0, numRows, wl, inspectionContext,
                    () =>
                    wl.ContinueWith(
                        () =>
                        {
                            completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                            rows.Free();
                        }),
                    onException));
        }