Exemple #1
0
        public override IEnumerable<PythonEvaluationResult> GetDebugChildren(ReprOptions reprOptions) {
            yield return new PythonEvaluationResult(new ValueStore<long>(ReadElements().Count()), "len()") {
                Category = DkmEvaluationResultCategory.Method
            };

            var reprBuilder = new ReprBuilder(reprOptions);
            foreach (var entry in ReadElements()) {
                reprBuilder.Clear();
                reprBuilder.AppendFormat("[{0}]", entry.Key);
                yield return new PythonEvaluationResult(entry.Value, reprBuilder.ToString());
            }
        }
Exemple #2
0
        public override IEnumerable <PythonEvaluationResult> GetDebugChildren(ReprOptions reprOptions)
        {
            yield return(new PythonEvaluationResult(new ValueStore <long>(ReadElements().Count()), "len()")
            {
                Category = DkmEvaluationResultCategory.Method
            });

            var reprBuilder = new ReprBuilder(reprOptions);

            foreach (var entry in ReadElements())
            {
                reprBuilder.Clear();
                reprBuilder.AppendFormat("[{0}]", entry.Key);
                yield return(new PythonEvaluationResult(entry.Value, reprBuilder.ToString()));
            }
        }
Exemple #3
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();
            }
        }
Exemple #4
0
            public List<DkmEvaluationResult> GetChildren(ExpressionEvaluator exprEval, DkmEvaluationResult result, DkmInspectionContext inspectionContext) {
                var stackFrame = result.StackFrame;
                var cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
                var obj = ValueStore.Read();
                var evalResults = new List<DkmEvaluationResult>();
                var reprOptions = new ReprOptions(inspectionContext);
                var reprBuilder = new ReprBuilder(reprOptions);

                if (DebuggerOptions.ShowCppViewNodes && !HasCppView) {
                    if (CppTypeName == null) {
                        // Try to guess the object's C++ type by looking at function pointers in its PyTypeObject. If they are pointing
                        // into a module for which symbols are available, C++ EE should be able to resolve them into something like
                        // "0x1e120d50 {python33_d.dll!list_dealloc(PyListObject *)}". If we are lucky, one of those functions will have
                        // the first argument declared as a strongly typed pointer, rather than PyObject* or void*.
                        CppTypeName = "PyObject";
                        CppTypeModuleName = null;
                        foreach (string methodField in _methodFields) {
                            var funcPtrEvalResult = cppEval.TryEvaluateObject(null, "PyObject", obj.Address, ".ob_type->" + methodField) as DkmSuccessEvaluationResult;
                            if (funcPtrEvalResult == null || funcPtrEvalResult.Value.IndexOf('{') < 0) {
                                continue;
                            }

                            var match = _cppFirstArgTypeFromFuncPtrRegex.Match(funcPtrEvalResult.Value);
                            string module = match.Groups["module"].Value;
                            string firstArgType = match.Groups["type"].Value;
                            if (firstArgType != "void" && firstArgType != "PyObject" && firstArgType != "_object") {
                                CppTypeName = firstArgType;
                                CppTypeModuleName = module;
                                break;
                            }
                        }
                    }

                    string cppExpr = CppExpressionEvaluator.GetExpressionForObject(CppTypeModuleName, CppTypeName, obj.Address, ",!");
                    var evalResult = DkmIntermediateEvaluationResult.Create(
                        inspectionContext, stackFrame, "[C++ view]", "{C++}" + cppExpr, cppExpr,
                        CppExpressionEvaluator.CppLanguage, stackFrame.Process.GetNativeRuntimeInstance(), null);
                    evalResults.Add(evalResult);
                }

                int i = 0;
                foreach (var child in obj.GetDebugChildren(reprOptions).Take(MaxDebugChildren)) {
                    if (child.Name == null) {
                        reprBuilder.Clear();
                        reprBuilder.AppendFormat("[{0:PY}]", i++);
                        child.Name = reprBuilder.ToString();
                    }

                    DkmEvaluationResult evalResult;
                    if (child.ValueStore is IValueStore<PyObject>) {
                        evalResult = exprEval.CreatePyObjectEvaluationResult(inspectionContext, stackFrame, FullName, child, cppEval);
                    } else {
                        var value = child.ValueStore.Read();
                        reprBuilder.Clear();
                        reprBuilder.AppendLiteral(value);

                        string type = null;
                        if (Process.GetPythonRuntimeInfo().LanguageVersion <= PythonLanguageVersion.V27) {
                            _typeMapping2x.TryGetValue(value.GetType(), out type);
                        }
                        if (type == null) {
                            _typeMapping.TryGetValue(value.GetType(), out type);
                        }

                        var flags = DkmEvaluationResultFlags.ReadOnly;
                        if (value is string) {
                            flags |= DkmEvaluationResultFlags.RawString;
                        }

                        string childFullName = child.Name;
                        if (FullName != null) {
                            if (childFullName.EndsWith("()")) { // len()
                                childFullName = childFullName.Substring(0, childFullName.Length - 2) + "(" + FullName + ")";
                            } else {
                                if (!childFullName.StartsWith("[")) { // [0], ['fob'] etc
                                    childFullName = "." + childFullName;
                                }
                                childFullName = FullName + childFullName;
                            }
                        }

                        evalResult = DkmSuccessEvaluationResult.Create(
                            inspectionContext, stackFrame, child.Name, childFullName, flags, reprBuilder.ToString(), null, type,
                            child.Category, child.AccessType, child.StorageType, child.TypeModifierFlags, null, null, null,
                            new RawEvaluationResult { Value = value });
                    }

                    evalResults.Add(evalResult);
                }

                return evalResults;
            }