/// <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); }
private void MaybeGenerateEntryForSymbol(Symbol symbol) { if (_context.ArgumentsOnly && symbol.StorageClass != StorageClass.Argument) { // We are only showing arguments return; } IrisType symbolType = symbol.Type; if (symbolType.IsMethod || symbolType == IrisType.Invalid || symbolType == IrisType.Void) { // This symbol doesn't belong in the Locals window. // Don't generate an entry for it. return; } if (symbol.Name.StartsWith("$.")) { // Don't show compiler internal symbols return; } string methodName = _context.NextMethodName(); IrisType derefType = DerefType(symbolType); // Emit code for the method to get the symbol value. MethodGenerator.BeginMethod(methodName, derefType, _context.ParameterVariables, _context.LocalVariables, entryPoint: false, methodFileName: null); EmitLoadSymbol(symbol, SymbolLoadMode.Dereference); MethodGenerator.EndMethod(); // Generate the local entry to pass back to the debug engine DkmClrCompilationResultFlags resultFlags = DkmClrCompilationResultFlags.None; if (derefType == IrisType.Boolean) { // The debugger uses "BoolResult" for breakpoint conditions so setting the flag // here has no effect currently, but we set it for the sake of consistency. resultFlags |= DkmClrCompilationResultFlags.BoolResult; } else if (derefType.IsArray) { // Iris doesn't support modification of an array itself resultFlags |= DkmClrCompilationResultFlags.ReadOnlyResult; } string fullName = symbol.Name; _context.GeneratedLocals.Add(DkmClrLocalVariableInfo.Create( fullName, fullName, methodName, resultFlags, DkmEvaluationResultCategory.Data, null)); }
private static DkmClrLocalVariableInfo ToLocalVariableInfo(LocalAndMethod local) { return(DkmClrLocalVariableInfo.Create( local.LocalDisplayName, local.LocalName, local.MethodName, local.Flags, DkmEvaluationResultCategory.Data, local.GetCustomTypeInfo().ToDkmClrCustomTypeInfo())); }
private static DkmClrLocalVariableInfo ToLocalVariableInfo(LocalAndMethod local) { ReadOnlyCollection <byte> customTypeInfo; Guid customTypeInfoId = local.GetCustomTypeInfo(out customTypeInfo); return(DkmClrLocalVariableInfo.Create( local.LocalDisplayName, local.LocalName, local.MethodName, local.Flags, DkmEvaluationResultCategory.Data, customTypeInfo.ToCustomTypeInfo(customTypeInfoId))); }
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; } }
private static DkmClrLocalVariableInfo ToLocalVariableInfo(LocalAndMethod local) { return(DkmClrLocalVariableInfo.Create(local.LocalName, local.MethodName, local.Flags, DkmEvaluationResultCategory.Data)); }