public InspectionScope(DkmClrInstructionAddress address, InspectionSession session)
 {
     InstructionAddress = address;
     SymModule = address.ModuleInstance.Module;
     CurrentMethodToken = address.MethodId.Token;
     Session = session;
 }
Example #2
0
        private EvaluationContextBase CreateMethodContext(DkmClrInstructionAddress instructionAddress, ImmutableArray <MetadataBlock> metadataBlocks)
        {
            var moduleInstance = instructionAddress.ModuleInstance;
            var methodToken    = instructionAddress.MethodId.Token;
            int localSignatureToken;

            try
            {
                localSignatureToken = moduleInstance.GetLocalSignatureToken(methodToken);
            }
            catch (InvalidOperationException)
            {
                // No local signature. May occur when debugging .dmp.
                localSignatureToken = 0;
            }
            catch (FileNotFoundException)
            {
                // No local signature. May occur when debugging heapless dumps.
                localSignatureToken = 0;
            }
            return(this.CreateMethodContext(
                       moduleInstance.AppDomain,
                       metadataBlocks,
                       new Lazy <ImmutableArray <AssemblyReaders> >(() => instructionAddress.MakeAssemblyReaders(), LazyThreadSafetyMode.None),
                       symReader: moduleInstance.GetSymReader(),
                       moduleVersionId: moduleInstance.Mvid,
                       methodToken: methodToken,
                       methodVersion: (int)instructionAddress.MethodId.Version,
                       ilOffset: (int)instructionAddress.ILOffset,
                       localSignatureToken: localSignatureToken));
        }
Example #3
0
        DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(
            DkmInspectionContext inspectionContext,
            DkmClrInstructionAddress instructionAddress,
            bool argumentsOnly)
        {
            try
            {
                var references = instructionAddress.Process.GetMetadataBlocks(instructionAddress.ModuleInstance.AppDomain);
                var context    = this.CreateMethodContext(instructionAddress, references);
                var builder    = ArrayBuilder <LocalAndMethod> .GetInstance();

                string typeName;
                var    assembly = context.CompileGetLocals(
                    builder,
                    argumentsOnly,
                    out typeName,
                    testData: null);
                Debug.Assert((builder.Count == 0) == (assembly.Count == 0));
                var locals = new ReadOnlyCollection <DkmClrLocalVariableInfo>(builder.SelectAsArray(l => DkmClrLocalVariableInfo.Create(l.LocalName, l.MethodName, l.Flags, DkmEvaluationResultCategory.Data)));
                builder.Free();
                return(DkmCompiledClrLocalsQuery.Create(inspectionContext.RuntimeInstance, null, this.CompilerId, assembly, typeName, locals));
            }
            catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
Example #4
0
 DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(
     DkmInspectionContext inspectionContext,
     DkmClrInstructionAddress instructionAddress,
     bool argumentsOnly)
 {
     try
     {
         var moduleInstance  = instructionAddress.ModuleInstance;
         var runtimeInstance = instructionAddress.RuntimeInstance;
         var aliases         = argumentsOnly
             ? ImmutableArray <Alias> .Empty
             : GetAliases(runtimeInstance, inspectionContext); // NB: Not affected by retrying.
         string?error;
         var    r = CompileWithRetry(
             moduleInstance.AppDomain,
             runtimeInstance,
             (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             var builder  = ArrayBuilder <LocalAndMethod> .GetInstance();
             var assembly = context.CompileGetLocals(
                 builder,
                 argumentsOnly,
                 aliases,
                 diagnostics,
                 out var typeName,
                 testData: null);
             Debug.Assert((builder.Count == 0) == (assembly.Count == 0));
             var locals = new ReadOnlyCollection <DkmClrLocalVariableInfo>(builder.SelectAsArray(ToLocalVariableInfo));
             builder.Free();
             return(new GetLocalsResult(typeName, locals, assembly));
         },
             out error);
         return(DkmCompiledClrLocalsQuery.Create(runtimeInstance, null, CompilerId, r.Assembly, r.TypeName, r.Locals));
     }
Example #5
0
        internal static ImmutableArray <AssemblyReaders> MakeAssemblyReaders(this DkmClrInstructionAddress instructionAddress)
        {
            var builder = ArrayBuilder <AssemblyReaders> .GetInstance();

            foreach (DkmClrModuleInstance module in instructionAddress.RuntimeInstance.GetModulesInAppDomain(instructionAddress.ModuleInstance.AppDomain))
            {
                var symReader = module.GetSymReader();
                if (symReader == null)
                {
                    continue;
                }
                MetadataReader reader;
                unsafe
                {
                    try
                    {
                        uint   size;
                        IntPtr ptr;
                        ptr = module.GetMetaDataBytesPtr(out size);
                        Debug.Assert(size > 0);
                        reader = new MetadataReader((byte *)ptr, (int)size);
                    }
                    catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName))
                    {
                        continue;
                    }
                }
                builder.Add(new AssemblyReaders(reader, symReader));
            }
            return(builder.ToImmutableAndFree());
        }
        /// <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);
                }
            }
        }
Example #7
0
 DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(
     DkmInspectionContext inspectionContext,
     DkmClrInstructionAddress instructionAddress,
     bool argumentsOnly)
 {
     try
     {
         var references = instructionAddress.Process.GetMetadataBlocks(instructionAddress.ModuleInstance.AppDomain);
         var context = this.CreateMethodContext(instructionAddress, references);
         var builder = ArrayBuilder<LocalAndMethod>.GetInstance();
         string typeName;
         var assembly = context.CompileGetLocals(
             builder,
             argumentsOnly,
             out typeName,
             testData: null);
         Debug.Assert((builder.Count == 0) == (assembly.Count == 0));
         var locals = new ReadOnlyCollection<DkmClrLocalVariableInfo>(builder.SelectAsArray(l => DkmClrLocalVariableInfo.Create(l.LocalName, l.MethodName, l.Flags, DkmEvaluationResultCategory.Data)));
         builder.Free();
         return DkmCompiledClrLocalsQuery.Create(inspectionContext.RuntimeInstance, null, this.CompilerId, assembly, typeName, locals);
     }
     catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
Example #8
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;
 }
        /// <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;
        }
Example #10
0
        internal override MethodSymbol GetMethod(
            CSharpCompilation compilation,
            DkmClrInstructionAddress instructionAddress
            )
        {
            var methodHandle = (MethodDefinitionHandle)MetadataTokens.Handle(
                instructionAddress.MethodId.Token
                );

            return(compilation.GetSourceMethod(
                       instructionAddress.ModuleInstance.Mvid,
                       methodHandle
                       ));
        }
        public InspectionScope GetScope(DkmClrInstructionAddress address)
        {
            // Cache the various scopes used during the inspection session.  Different scopes are
            // used when the user selects different frames and when the debug engine asks us to
            // format each stack frame.
            InspectionScope scope;
            if (!_scopes.TryGetValue(address, out scope))
            {
                scope = new InspectionScope(address, this);
                _scopes.Add(address, scope);
            }

            return scope;
        }
        public InspectionScope GetScope(DkmClrInstructionAddress address)
        {
            // Cache the various scopes used during the inspection session.  Different scopes are
            // used when the user selects different frames and when the debug engine asks us to
            // format each stack frame.
            InspectionScope scope;

            if (!_scopes.TryGetValue(address, out scope))
            {
                scope = new InspectionScope(address, this);
                _scopes.Add(address, scope);
            }

            return(scope);
        }
Example #13
0
        internal override void OnFunctionResolved(
            DkmClrModuleInstance module,
            DkmRuntimeFunctionResolutionRequest request,
            int token,
            int version,
            int ilOffset)
        {
            var address = DkmClrInstructionAddress.Create(
                module.RuntimeInstance,
                module,
                new DkmClrMethodId(Token: token, Version: (uint)version),
                NativeOffset: uint.MaxValue,
                ILOffset: (uint)ilOffset,
                CPUInstruction: null);

            request.OnFunctionResolved(address);
        }
Example #14
0
        internal static ImmutableArray <AssemblyReaders> MakeAssemblyReaders(this DkmClrInstructionAddress instructionAddress)
        {
            var builder = ArrayBuilder <AssemblyReaders> .GetInstance();

            foreach (DkmClrModuleInstance module in instructionAddress.Process.GetModulesInAppDomain(instructionAddress.ModuleInstance.AppDomain))
            {
                MetadataReader metadataReader;
                if (module.TryGetMetadataReader(out metadataReader))
                {
                    var symReader = module.GetSymReader();
                    if (symReader != null)
                    {
                        builder.Add(new AssemblyReaders(metadataReader, symReader));
                    }
                }
            }
            return(builder.ToImmutableAndFree());
        }
Example #15
0
 private static OnFunctionResolvedDelegate <DkmClrModuleInstance, DkmRuntimeFunctionResolutionRequest> OnFunctionResolved(DkmWorkList workList)
 {
     return((DkmClrModuleInstance module,
             DkmRuntimeFunctionResolutionRequest request,
             int token,
             int version,
             int ilOffset) =>
     {
         var address = DkmClrInstructionAddress.Create(
             module.RuntimeInstance,
             module,
             new DkmClrMethodId(Token: token, Version: (uint)version),
             NativeOffset: 0,
             ILOffset: (uint)ilOffset,
             CPUInstruction: null);
         // Use async overload of OnFunctionResolved to avoid deadlock.
         request.OnFunctionResolved(workList, address, result => { });
     });
 }
Example #16
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 #17
0
 DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(
     DkmInspectionContext inspectionContext,
     DkmClrInstructionAddress instructionAddress,
     bool argumentsOnly)
 {
     try
     {
         var    moduleInstance           = instructionAddress.ModuleInstance;
         var    runtimeInstance          = instructionAddress.RuntimeInstance;
         var    runtimeInspectionContext = RuntimeInspectionContext.Create(inspectionContext);
         var    aliases = argumentsOnly ? null : s_NoAliases;
         string error;
         var    r = this.CompileWithRetry(
             moduleInstance,
             runtimeInstance.GetMetadataBlocks(moduleInstance.AppDomain),
             (blocks, useReferencedModulesOnly) => CreateMethodContext(instructionAddress, blocks, useReferencedModulesOnly),
             (context, diagnostics) =>
         {
             var builder = ArrayBuilder <LocalAndMethod> .GetInstance();
             string typeName;
             var assembly = context.CompileGetLocals(
                 aliases,
                 builder,
                 argumentsOnly,
                 diagnostics,
                 out typeName,
                 testData: null);
             Debug.Assert((builder.Count == 0) == (assembly.Count == 0));
             var locals = new ReadOnlyCollection <DkmClrLocalVariableInfo>(builder.SelectAsArray(ToLocalVariableInfo));
             builder.Free();
             return(new GetLocalsResult(typeName, locals, assembly));
         },
             out error);
         return(DkmCompiledClrLocalsQuery.Create(runtimeInstance, null, this.CompilerId, r.Assembly, r.TypeName, r.Locals));
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
Example #18
0
        internal override CSharpCompilation GetCompilation(DkmClrInstructionAddress instructionAddress)
        {
            var moduleInstance = instructionAddress.ModuleInstance;
            var appDomain      = moduleInstance.AppDomain;
            var previous       = appDomain.GetDataItem <CSharpMetadataContext>();
            var metadataBlocks = instructionAddress.Process.GetMetadataBlocks(appDomain);

            CSharpCompilation compilation;

            if (metadataBlocks.HaveNotChanged(previous))
            {
                compilation = previous.Compilation;
            }
            else
            {
                var dataItem = new CSharpMetadataContext(metadataBlocks);
                appDomain.SetDataItem(DkmDataCreationDisposition.CreateAlways, dataItem);
                compilation = dataItem.Compilation;
            }

            return(compilation);
        }
Example #19
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;
            }
        }
        public static DebugCompilerContext CreateLocalsContext(DkmInspectionContext inspectionContext, DkmClrInstructionAddress address, bool argumentsOnly)
        {
            MemoryStream input;
            StreamReader reader;
            CreateInputStream(string.Empty, out input, out reader);

            InspectionSession session = InspectionSession.GetInstance(inspectionContext.InspectionSession);
            InspectionScope scope = session.GetScope(address);

            DebugCompilerContext context = new DebugCompilerContext(
                null /* null because the context doesn't own the lifetime of the session */,
                scope,
                input,
                reader,
                typeof(LocalVariablesTranslator),
                null /* Method name is not applicable because we create multiple methods for Locals. */,
                new List<DkmClrLocalVariableInfo>(),
                null /* Assignment L-Value only applies to assigments */,
                argumentsOnly);
            context.InitializeSymbols();

            return context;
        }
        public static DebugCompilerContext CreateAssignmentContext(DkmEvaluationResult lValue, DkmClrInstructionAddress address, string expression)
        {
            MemoryStream input;
            StreamReader reader;
            CreateInputStream(expression, out input, out reader);

            InspectionSession session = InspectionSession.GetInstance(lValue.InspectionSession);
            InspectionScope scope = session.GetScope(address);

            DebugCompilerContext context = new DebugCompilerContext(
                null /* null because the context doesn't own the lifetime of the session */,
                scope,
                input,
                reader,
                typeof(AssignmentTranslator),
                "$.M1",
                null /* Generated locals is not applicable for assigments */,
                lValue.FullName,
                false /* "ArgumentsOnly" only applies to local variable query */);
            context.InitializeSymbols();

            return context;
        }
Example #22
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;
            }
        }
        public static DebugCompilerContext CreateExpressionContext(DkmInspectionContext inspectionContext, DkmClrInstructionAddress address, string expression)
        {
            InspectionSession ownedSession = null;
            InspectionScope scope;
            if (inspectionContext != null)
            {
                InspectionSession session = InspectionSession.GetInstance(inspectionContext.InspectionSession);
                scope = session.GetScope(address);
            }
            else
            {
                // There is no inspection context when compiling breakpoint conditions.  Create a
                // new temporary session.  The context will need to dispose of this new session
                // when it is disposed.
                ownedSession = new InspectionSession();
                scope = ownedSession.GetScope(address);
            }

            MemoryStream input;
            StreamReader reader;
            CreateInputStream(expression, out input, out reader);

            DebugCompilerContext context = new DebugCompilerContext(
                ownedSession,
                scope,
                input,
                reader,
                typeof(ExpressionTranslator),
                "$.M1",
                null /* Generated locals is not applicable for compiling expressions */,
                null /* Assignment L-Value only applies to assigments */,
                false /* "ArgumentsOnly" only applies to local variable query */);
            context.InitializeSymbols();

            return context;
        }
 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;
     }
 }
Example #25
0
 internal override MethodSymbol GetMethod(CSharpCompilation compilation, DkmClrInstructionAddress instructionAddress)
 {
     return(compilation.GetSourceMethod(instructionAddress.ModuleInstance.Mvid, instructionAddress.MethodId.Token));
 }
        /// <summary>
        /// This method is called by the debug engine to retrieve the current local variables.
        /// The result of this call will be a query containing the names of the local variables
        /// as well as IL code to retrieve each variable value.
        /// </summary>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// reference point for where we need to retrieve the local variables</param>
        /// <param name="argumentsOnly">True if only arguments are needed</param>
        /// <returns>A local variables query</returns>
        DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(DkmInspectionContext inspectionContext, DkmClrInstructionAddress instructionAddress, bool argumentsOnly)
        {
            using (DebugCompilerContext context = ContextFactory.CreateLocalsContext(inspectionContext, instructionAddress, argumentsOnly))
            {
                context.GenerateQuery();

                return DkmCompiledClrLocalsQuery.Create(
                    inspectionContext.RuntimeInstance,
                    null,
                    inspectionContext.Language.Id,
                    new ReadOnlyCollection<byte>(context.GetPeBytes()),
                    context.ClassName,
                    new ReadOnlyCollection<DkmClrLocalVariableInfo>(context.GeneratedLocals));
            }
        }
Example #27
0
 internal abstract string GetName(DkmClrInstructionAddress instructionAddress, bool includeParameterTypes, bool includeParameterNames, ArrayBuilder <string> argumentValues);
Example #28
0
 internal abstract string GetReturnType(DkmClrInstructionAddress instructionAddress);
Example #29
0
 internal abstract TCompilation GetCompilation(DkmClrInstructionAddress instructionAddress);
Example #30
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 #31
0
        public static DebugCompilerContext CreateLocalsContext(DkmInspectionContext inspectionContext, DkmClrInstructionAddress address, bool argumentsOnly)
        {
            MemoryStream input;
            StreamReader reader;

            CreateInputStream(string.Empty, out input, out reader);

            InspectionSession session = InspectionSession.GetInstance(inspectionContext.InspectionSession);
            InspectionScope   scope   = session.GetScope(address);

            DebugCompilerContext context = new DebugCompilerContext(
                null /* null because the context doesn't own the lifetime of the session */,
                scope,
                input,
                reader,
                typeof(LocalVariablesTranslator),
                null /* Method name is not applicable because we create multiple methods for Locals. */,
                new List <DkmClrLocalVariableInfo>(),
                null /* Assignment L-Value only applies to assigments */,
                argumentsOnly);

            context.InitializeSymbols();

            return(context);
        }
Example #32
0
        public static DebugCompilerContext CreateAssignmentContext(DkmEvaluationResult lValue, DkmClrInstructionAddress address, string expression)
        {
            MemoryStream input;
            StreamReader reader;

            CreateInputStream(expression, out input, out reader);

            InspectionSession session = InspectionSession.GetInstance(lValue.InspectionSession);
            InspectionScope   scope   = session.GetScope(address);

            DebugCompilerContext context = new DebugCompilerContext(
                null /* null because the context doesn't own the lifetime of the session */,
                scope,
                input,
                reader,
                typeof(AssignmentTranslator),
                "$.M1",
                null /* Generated locals is not applicable for assigments */,
                lValue.FullName,
                false /* "ArgumentsOnly" only applies to local variable query */);

            context.InitializeSymbols();

            return(context);
        }
Example #33
0
        public static DebugCompilerContext CreateExpressionContext(DkmInspectionContext inspectionContext, DkmClrInstructionAddress address, string expression)
        {
            InspectionSession ownedSession = null;
            InspectionScope   scope;

            if (inspectionContext != null)
            {
                InspectionSession session = InspectionSession.GetInstance(inspectionContext.InspectionSession);
                scope = session.GetScope(address);
            }
            else
            {
                // There is no inspection context when compiling breakpoint conditions.  Create a
                // new temporary session.  The context will need to dispose of this new session
                // when it is disposed.
                ownedSession = new InspectionSession();
                scope        = ownedSession.GetScope(address);
            }

            MemoryStream input;
            StreamReader reader;

            CreateInputStream(expression, out input, out reader);

            DebugCompilerContext context = new DebugCompilerContext(
                ownedSession,
                scope,
                input,
                reader,
                typeof(ExpressionTranslator),
                "$.M1",
                null /* Generated locals is not applicable for compiling expressions */,
                null /* Assignment L-Value only applies to assigments */,
                false /* "ArgumentsOnly" only applies to local variable query */);

            context.InitializeSymbols();

            return(context);
        }
Example #34
0
        private EvaluationContextBase CreateMethodContext(DkmClrInstructionAddress instructionAddress, ImmutableArray<MetadataBlock> metadataBlocks)
        {
            var moduleInstance = instructionAddress.ModuleInstance;
            var methodToken = instructionAddress.MethodId.Token;
            int localSignatureToken;
            try
            {
                localSignatureToken = moduleInstance.GetLocalSignatureToken(methodToken);
            }
            catch (InvalidOperationException)
            {
                // No local signature. May occur when debugging .dmp.
                localSignatureToken = 0;
			}
			catch (FileNotFoundException)
			{
				// No local signature. May occur when debugging heapless dumps.
				localSignatureToken = 0;
			}
			return this.CreateMethodContext(
                moduleInstance.AppDomain,
                metadataBlocks,
                new Lazy<ImmutableArray<AssemblyReaders>>(() => instructionAddress.MakeAssemblyReaders(), LazyThreadSafetyMode.None),
                symReader: moduleInstance.GetSymReader(),
                moduleVersionId: moduleInstance.Mvid,
                methodToken: methodToken,
                methodVersion: (int)instructionAddress.MethodId.Version,
                ilOffset: (int)instructionAddress.ILOffset,
                localSignatureToken: localSignatureToken);
        }
        /// <summary>
        /// This method is called by the debug engine to retrieve the current local variables.
        /// The result of this call will be a query containing the names of the local variables
        /// as well as IL code to retrieve each variable value.
        /// </summary>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// reference point for where we need to retrieve the local variables</param>
        /// <param name="argumentsOnly">True if only arguments are needed</param>
        /// <returns>A local variables query</returns>
        DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(DkmInspectionContext inspectionContext, DkmClrInstructionAddress instructionAddress, bool argumentsOnly)
        {
            var  result    = inspectionContext.GetClrLocalVariableQuery(instructionAddress, argumentsOnly);
            var  newlocals = new List <DkmClrLocalVariableInfo>();
            bool changed   = false;

            foreach (var loc in result.LocalInfo)
            {
                if (loc.VariableName.Contains("$"))
                {
                    // do not add
                    changed = true;
                }
                else if (loc.VariableName == "this")
                {
                    // rename
                    var newloc = DkmClrLocalVariableInfo.Create("SELF", "SELF", loc.MethodName, loc.CompilationFlags, loc.ResultCategory, loc.CustomTypeInfo);
                    newlocals.Add(newloc);
                    changed = true;
                }
                else
                {
                    newlocals.Add(loc);
                }
            }
            if (changed)
            {
                result = DkmCompiledClrLocalsQuery.Create(result.RuntimeInstance,
                                                          result.DataContainer, result.LanguageId, result.Binary, result.TypeName,
                                                          new ReadOnlyCollection <DkmClrLocalVariableInfo>(newlocals));
            }
            return(result);
        }
 /// <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 #37
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;
            using (DebugCompilerContext context = ContextFactory.CreateAssignmentContext(lValue, 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),
                        DkmClrCompilationResultFlags.None,
                        DkmEvaluationResultCategory.Data,
                        DkmEvaluationResultAccessType.None,
                        DkmEvaluationResultStorageType.None,
                        DkmEvaluationResultTypeModifierFlags.None,
                        null);
                }
            }
        }
Example #38
0
 internal abstract TMethodSymbol GetMethod(TCompilation compilation, DkmClrInstructionAddress instructionAddress);
Example #39
0
        /// <summary>
        /// This method is called by the debug engine to retrieve the current local variables.
        /// The result of this call will be a query containing the names of the local variables
        /// as well as IL code to retrieve each variable value.
        /// </summary>
        /// <param name="inspectionContext">Context of the evaluation.  This contains options/flags
        /// to be used during compilation. It also contains the InspectionSession.  The inspection
        /// session is the object that provides lifetime management for our objects.  When the user
        /// steps or continues the process, the debug engine will dispose of the inspection session</param>
        /// <param name="instructionAddress">Instruction address or code location to use as the
        /// reference point for where we need to retrieve the local variables</param>
        /// <param name="argumentsOnly">True if only arguments are needed</param>
        /// <returns>A local variables query</returns>
        DkmCompiledClrLocalsQuery IDkmClrExpressionCompiler.GetClrLocalVariableQuery(DkmInspectionContext inspectionContext, DkmClrInstructionAddress instructionAddress, bool argumentsOnly)
        {
            using (DebugCompilerContext context = ContextFactory.CreateLocalsContext(inspectionContext, instructionAddress, argumentsOnly))
            {
                context.GenerateQuery();

                return(DkmCompiledClrLocalsQuery.Create(
                           inspectionContext.RuntimeInstance,
                           null,
                           inspectionContext.Language.Id,
                           new ReadOnlyCollection <byte>(context.GetPeBytes()),
                           context.ClassName,
                           new ReadOnlyCollection <DkmClrLocalVariableInfo>(context.GeneratedLocals)));
            }
        }