Example #1
0
 void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
     DkmLanguageExpression expression,
     DkmClrModuleInstance moduleInstance,
     int token,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     try
     {
         var runtimeInstance = moduleInstance.RuntimeInstance;
         var appDomain       = moduleInstance.AppDomain;
         var compileResult   = this.CompileWithRetry(
             moduleInstance,
             runtimeInstance.GetMetadataBlocks(appDomain),
             (blocks, useReferencedModulesOnly) => CreateTypeContext(appDomain, blocks, moduleInstance.Mvid, token, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             ResultProperties unusedResultProperties;
             return(context.CompileExpression(
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        ImmutableArray <Alias> .Empty,
                        diagnostics,
                        out unusedResultProperties,
                        testData: null));
         },
             out error);
         result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), runtimeInstance);
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
        private DkmLanguageExpression AddFuncEval(
            DkmWorkList workList,
            string funcEval,
            Action <DkmEvaluationResult> evalResult)
        {
            Debug.Assert(workList != null && !string.IsNullOrEmpty(funcEval), "Arguments should not be null");
            Debug.WriteLine($"Creating func-eval: '{funcEval}'");

            // Create the evaluation to add
            var langExpr = DkmLanguageExpression.Create(
                this.inspectionContext.Language,
                DkmEvaluationFlags.None,
                funcEval,
                null);

            this.inspectionContext.EvaluateExpression(
                workList,
                langExpr,
                this.inspectionContext.Thread.GetTopStackFrame(),
                delegate(DkmEvaluateExpressionAsyncResult asyncResult)
            {
                evalResult(asyncResult.ResultObject);
            });

            return(langExpr);
        }
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <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="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error = null;
            result = null;
            using (DebugCompilerContext context = ContextFactory.CreateExpressionContext(inspectionContext, instructionAddress, expression.Text))
            {
                context.GenerateQuery();

                error = context.FirstError;
                if (string.IsNullOrEmpty(error))
                {
                    result = DkmCompiledClrInspectionQuery.Create(
                        instructionAddress.RuntimeInstance,
                        null,
                        expression.Language.Id,
                        new ReadOnlyCollection<byte>(context.GetPeBytes()),
                        context.ClassName,
                        context.MethodName,
                        new ReadOnlyCollection<string>(context.FormatSpecifiers),
                        context.ResultFlags,
                        DkmEvaluationResultCategory.Data,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null);
                }
            }
        }
 /// <summary>
 /// This method is called by the debug engine when the user modifies the result of a
 /// previous evaluation.  The result of this call will be a query containing the IL code
 /// necessary to assign the value.
 /// </summary>
 /// <param name="expression">The text the user entered as the new value</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="lValue">The L-Value of the assigment.  This is a previous evaluation result.</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query to
 /// execute to perform the assignment.</param>
 void IDkmClrExpressionCompiler.CompileAssignment(DkmLanguageExpression expression, DkmClrInstructionAddress instructionAddress, DkmEvaluationResult lValue, out string error, out DkmCompiledClrInspectionQuery result)
 {
     // when the user assigns a value in the debugger then this method is called.
     // we may want to change an expression like "{1,2,3}" to "new object[] {1,2,3}"
     // and "2020.12.03" to "XSharp.RT.Functions.ConDate(2020,12,03)"
     error  = null;
     result = null;
     expression.CompileAssignment(instructionAddress, lValue, out error, out result);
 }
Example #5
0
        public static DkmEvaluationResult Evaluate(DkmVisualizedExpression expr, DkmEvaluationFlags flags, string text, DkmDataItem data)
        {
            using (DkmLanguageExpression vexpr = DkmLanguageExpression.Create(CppLanguage, flags, text, data))
            {
                DkmEvaluationResult result = null;
                expr.EvaluateExpressionCallback(expr.InspectionContext, vexpr, expr.StackFrame, out result);

                return(result);
            }
        }
Example #6
0
 public DkmEvaluationResult TryEvaluate(string expr)
 {
     using (var cppExpr = DkmLanguageExpression.Create(CppLanguage, DkmEvaluationFlags.NoSideEffects, expr, null)) {
         DkmEvaluationResult cppEvalResult = null;
         var cppWorkList = DkmWorkList.Create(null);
         _cppInspectionContext.EvaluateExpression(cppWorkList, cppExpr, _nativeFrame, (result) => {
             cppEvalResult = result.ResultObject;
         });
         cppWorkList.Execute();
         return(cppEvalResult);
     }
 }
Example #7
0
 /// <summary>
 /// This method is called by the debug engine to compile an expression that the user wants
 /// to evaluate.  Before the call, we have the text of the expression and information about
 /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
 /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
 /// result of the expression.
 /// </summary>
 /// <param name="expression">This is the raw expression to compile</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <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="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
 void IDkmClrExpressionCompiler.CompileExpression(
     DkmLanguageExpression expression,
     DkmClrInstructionAddress instructionAddress,
     DkmInspectionContext inspectionContext,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     error  = null;
     result = null;
     expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
     return;
 }
Example #8
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);
            }
        }
        /// <summary>
        /// This method is called by the debug engine to compile an expression that the user wants
        /// to evaluate.  Before the call, we have the text of the expression and information about
        /// the context we want to evaluate in (code location, evaluation flags, etc.).  The result
        /// of the call is a &quot;query&quot; containing IL the debugger will execute to get the
        /// result of the expression.
        /// </summary>
        /// <param name="expression">This is the raw expression to compile</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// context of the compilation.</param>
        /// <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="error">[Out] If the there are any compile errors, this parameter is set to
        /// the error message to display to the user</param>
        /// <param name="result">[Out] If compilation was successful, this is the output query.</param>
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            error  = null;
            result = null;
            bool   changed      = false;
            string originalExpr = expression.Text;
            // We use a trick to change the Text when sending it to C#, by retrieveing the field info.
            // This field has a property get but not a property set.
            var fi = typeof(DkmLanguageExpression).GetField("m_Text", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            if (fi != null)
            {
                var newexpr = originalExpr;
                if (expression.Text.StartsWith("SELF", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "this" + originalExpr.Substring(4);
                }
                else if (expression.Text.StartsWith("SUPER", System.StringComparison.OrdinalIgnoreCase))
                {
                    changed = true;
                    newexpr = "base" + originalExpr.Substring(5);
                }
                if (newexpr.Contains(":"))
                {
                    newexpr = newexpr.Replace(':', '.');
                    changed = true;
                }
                // check for literal array
                //var lbrkt = newexpr.IndexOf('[');
                //var rbrkt = newexpr.IndexOf(']');
                //if (lbrkt > 0 && rbrkt > 0 && lbrkt < rbrkt)
                //{
                //    newexpr = AdjustArrayIndices(newexpr, ref changed);
                //}
                if (changed && fi != null)
                {
                    fi.SetValue(expression, newexpr);
                }
            }
            expression.CompileExpression(instructionAddress, inspectionContext, out error, out result);
            if (changed && fi != null)
            {
                fi.SetValue(expression, originalExpr);
            }
            return;
        }
        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);

            DkmInspectionContext inspectionContext;

            LuaWorkerConnectionWrapper workerConnectionWrapper = inspectionSession.Process.GetDataItem <LuaWorkerConnectionWrapper>();

            if (workerConnectionWrapper != null)
            {
                inspectionContext = workerConnectionWrapper.CreateInspectionSession(inspectionSession, runtimeInstance, thread, flags, language);
            }
            else
            {
                inspectionContext = DkmInspectionContext.Create(inspectionSession, runtimeInstance, thread, 200, flags, DkmFuncEvalFlags.None, 10, language, null);
            }

            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);
            }
        }
        private int QueryColumnCount()
        {
            int columnCount            = 0;
            DkmLanguageExpression expr = null;

            try
            {
                DkmWorkList workList         = DkmWorkList.Create(null);
                SqliteVisualizerException ex = null;
                expr = this.AddFuncEval(
                    workList,
                    $"sqlite3_column_count(*(sqlite3_stmt **){this.procMemForQuery})",
                    (r) =>
                {
                    DkmSuccessEvaluationResult suc;
                    if (!this.VerifySuccess(r, out suc))
                    {
                        ex = new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
                        return;
                    }

                    columnCount = (int)suc.Address.Value;
                });

                workList.Execute();

                if (ex != null)
                {
                    throw ex;
                }
            }
            finally
            {
                if (expr != null)
                {
                    expr.Close();
                }
            }

            return(columnCount);
        }
Example #12
0
        void IDkmClrExpressionCompiler.CompileAssignment(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmEvaluationResult lValue,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var moduleInstance  = instructionAddress.ModuleInstance;
                var runtimeInstance = instructionAddress.RuntimeInstance;
                var aliases         = GetAliases(runtimeInstance, lValue.InspectionContext); // NB: Not affected by retrying.
                var r = this.CompileWithRetry(
                    moduleInstance.AppDomain,
                    runtimeInstance,
                    (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
                    (context, diagnostics) =>
                {
                    ResultProperties resultProperties;
                    var compileResult = context.CompileAssignment(
                        lValue.FullName,
                        expression.Text,
                        aliases,
                        diagnostics,
                        out resultProperties,
                        testData: null);
                    return(new CompileExpressionResult(compileResult, resultProperties));
                },
                    out error);

                Debug.Assert(
                    r.CompileResult == null && r.ResultProperties.Flags == default ||
                    (r.ResultProperties.Flags & DkmClrCompilationResultFlags.PotentialSideEffect) == DkmClrCompilationResultFlags.PotentialSideEffect);

                result = r.CompileResult.ToQueryResult(this.CompilerId, r.ResultProperties, runtimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Example #13
0
        void IDkmClrExpressionCompiler.CompileAssignment(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmEvaluationResult lValue,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain  = instructionAddress.ModuleInstance.AppDomain;
                var references = instructionAddress.Process.GetMetadataBlocks(appDomain);

                ResultProperties resultProperties;
                ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateMethodContext(instructionAddress, references);
                    compileResult = context.CompileAssignment(
                        RuntimeInspectionContext.Create(lValue.InspectionContext),
                        lValue.FullName,
                        expression.Text,
                        this.DiagnosticFormatter,
                        out resultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                Debug.Assert((resultProperties.Flags & DkmClrCompilationResultFlags.PotentialSideEffect) == DkmClrCompilationResultFlags.PotentialSideEffect);
                result = compileResult.ToQueryResult(this.CompilerId, resultProperties, instructionAddress.RuntimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Example #14
0
        void IDkmClrExpressionCompiler.CompileExpression(
            DkmLanguageExpression expression,
            DkmClrInstructionAddress instructionAddress,
            DkmInspectionContext inspectionContext,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain = instructionAddress.ModuleInstance.AppDomain;
                var references = instructionAddress.Process.GetMetadataBlocks(appDomain);

                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                ResultProperties resultProperties;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateMethodContext(instructionAddress, references);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Create(inspectionContext),
                        expression.Text,
                        expression.CompilationFlags,
                        this.DiagnosticFormatter,
                        out resultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, resultProperties, instructionAddress.RuntimeInstance);
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Example #15
0
        void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
            DkmLanguageExpression expression,
            DkmClrModuleInstance moduleInstance,
            int token,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain  = moduleInstance.AppDomain;
                var references = moduleInstance.Process.GetMetadataBlocks(appDomain);

                ResultProperties unusedResultProperties;
                ImmutableArray <AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateTypeContext(moduleInstance, references, token);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Empty,
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        this.DiagnosticFormatter,
                        out unusedResultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), moduleInstance.RuntimeInstance);
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
 void IDkmClrExpressionCompiler.CompileExpression(
     DkmLanguageExpression expression,
     DkmClrInstructionAddress instructionAddress,
     DkmInspectionContext inspectionContext,
     out string error,
     out DkmCompiledClrInspectionQuery result)
 {
     try
     {
         var moduleInstance           = instructionAddress.ModuleInstance;
         var runtimeInstance          = instructionAddress.RuntimeInstance;
         var runtimeInspectionContext = RuntimeInspectionContext.Create(inspectionContext);
         var r = this.CompileWithRetry(
             moduleInstance,
             runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
             (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             ResultProperties resultProperties;
             var compileResult = context.CompileExpression(
                 runtimeInspectionContext,
                 expression.Text,
                 expression.CompilationFlags,
                 diagnostics,
                 out resultProperties,
                 testData: null);
             return(new CompileExpressionResult(compileResult, resultProperties));
         },
             out error);
         result = r.CompileResult.ToQueryResult(this.CompilerId, r.ResultProperties, runtimeInstance);
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
        private void FinalizeQuery()
        {
            DkmLanguageExpression expr = null;

            try
            {
                SqliteVisualizerException ex = null;
                DkmWorkList workList         = DkmWorkList.Create(null);
                expr = this.AddFuncEval(
                    workList,
                    $"sqlite3_finalize(*(sqlite3_stmt **){this.procMemForQuery})",
                    (r) =>
                {
                    DkmSuccessEvaluationResult suc;
                    if (!this.VerifySuccess(r, out suc))
                    {
                        ex = new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
                        return;
                    }
                });

                workList.Execute();

                if (ex != null)
                {
                    throw ex;
                }
            }
            finally
            {
                if (expr != null)
                {
                    expr.Close();
                }
            }
        }
        private void PrepareQuery()
        {
            DkmLanguageExpression expr = null;

            try
            {
                SqliteVisualizerException ex = null;
                DkmWorkList workList         = DkmWorkList.Create(null);
                expr = this.AddFuncEval(
                    workList,
                    $"sqlite3_prepare({sqliteInstanceName}, \"{query}\", {query.Length + 1}, (sqlite3_stmt **){this.procMemForQuery}, nullptr)",
                    (r) =>
                {
                    DkmSuccessEvaluationResult suc;
                    if (!this.VerifySuccess(r, out suc))
                    {
                        ex = new SqliteVisualizerException(Resources.ErrMsg_PrepareFailed, r.FullName);
                        return;
                    }
                });

                workList.Execute();

                if (ex != null)
                {
                    throw ex;
                }
            }
            finally
            {
                if (expr != null)
                {
                    expr.Close();
                }
            }
        }
Example #19
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 bool TryGetRow(out string[] row)
        {
            // Move to the next row
            bool moreRows = false;
            var  exprs    = new List <DkmLanguageExpression>();

            try
            {
                const int SQLITE_ROW           = 100;
                SqliteVisualizerException ex   = null;
                DkmWorkList           workList = DkmWorkList.Create(null);
                DkmLanguageExpression expr     = this.AddFuncEval(
                    workList,
                    $"sqlite3_step(*(sqlite3_stmt **){this.procMemForQuery})",
                    (r) =>
                {
                    DkmSuccessEvaluationResult suc;
                    if (!this.VerifySuccess(r, out suc))
                    {
                        ex = new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
                        return;
                    }

                    moreRows = SQLITE_ROW == (int)suc.Address.Value;
                });

                exprs.Add(expr);
                workList.Execute();

                if (ex != null)
                {
                    throw ex;
                }
            }
            finally
            {
                foreach (var e in exprs)
                {
                    e.Close();
                }

                exprs.Clear();
            }

            if (!moreRows)
            {
                row = new string[0];
                return(false);
            }

            // Read each column in the row
            var rowLocal = new string[ColumnNames.Count()];

            try
            {
                SqliteVisualizerException ex = null;
                DkmProcess  process          = this.inspectionContext.Thread.Process;
                DkmWorkList workList         = DkmWorkList.Create(null);
                for (int i = 0; i < rowLocal.Length; i++)
                {
                    var i_local = i;
                    var e       = this.AddFuncEval(
                        workList,
                        $"sqlite3_column_text(*(sqlite3_stmt **){this.procMemForQuery}, {i})",
                        (r) =>
                    {
                        DkmSuccessEvaluationResult suc;
                        if (!this.VerifySuccess(r, out suc))
                        {
                            ex = ex ?? new SqliteVisualizerException(Resources.ErrMsg_FuncEvalFailed, r.FullName);
                            return;
                        }

                        ulong address      = suc.Address.Value;
                        byte[] stringMaybe = process.ReadMemoryString(address, DkmReadMemoryFlags.None, 1, 1024);
                        int len            = stringMaybe.Length;
                        if (len > 0)
                        {
                            // The debugger null terminates all strings, but encoding doesn't strip null when creating a string
                            len--;
                            rowLocal[i_local] = Encoding.UTF8.GetString(stringMaybe, 0, len);
                        }
                    });

                    exprs.Add(e);
                }

                workList.Execute();

                if (ex != null)
                {
                    throw ex;
                }
            }
            finally
            {
                foreach (var e in exprs)
                {
                    e.Close();
                }
            }

            row = rowLocal;
            return(true);
        }
Example #21
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);
                         }
                     });
                 });
             }
         });
     });
 }
Example #22
0
 /// <summary>
 /// This method is called by the debug engine when the user modifies the result of a
 /// previous evaluation.  The result of this call will be a query containing the IL code
 /// necessary to assign the value.
 /// </summary>
 /// <param name="expression">The text the user entered as the new value</param>
 /// <param name="instructionAddress">Instruction address or code location to use as the
 /// context of the compilation.</param>
 /// <param name="lValue">The L-Value of the assigment.  This is a previous evaluation result.</param>
 /// <param name="error">[Out] If the there are any compile errors, this parameter is set to
 /// the error message to display to the user</param>
 /// <param name="result">[Out] If compilation was successful, this is the output query to
 /// execute to perform the assignment.</param>
 void IDkmClrExpressionCompiler.CompileAssignment(DkmLanguageExpression expression, DkmClrInstructionAddress instructionAddress, DkmEvaluationResult lValue, out string error, out DkmCompiledClrInspectionQuery result)
 {
     error  = null;
     result = null;
     expression.CompileAssignment(instructionAddress, lValue, out error, out result);
 }
Example #23
0
        void IDkmClrExpressionCompilerCallback.CompileDisplayAttribute(
            DkmLanguageExpression expression,
            DkmClrModuleInstance moduleInstance,
            int token,
            out string error,
            out DkmCompiledClrInspectionQuery result)
        {
            try
            {
                var appDomain = moduleInstance.AppDomain;
                var references = moduleInstance.Process.GetMetadataBlocks(appDomain);

                ResultProperties unusedResultProperties;
                ImmutableArray<AssemblyIdentity> missingAssemblyIdentities;
                CompileResult compileResult;
                do
                {
                    var context = this.CreateTypeContext(moduleInstance, references, token);
                    compileResult = context.CompileExpression(
                        RuntimeInspectionContext.Empty,
                        expression.Text,
                        DkmEvaluationFlags.TreatAsExpression,
                        this.DiagnosticFormatter,
                        out unusedResultProperties,
                        out error,
                        out missingAssemblyIdentities,
                        preferredUICulture: null,
                        testData: null);
                } while (ShouldTryAgainWithMoreMetadataBlocks(appDomain, missingAssemblyIdentities, ref references));

                result = compileResult.ToQueryResult(this.CompilerId, default(ResultProperties), moduleInstance.RuntimeInstance);
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Example #24
0
        /// <summary>
        /// Returns child elements of previous evaluation.
        /// </summary>
        public void GetItems(DkmVisualizedExpression visualizedExpression, DkmEvaluationResultEnumContext enumContext, int startIndex, int count, out DkmChildVisualizedExpression[] items)
        {
            // Check if we want to use passthrough visualizer
            PassThroughVisualizer passThroughVisualizer = enumContext.GetDataItem <PassThroughVisualizer>();

            if (passThroughVisualizer != null)
            {
                passThroughVisualizer.GetItems(visualizedExpression, enumContext, startIndex, count, out items);
                return;
            }

            // Execute our regular visualizer
            VSCustomVisualizerEvaluator evaluator = visualizedExpression.GetDataItem <VSCustomVisualizerEvaluator>();

            IResultVisualizer[] itemsAsResults = evaluator.ResultVisualizer.Children.Skip(startIndex).Take(count).ToArray();

            items = new DkmChildVisualizedExpression[itemsAsResults.Length];
            for (int i = 0; i < items.Length; i++)
            {
                IResultVisualizer           item = itemsAsResults[i];
                DkmEvaluationResultCategory category;

                switch (item.DataType)
                {
                case CompletionDataType.Class:
                    category = DkmEvaluationResultCategory.Class;
                    break;

                case CompletionDataType.Property:
                case CompletionDataType.StaticProperty:
                    category = DkmEvaluationResultCategory.Property;
                    break;

                case CompletionDataType.Event:
                    category = DkmEvaluationResultCategory.Event;
                    break;

                case CompletionDataType.Method:
                    category = DkmEvaluationResultCategory.Method;
                    break;

                case CompletionDataType.Enum:
                case CompletionDataType.EnumValue:
                case CompletionDataType.Keyword:
                case CompletionDataType.Namespace:
                case CompletionDataType.StaticClass:
                case CompletionDataType.StaticEvent:
                case CompletionDataType.StaticMethod:
                case CompletionDataType.StaticVariable:
                case CompletionDataType.Unknown:
                case CompletionDataType.Variable:
                default:
                    category = DkmEvaluationResultCategory.Data;
                    break;
                }

                DkmExpressionValueHome valueHome = visualizedExpression.ValueHome;
                ulong  address  = 0;
                string fullName = string.Empty;
                string typeName = null;

                try
                {
                    if (item.Value is Variable variable)
                    {
                        address   = variable.GetPointerAddress();
                        typeName  = variable.GetCodeType().Name;
                        fullName  = $"*(({typeName}*)0x{address:X})";
                        valueHome = DkmPointerValueHome.Create(address);
                    }
                }
                catch
                {
                }

                DkmEvaluationResult result;
                DkmDataItem         dataItem = null;

                if (item.ShouldForceDefaultVisualizer && !string.IsNullOrEmpty(fullName))
                {
                    using (DkmLanguageExpression languageExpression = DkmLanguageExpression.Create(visualizedExpression.InspectionContext.Language, DkmEvaluationFlags.TreatAsExpression, fullName, null))
                    {
                        visualizedExpression.EvaluateExpressionCallback(visualizedExpression.InspectionContext, languageExpression, visualizedExpression.StackFrame, out result);
                    }

                    if (result is DkmSuccessEvaluationResult successResult)
                    {
                        dataItem = new PassThroughVisualizer(successResult);
                        result   = DkmSuccessEvaluationResult.Create(
                            successResult.InspectionContext,
                            successResult.StackFrame,
                            item.Name, // Name - Left column
                            successResult.FullName,
                            successResult.Flags,
                            successResult.Value, // Value - Middle column
                            successResult.EditableValue,
                            successResult.Type,  // Type - Right column
                            category,
                            successResult.Access,
                            successResult.StorageType,
                            successResult.TypeModifierFlags,
                            successResult.Address,
                            successResult.CustomUIVisualizers,
                            successResult.ExternalModules,
                            successResult.RefreshButtonText,
                            dataItem);
                    }
                }
                else
                {
                    result = DkmSuccessEvaluationResult.Create(
                        visualizedExpression.InspectionContext,
                        visualizedExpression.StackFrame,
                        item.Name,        // Name - Left column
                        fullName,         // FullName - What is being copied when "Add to watch"
                        DkmEvaluationResultFlags.ReadOnly | (item.IsExpandable ? DkmEvaluationResultFlags.Expandable : DkmEvaluationResultFlags.None),
                        item.ValueString, // Value - Middle column
                        "",
                        item.Type ?? "",  // Type - Right column
                        category,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null,
                        VSUIVisualizerService.GetUIVisualizers(item),
                        null,
                        null);
                    dataItem = new VSCustomVisualizerEvaluator(result, item);
                }
                items[i] = DkmChildVisualizedExpression.Create(
                    visualizedExpression.InspectionContext,
                    visualizedExpression.VisualizerId,
                    visualizedExpression.SourceId,
                    visualizedExpression.StackFrame,
                    valueHome,
                    result,
                    visualizedExpression,
                    (uint)(startIndex + i),
                    dataItem);
            }
        }
Example #25
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)));
            }
        }
Example #26
0
        public void EvaluateVisualizedExpression(DkmVisualizedExpression visualizedExpression, out DkmEvaluationResult resultObject)
        {
            var rootExpr = visualizedExpression as DkmRootVisualizedExpression;

            if (rootExpr == null)
            {
                Debug.Fail("PythonViewNativeVisualizer.EvaluateVisualizedExpression was given a visualized expression that is not a DkmRootVisualizedExpression.");
                throw new NotSupportedException();
            }

            DkmEvaluationResult       rawResult;
            RawEvaluationResultHolder rawResultHolder;

            using (var rawExpr = DkmLanguageExpression.Create(CppExpressionEvaluator.CppLanguage, DkmEvaluationFlags.ShowValueRaw, rootExpr.FullName + ",!", null)) {
                rootExpr.EvaluateExpressionCallback(rootExpr.InspectionContext, rawExpr, rootExpr.StackFrame, out rawResult);
                rawResultHolder = new RawEvaluationResultHolder {
                    RawResult = rawResult
                };
                rootExpr.SetDataItem(DkmDataCreationDisposition.CreateAlways, rawResultHolder);
            }

            var rawSuccessResult = rawResult as DkmSuccessEvaluationResult;

            if (rawSuccessResult != null)
            {
                resultObject = DkmSuccessEvaluationResult.Create(
                    rawResult.InspectionContext,
                    rawResult.StackFrame,
                    rootExpr.Name,
                    rawSuccessResult.FullName,
                    rawSuccessResult.Flags,
                    rawSuccessResult.Value,
                    rawSuccessResult.EditableValue,
                    rawSuccessResult.Type,
                    rawSuccessResult.Category,
                    rawSuccessResult.Access,
                    rawSuccessResult.StorageType,
                    rawSuccessResult.TypeModifierFlags,
                    rawSuccessResult.Address,
                    rawSuccessResult.CustomUIVisualizers,
                    rawSuccessResult.ExternalModules,
                    rawResultHolder);
                return;
            }

            var rawFailedResult = rawResult as DkmFailedEvaluationResult;

            if (rawFailedResult != null)
            {
                resultObject = DkmFailedEvaluationResult.Create(
                    rawResult.InspectionContext,
                    rawResult.StackFrame,
                    rootExpr.Name,
                    rootExpr.FullName,
                    rawFailedResult.ErrorMessage,
                    rawFailedResult.Flags,
                    rawResultHolder);
                return;
            }

            Debug.Fail("Raw evaluation result was neither DkmSuccessEvaluationResult nor DkmFailedEvaluationResult.");
            throw new NotSupportedException();
        }
Example #27
0
        void IDkmLanguageExpressionEvaluator.EvaluateExpression(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine <DkmEvaluateExpressionAsyncResult> completionRoutine)
        {
            if (stackFrame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid)
            {
                Debug.Fail("EvaluateExpression called on a non-Python frame.");
                throw new NotSupportedException();
            }

            var ee = stackFrame.Process.GetDataItem <ExpressionEvaluator>();

            if (ee == null)
            {
                Debug.Fail("EvaluateExpression called, but no instance of ExpressionEvaluator exists in this DkmProcess to handle it.");
                throw new InvalidOperationException();
            }

            ee.EvaluateExpression(inspectionContext, workList, expression, stackFrame, completionRoutine);
        }
Example #28
0
 private static DkmLanguageExpression CppExpression(string expression)
 {
     return(DkmLanguageExpression.Create(CppLanguage, DkmEvaluationFlags.None, expression, null));
 }