Exemple #1
0
            public void PyIter_Next(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string iterVar = useRegisters ? "((PyObject*)@rcx)" : "iter";

                ulong tp_iternext = cppEval.EvaluateUInt64(iterVar + "->ob_type->tp_iternext");

                _owner.OnPotentialRuntimeExit(thread, tp_iternext);
            }
Exemple #2
0
            public void builtin_next(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string argsVar = useRegisters ? "((PyTupleObject*)@rdx)" : "((PyTupleObject*)args)";

                ulong tp_iternext = cppEval.EvaluateUInt64(argsVar + "->ob_item[0]->ob_type->tp_iternext");

                _owner.OnPotentialRuntimeExit(thread, tp_iternext);
            }
Exemple #3
0
            public void PyObject_Call(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string funcVar = useRegisters ? "((PyObject*)@rcx)" : "func";

                ulong tp_call = cppEval.EvaluateUInt64(funcVar + "->ob_type->tp_call");

                _owner.OnPotentialRuntimeExit(thread, tp_call);
            }
Exemple #4
0
            public void PyType_GenericNew(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string typeVar = useRegisters ? "((PyTypeObject*)@rcx)" : "type";

                ulong tp_alloc = cppEval.EvaluateUInt64(typeVar + "->tp_alloc");

                _owner.OnPotentialRuntimeExit(thread, tp_alloc);
            }
Exemple #5
0
            public void PyObject_SetAttrString(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string vVar = useRegisters ? "((PyObject*)@rcx)" : "v";

                ulong tp_setattr = cppEval.EvaluateUInt64(vVar + "->ob_type->tp_setattr");

                _owner.OnPotentialRuntimeExit(thread, tp_setattr);
            }
Exemple #6
0
            public void PyCFunction_Call(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                ulong ml_meth = cppEval.EvaluateUInt64(
                    "((PyObject*){0})->ob_type == &PyCFunction_Type ? ((PyCFunctionObject*){0})->m_ml->ml_meth : 0",
                    useRegisters ? "@rcx" : "func");

                _owner.OnPotentialRuntimeExit(thread, ml_meth);
            }
Exemple #7
0
            public void getset_set(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string descrVar = useRegisters ? "((PyGetSetDescrObject*)@rcx)" : "descr";

                ulong set = cppEval.EvaluateUInt64(descrVar + "->d_getset->set");

                _owner.OnPotentialRuntimeExit(thread, set);
            }
            public void PyObject_Print(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                CppExpressionEvaluator cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string opVar = useRegisters ? "((PyObject*)@rcx)" : "op";

                ulong tp_print = cppEval.EvaluateUInt64(opVar + "->ob_type->tp_print");

                _owner.OnPotentialRuntimeExit(thread, tp_print);
            }
Exemple #9
0
            public void new_threadstate(DkmThread thread, ulong frameBase, ulong vframe, ulong returnAddress)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                // Addressing this local by name does not work for release builds, so read the return value directly from the register instead.
                var tstate = PyThreadState.TryCreate(process, cppEval.EvaluateReturnValueUInt64());

                if (tstate == null)
                {
                    return;
                }

                _owner.RegisterTracing(tstate);
            }
            public void type_call(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                CppExpressionEvaluator cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string typeVar = useRegisters ? "((PyTypeObject*)@rcx)" : "type";

                ulong tp_new = cppEval.EvaluateUInt64(typeVar + "->tp_new");

                _owner.OnPotentialRuntimeExit(thread, tp_new);

                ulong tp_init = cppEval.EvaluateUInt64(typeVar + "->tp_init");

                _owner.OnPotentialRuntimeExit(thread, tp_init);
            }
Exemple #11
0
            public void do_richcompare(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                string vVar = useRegisters ? "((PyObject*)@rcx)" : "v";
                string wVar = useRegisters ? "((PyObject*)@rdx)" : "w";

                ulong tp_richcompare1 = cppEval.EvaluateUInt64(vVar + "->ob_type->tp_richcompare");

                _owner.OnPotentialRuntimeExit(thread, tp_richcompare1);

                ulong tp_richcompare2 = cppEval.EvaluateUInt64(wVar + "->ob_type->tp_richcompare");

                _owner.OnPotentialRuntimeExit(thread, tp_richcompare2);
            }
Exemple #12
0
            public void PyInterpreterState_New(DkmThread thread, ulong frameBase, ulong vframe, ulong returnAddress)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                var istate = PyInterpreterState.TryCreate(process, cppEval.EvaluateReturnValueUInt64());

                if (istate == null)
                {
                    return;
                }

                if (process.GetPythonRuntimeInfo().LanguageVersion >= PythonLanguageVersion.V36)
                {
                    _owner.RegisterJITTracing(istate);
                }
            }
Exemple #13
0
            public void call_function(DkmThread thread, ulong frameBase, ulong vframe, bool useRegisters)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                int oparg = cppEval.EvaluateInt32(useRegisters ? "@rdx" : "oparg");

                int na = oparg & 0xff;
                int nk = (oparg >> 8) & 0xff;
                int n  = na + 2 * nk;

                ulong func = cppEval.EvaluateUInt64(
                    "*((*(PyObject***){0}) - {1} - 1)",
                    useRegisters ? "@rcx" : "pp_stack",
                    n);
                var   obj     = PyObject.FromAddress(process, func);
                ulong ml_meth = cppEval.EvaluateUInt64(
                    "((PyObject*){0})->ob_type == &PyCFunction_Type ? ((PyCFunctionObject*){0})->m_ml->ml_meth : 0",
                    func);

                _owner.OnPotentialRuntimeExit(thread, ml_meth);
            }
Exemple #14
0
            public static void PyCode_NewEmpty(DkmThread thread, ulong frameBase, ulong vframe, ulong returnAddress)
            {
                var process = thread.Process;
                var cppEval = new CppExpressionEvaluator(thread, frameBase, vframe);

                ulong filenamePtr = cppEval.EvaluateUInt64("filename");

                if (filenamePtr == 0)
                {
                    return;
                }

                string filename = new CStringProxy(process, filenamePtr).ReadUnicode();

                if (process.GetPythonRuntimeInstance().GetModuleInstances().Any(mi => mi.FullName == filename))
                {
                    return;
                }

                new RemoteComponent.CreateModuleRequest {
                    ModuleId = Guid.NewGuid(),
                    FileName = filename
                }.SendLower(process);
            }
        private DkmEvaluationResult GetPythonView(DkmVisualizedExpression visualizedExpression)
        {
            var stackFrame    = visualizedExpression.StackFrame;
            var process       = stackFrame.Process;
            var pythonRuntime = process.GetPythonRuntimeInstance();

            if (pythonRuntime == null)
            {
                return(null);
            }

            var home = visualizedExpression.ValueHome as DkmPointerValueHome;

            if (home == null)
            {
                Debug.Fail("PythonViewNativeVisualizer given a visualized expression that has a non-DkmPointerValueHome home.");
                return(null);
            }
            else if (home.Address == 0)
            {
                return(null);
            }

            var exprEval = process.GetDataItem <ExpressionEvaluator>();

            if (exprEval == null)
            {
                Debug.Fail("PythonViewNativeVisualizer failed to obtain an instance of ExpressionEvaluator.");
                return(null);
            }

            string cppTypeName = null;
            var    childExpr   = visualizedExpression as DkmChildVisualizedExpression;

            if (childExpr != null)
            {
                var evalResult = childExpr.EvaluationResult as DkmSuccessEvaluationResult;
                cppTypeName = evalResult.Type;
            }
            else
            {
                object punkTypeSymbol;
                visualizedExpression.GetSymbolInterface(typeof(IDiaSymbol).GUID, out punkTypeSymbol);
                using (ComPtr.Create(punkTypeSymbol)) {
                    var typeSymbol = punkTypeSymbol as IDiaSymbol;
                    if (typeSymbol != null)
                    {
                        cppTypeName = typeSymbol.name;
                    }
                }
            }

            PyObject objRef;

            try {
                objRef = PyObject.FromAddress(process, home.Address);
            } catch {
                return(null);
            }

            // TODO: Localization - [Python view] also appears in .natvis file, leave as-is for now
            var pyEvalResult = new PythonEvaluationResult(objRef, "[Python view]")
            {
                Category   = DkmEvaluationResultCategory.Property,
                AccessType = DkmEvaluationResultAccessType.Private
            };

            var inspectionContext = visualizedExpression.InspectionContext;
            CppExpressionEvaluator cppEval;

            try {
                cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
            } catch {
                return(null);
            }

            var pythonContext = DkmInspectionContext.Create(visualizedExpression.InspectionSession, pythonRuntime, stackFrame.Thread,
                                                            inspectionContext.Timeout, inspectionContext.EvaluationFlags, inspectionContext.FuncEvalFlags, inspectionContext.Radix,
                                                            DkmLanguage.Create("Python", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.PythonLanguageGuid)), null);

            try {
                return(exprEval.CreatePyObjectEvaluationResult(pythonContext, stackFrame, null, pyEvalResult, cppEval, cppTypeName, hasCppView: true));
            } catch {
                return(null);
            }
        }