Exemple #1
0
        public CppExpressionEvaluator(DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame)
        {
            _process = stackFrame.Process;
            var thread = stackFrame.Thread;

            if (stackFrame.InstructionAddress is DkmNativeInstructionAddress)
            {
                _nativeFrame = stackFrame;
            }
            else
            {
                var customAddr = stackFrame.InstructionAddress as DkmCustomInstructionAddress;
                if (customAddr == null)
                {
                    throw new ArgumentException();
                }

                var loc = new SourceLocation(customAddr.AdditionalData, _process);
                if (loc.NativeAddress == null)
                {
                    throw new ArgumentException();
                }

                _nativeFrame = DkmStackWalkFrame.Create(thread, loc.NativeAddress, stackFrame.FrameBase, stackFrame.FrameSize,
                                                        DkmStackWalkFrameFlags.None, null, stackFrame.Registers, null);
            }

            _cppInspectionContext = DkmInspectionContext.Create(inspectionContext.InspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, inspectionContext.Radix, CppLanguage, null);
        }
Exemple #2
0
            internal string ExecuteExpression(string expression, DkmStackContext stackContext, DkmStackWalkFrame input, bool allowZero)
            {
                var compilerId         = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp);
                var language           = DkmLanguage.Create("C++", compilerId);
                var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null);

                var inspectionContext = DkmInspectionContext.Create(stackContext.InspectionSession, input.RuntimeInstance, stackContext.Thread, 200, DkmEvaluationFlags.None, DkmFuncEvalFlags.None, 10, language, null);

                var    workList   = DkmWorkList.Create(null);
                string resultText = null;

                inspectionContext.EvaluateExpression(workList, languageExpression, input, res =>
                {
                    if (res.ErrorCode == 0)
                    {
                        var result = res.ResultObject as DkmSuccessEvaluationResult;

                        if (result != null && result.TagValue == DkmEvaluationResult.Tag.SuccessResult && (allowZero || result.Address.Value != 0))
                        {
                            resultText = result.Value;
                        }

                        res.ResultObject.Close();
                    }
                });

                workList.Execute();

                return(resultText);
            }
Exemple #3
0
        internal static DkmEvaluationResult ExecuteRawExpression(string expression, DkmInspectionSession inspectionSession, DkmThread thread, DkmStackWalkFrame input, DkmRuntimeInstance runtimeInstance, DkmEvaluationFlags flags)
        {
            var compilerId         = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp);
            var language           = DkmLanguage.Create("C++", compilerId);
            var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null);

            var inspectionContext = DkmInspectionContext.Create(inspectionSession, runtimeInstance, thread, 200, flags, DkmFuncEvalFlags.None, 10, language, null, null, DkmCompiledVisualizationDataPriority.None, null, workerConnection);

            var workList = DkmWorkList.Create(null);

            try
            {
                DkmEvaluationResult result = null;

                inspectionContext.EvaluateExpression(workList, languageExpression, input, res =>
                {
                    if (res.ErrorCode == 0)
                    {
                        result = res.ResultObject;
                    }
                });

                workList.Execute();

                return(result);
            }
            catch (OperationCanceledException)
            {
                return(null);
            }
        }
Exemple #4
0
        internal static string ExecuteExpression(string expression, DkmInspectionSession inspectionSession, DkmThread thread, DkmStackWalkFrame input, DkmEvaluationFlags flags, bool allowZero, out ulong address)
        {
            if (Log.instance != null)
            {
                Log.instance.Verbose($"ExecuteExpression begin evaluation of '{expression}'");
            }

            var compilerId         = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp);
            var language           = DkmLanguage.Create("C++", compilerId);
            var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null);

            var inspectionContext = DkmInspectionContext.Create(inspectionSession, input.RuntimeInstance, thread, 200, flags, DkmFuncEvalFlags.None, 10, language, null, null, DkmCompiledVisualizationDataPriority.None, null, workerConnection);

            var workList = DkmWorkList.Create(null);

            try
            {
                string resultText    = null;
                ulong  resultAddress = 0;

                inspectionContext.EvaluateExpression(workList, languageExpression, input, res =>
                {
                    if (res.ErrorCode == 0)
                    {
                        var result = res.ResultObject as DkmSuccessEvaluationResult;

                        if (result != null && result.TagValue == DkmEvaluationResult.Tag.SuccessResult && (allowZero || result.Address.Value != 0))
                        {
                            resultText    = result.Value;
                            resultAddress = result.Address.Value;
                        }

                        res.ResultObject.Close();
                    }
                });

                workList.Execute();

                if (Log.instance != null)
                {
                    Log.instance.Verbose($"ExecuteExpression completed");
                }

                address = resultAddress;
                return(resultText);
            }
            catch (OperationCanceledException)
            {
                address = 0;
                return(null);
            }
        }
Exemple #5
0
 private static DkmInspectionContext CreateInspectionContext(DkmStackContext stackContext, DkmStackWalkFrame frame)
 {
     return(DkmInspectionContext.Create(
                stackContext.InspectionSession,
                frame.RuntimeInstance,
                frame.Thread,
                1000,
                DkmEvaluationFlags.None,
                DkmFuncEvalFlags.None,
                10,
                CppLanguage,
                null));
 }
Exemple #6
0
        public CppExpressionEvaluator(DkmThread thread, ulong frameBase, ulong vframe)
        {
            _process = thread.Process;

            var inspectionSession = DkmInspectionSession.Create(_process, null);

            _cppInspectionContext = DkmInspectionContext.Create(inspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, CppLanguage, null);

            const int CV_ALLREG_VFRAME = 0x00007536;
            var       vframeReg        = DkmUnwoundRegister.Create(CV_ALLREG_VFRAME, new ReadOnlyCollection <byte>(BitConverter.GetBytes(vframe)));
            var       regs             = thread.GetCurrentRegisters(new[] { vframeReg });
            var       iaddr            = _process.CreateNativeInstructionAddress(regs.GetInstructionPointer());

            _nativeFrame = DkmStackWalkFrame.Create(thread, iaddr, frameBase, 0, DkmStackWalkFrameFlags.None, null, regs, null);
        }
 internal static DkmInspectionContext With(this DkmInspectionContext inspectionContext, DkmEvaluationFlags flags)
 {
     return(DkmInspectionContext.Create(
                inspectionContext.InspectionSession,
                inspectionContext.RuntimeInstance,
                inspectionContext.Thread,
                inspectionContext.Timeout,
                inspectionContext.EvaluationFlags | flags,
                inspectionContext.FuncEvalFlags,
                inspectionContext.Radix,
                inspectionContext.Language,
                inspectionContext.ReturnValue,
                inspectionContext.AdditionalVisualizationData,
                inspectionContext.AdditionalVisualizationDataPriority,
                inspectionContext.ReturnValues));
 }
Exemple #8
0
        public static unsafe PyFrameObject TryCreate(DkmStackWalkFrame frame)
        {
            var process = frame.Process;

            if (frame.InstructionAddress == null)
            {
                return(null);
            }
            if (frame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid && !IsInEvalFrame(frame))
            {
                return(null);
            }

            var cppLanguage       = DkmLanguage.Create("C++", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.CppLanguageGuid));
            var inspectionSession = DkmInspectionSession.Create(process, null);
            var inspectionContext = DkmInspectionContext.Create(inspectionSession, process.GetNativeRuntimeInstance(), frame.Thread, 0,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, cppLanguage, null);

            CppExpressionEvaluator cppEval;

            try
            {
                cppEval = new CppExpressionEvaluator(inspectionContext, frame);
            }
            catch (ArgumentException)
            {
                Debug.Fail("Failed to create C++ expression evaluator while obtaining PyFrameObject from a native frame.");
                return(null);
            }

            ulong framePtr;

            try
            {
                framePtr = cppEval.EvaluateUInt64("f");
            }
            catch (CppEvaluationException)
            {
                Debug.Fail("Failed to evaluate the 'f' parameter to PyEval_EvalFrameEx while obtaining PyFrameObject from a native frame.");
                return(null);
            }

            return(new PyFrameObject(frame.Process, framePtr));
        }
Exemple #9
0
        private void GetFrameName(
            DkmInspectionContext inspectionContext,
            DkmWorkList workList,
            DkmStackWalkFrame frame,
            DkmVariableInfoFlags argumentFlags,
            DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine,
            TMethodSymbol method)
        {
            var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types);
            var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names);

            if (argumentFlags.Includes(DkmVariableInfoFlags.Values))
            {
                // No need to compute the Expandable bit on
                // argument values since that can be expensive.
                inspectionContext = DkmInspectionContext.Create(
                    inspectionContext.InspectionSession,
                    inspectionContext.RuntimeInstance,
                    inspectionContext.Thread,
                    inspectionContext.Timeout,
                    inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoExpansion,
                    inspectionContext.FuncEvalFlags,
                    inspectionContext.Radix,
                    inspectionContext.Language,
                    inspectionContext.ReturnValue,
                    inspectionContext.AdditionalVisualizationData,
                    inspectionContext.AdditionalVisualizationDataPriority,
                    inspectionContext.ReturnValues);

                // GetFrameArguments returns an array of formatted argument values. We'll pass
                // ourselves (GetFrameName) as the continuation of the GetFrameArguments call.
                inspectionContext.GetFrameArguments(
                    workList,
                    frame,
                    result =>
                {
                    var argumentValues = result.Arguments;
                    try
                    {
                        var builder = ArrayBuilder <string> .GetInstance();
                        foreach (var argument in argumentValues)
                        {
                            var formattedArgument = argument as DkmSuccessEvaluationResult;
                            // Not expecting Expandable bit, at least not from this EE.
                            Debug.Assert((formattedArgument == null) || (formattedArgument.Flags & DkmEvaluationResultFlags.Expandable) == 0);
                            builder.Add(formattedArgument?.Value);
                        }

                        var frameName = _instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, builder);
                        builder.Free();
                        completionRoutine(new DkmGetFrameNameAsyncResult(frameName));
                    }
                    catch (Exception e) when(ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException))
                    {
                        completionRoutine(DkmGetFrameNameAsyncResult.CreateErrorResult(e));
                    }
                    finally
                    {
                        foreach (var argument in argumentValues)
                        {
                            argument.Close();
                        }
                    }
                });
            }
            else
            {
                var frameName = _instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, null);
                completionRoutine(new DkmGetFrameNameAsyncResult(frameName));
            }
        }
Exemple #10
0
        /// <summary>
        /// Visualize the property that represents a 'sqlite3 *'.
        /// </summary>
        /// <param name="result">Result of accessing property</param>
        /// <param name="sqliteInstanceName">Property name</param>
        public void VisualizeSqliteInstance(DkmSuccessEvaluationResult result)
        {
            Debug.Assert(result != null && !String.IsNullOrEmpty(result.FullName), "Arguments should not be null");

            this.sqliteInstanceName     = result.FullName;
            this.ShowOverlay            = true;
            this.LoadNextCommand.Enable = false;
            this.CancelCommand.Enable   = false;

            bool dmpDebugging = result.InspectionContext.Thread.Process.LivePart == null;

            if (dmpDebugging)
            {
                this.OverlayMessage = Resources.ErrMsg_DmpDebuggingNotSupported;
            }
            else
            {
                this.OverlayMessage = Resources.Msg_LoadingTables;

                // Create a new inspection context for all subsequent func-evals in this visualizer
                this.inspectionContext = DkmInspectionContext.Create(
                    result.InspectionSession,
                    result.RuntimeInstance,
                    result.InspectionContext.Thread,
                    1000,
                    DkmEvaluationFlags.None,
                    DkmFuncEvalFlags.None,
                    10,
                    result.InspectionContext.Language,
                    null);

                // Get available tables
                ThreadHelper.JoinableTaskFactory.RunAsync(async() =>
                {
                    IList <string> tables;
                    try
                    {
                        tables = await LoadTablesAsync();
                    }
                    catch (Exception e)
                    {
                        this.OverlayMessage = String.Format(CultureInfo.CurrentCulture, Resources.ErrMsg_FailureGettingTables, e.Message);
                        return;
                    }

                    // If tables do exist, prepare the table query
                    if (tables.Count == 0)
                    {
                        this.OverlayMessage = Resources.ErrMsg_NoTablesFound;
                    }
                    else
                    {
                        this.AvailableTables = tables;
                        this.SelectedTable   = tables[0];
                    }
                });
            }

            var window = new VisualizerWindow()
            {
                DataContext = this
            };

            window.ShowDialog();
        }
        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);
            }
        }
Exemple #12
0
        void IDkmLanguageFrameDecoder.GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine)
        {
            try
            {
                Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types | DkmVariableInfoFlags.Values)) == argumentFlags,
                             "Unexpected argumentFlags", "argumentFlags = {0}", argumentFlags);

                var instructionAddress    = (DkmClrInstructionAddress)frame.InstructionAddress;
                var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types);
                var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names);

                if (argumentFlags.Includes(DkmVariableInfoFlags.Values))
                {
                    // No need to compute the Expandable bit on
                    // argument values since that can be expensive.
                    inspectionContext = DkmInspectionContext.Create(
                        inspectionContext.InspectionSession,
                        inspectionContext.RuntimeInstance,
                        inspectionContext.Thread,
                        inspectionContext.Timeout,
                        inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoExpansion,
                        inspectionContext.FuncEvalFlags,
                        inspectionContext.Radix,
                        inspectionContext.Language,
                        inspectionContext.ReturnValue,
                        inspectionContext.AdditionalVisualizationData,
                        inspectionContext.AdditionalVisualizationDataPriority,
                        inspectionContext.ReturnValues);

                    // GetFrameArguments returns an array of formatted argument values. We'll pass
                    // ourselves (GetFrameName) as the continuation of the GetFrameArguments call.
                    inspectionContext.GetFrameArguments(
                        workList,
                        frame,
                        result =>
                    {
                        try
                        {
                            var builder = ArrayBuilder <string> .GetInstance();
                            foreach (var argument in result.Arguments)
                            {
                                var evaluatedArgument = argument as DkmSuccessEvaluationResult;
                                // Not expecting Expandable bit, at least not from this EE.
                                Debug.Assert((evaluatedArgument == null) || (evaluatedArgument.Flags & DkmEvaluationResultFlags.Expandable) == 0);
                                builder.Add((evaluatedArgument != null) ? evaluatedArgument.Value : null);
                            }

                            var frameName = _instructionDecoder.GetName(instructionAddress, includeParameterTypes, includeParameterNames, builder);
                            builder.Free();
                            completionRoutine(new DkmGetFrameNameAsyncResult(frameName));
                        }
                        // TODO: Consider calling DkmComponentManager.ReportCurrentNonFatalException() to
                        // trigger a non-fatal Watson when this occurs.
                        catch (Exception e) when(!ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
                        {
                            completionRoutine(DkmGetFrameNameAsyncResult.CreateErrorResult(e));
                        }
                        finally
                        {
                            foreach (var argument in result.Arguments)
                            {
                                argument.Close();
                            }
                        }
                    });
                }
                else
                {
                    var frameName = _instructionDecoder.GetName(instructionAddress, includeParameterTypes, includeParameterNames, null);
                    completionRoutine(new DkmGetFrameNameAsyncResult(frameName));
                }
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }