private string GetName(string source, string methodName, DkmVariableInfoFlags argumentFlags, string[] typeArguments, string[] argumentValues = null) { Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types)) == argumentFlags, "Unexpected argumentFlags", "argumentFlags = {0}", argumentFlags); var instructionDecoder = CSharpInstructionDecoder.Instance; var method = GetConstructedMethod(source, methodName, typeArguments, instructionDecoder); var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); ArrayBuilder <string> builder = null; if (argumentValues != null) { builder = ArrayBuilder <string> .GetInstance(); builder.AddRange(argumentValues); } var name = instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, builder); builder?.Free(); return(name); }
void IDkmLanguageFrameDecoder.GetFrameName( DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { try { Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types | DkmVariableInfoFlags.Values)) == argumentFlags, $"Unexpected argumentFlags '{argumentFlags}'"); GetNameWithGenericTypeArguments(inspectionContext, workList, frame, onSuccess: method => GetFrameName(inspectionContext, workList, frame, argumentFlags, completionRoutine, method), onFailure: e => completionRoutine(DkmGetFrameNameAsyncResult.CreateErrorResult(e))); } catch (NotImplementedMetadataException) { inspectionContext.GetFrameName(workList, frame, argumentFlags, completionRoutine); } catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e)) { throw ExceptionUtilities.Unreachable; } }
/// <summary> /// This method is called by the debug engine to get the text representation of a stack /// frame. /// </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="workList">The current work list. This is used to batch asynchronous /// work items. If any asynchronous calls are needed later, this is the work list to pass /// to the asynchronous call. It's not needed in our case.</param> /// <param name="frame">The frame to get the text representation for</param> /// <param name="argumentFlags">Option flags to change the way we format frames</param> /// <param name="completionRoutine">Completion routine to call when work is completed</param> void IDkmLanguageFrameDecoder.GetFrameName( DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine<DkmGetFrameNameAsyncResult> completionRoutine) { string name = TryGetFrameNameHelper(inspectionContext, frame, argumentFlags) ?? "<Unknown Method>"; completionRoutine(new DkmGetFrameNameAsyncResult(name)); }
/// <summary> /// This method is called by the debug engine to get the text representation of a stack /// frame. /// </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="workList">The current work list. This is used to batch asynchronous /// work items. If any asynchronous calls are needed later, this is the work list to pass /// to the asynchronous call. It's not needed in our case.</param> /// <param name="frame">The frame to get the text representation for</param> /// <param name="argumentFlags">Option flags to change the way we format frames</param> /// <param name="completionRoutine">Completion routine to call when work is completed</param> void IDkmLanguageFrameDecoder.GetFrameName( DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { string name = TryGetFrameNameHelper(inspectionContext, frame, argumentFlags) ?? "<Unknown Method>"; completionRoutine(new DkmGetFrameNameAsyncResult(name)); }
private static string TryGetFrameNameHelper(DkmInspectionContext inspectionContext, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags) { ImportedMethod currentMethod = TryGetCurrentMethod(inspectionContext, frame); if (currentMethod == null) return null; string name = currentMethod.Name; if (string.Equals(name, "$.main", StringComparison.Ordinal)) return "<Main Block>"; if (argumentFlags == DkmVariableInfoFlags.None) return name; Variable[] args = currentMethod.GetParameters(); if (args.Length == 0) return name; StringBuilder nameBuilder = new StringBuilder(); nameBuilder.Append(name); nameBuilder.Append('('); bool first = true; bool showTypes = argumentFlags.HasFlag(DkmVariableInfoFlags.Types); bool showNames = argumentFlags.HasFlag(DkmVariableInfoFlags.Names); foreach (Variable arg in args) { if (first) first = false; else nameBuilder.Append("; "); IrisType argType = arg.Type; if (argType.IsByRef) { nameBuilder.Append("var "); argType = argType.GetElementType(); } if (showNames) nameBuilder.Append(arg.Name); if (showNames && showTypes) nameBuilder.Append(" : "); if (showTypes) nameBuilder.Append(argType); } nameBuilder.Append(')'); return nameBuilder.ToString(); }
string IDkmLanguageInstructionDecoder.GetMethodName( DkmLanguageInstructionAddress languageInstructionAddress, DkmVariableInfoFlags argumentFlags ) { try { // DkmVariableInfoFlags.FullNames was accepted by the old GetMethodName implementation, // but it was ignored. Furthermore, it's not clear what FullNames would mean with respect // to argument names in C# or Visual Basic. For consistency with the old behavior, we'll // just ignore the flag as well. Debug.Assert( ( argumentFlags & ( DkmVariableInfoFlags.FullNames | DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types ) ) == argumentFlags, $"Unexpected argumentFlags '{argumentFlags}'" ); var instructionAddress = (DkmClrInstructionAddress)languageInstructionAddress.Address; var compilation = _instructionDecoder.GetCompilation( instructionAddress.ModuleInstance ); var method = _instructionDecoder.GetMethod(compilation, instructionAddress); var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); return(_instructionDecoder.GetName( method, includeParameterTypes, includeParameterNames )); } catch (NotImplementedMetadataException) { return(languageInstructionAddress.GetMethodName(argumentFlags)); } catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e)) { throw ExceptionUtilities.Unreachable; } }
private string GetName( string source, string methodName, DkmVariableInfoFlags argumentFlags, Type[] typeArguments = null, string[] argumentValues = null ) { var serializedTypeArgumentNames = typeArguments ?.Select(t => t?.AssemblyQualifiedName) .ToArray(); return(GetName( source, methodName, argumentFlags, serializedTypeArgumentNames, argumentValues )); }
private string GetName(string source, string methodName, DkmVariableInfoFlags argumentFlags, params string[] argumentValues) { Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types)) == argumentFlags, "Unexpected argumentFlags", "argumentFlags = {0}", argumentFlags); var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll); var runtime = CreateRuntimeInstance(compilation); var moduleInstances = runtime.Modules; var blocks = moduleInstances.SelectAsArray(m => m.MetadataBlock); compilation = blocks.ToCompilation(); var frame = (PEMethodSymbol)GetMethodOrTypeBySignature(compilation, methodName); // Once we have the method token, we want to look up the method (again) // using the same helper as the product code. This helper will also map // async/iterator "MoveNext" methods to the original source method. var method = compilation.GetSourceMethod( ((PEModuleSymbol)frame.ContainingModule).Module.GetModuleVersionIdOrThrow(), MetadataTokens.GetToken(frame.Handle)); var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); ArrayBuilder<string> builder = null; if (argumentValues.Length > 0) { builder = ArrayBuilder<string>.GetInstance(); builder.AddRange(argumentValues); } var frameDecoder = CSharpInstructionDecoder.Instance; var frameName = frameDecoder.GetName(method, includeParameterTypes, includeParameterNames, builder); if (builder != null) { builder.Free(); } return frameName; }
void IDkmLanguageFrameDecoder.GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { if (frame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid) { Debug.Fail("GetFrameName called on a non-Python frame."); throw new NotSupportedException(); } var filter = frame.Process.GetDataItem <CallStackFilter>(); if (filter == null) { Debug.Fail("GetFrameName called, but no instance of CallStackFilter is there to handle it."); throw new InvalidOperationException(); } filter.GetFrameName(inspectionContext, workList, frame, argumentFlags, completionRoutine); }
private void GetFrameName( DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine, TMethodSymbol method) { var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); if (argumentFlags.Includes(DkmVariableInfoFlags.Values)) { // No need to compute the Expandable bit on // argument values since that can be expensive. inspectionContext = DkmInspectionContext.Create( inspectionContext.InspectionSession, inspectionContext.RuntimeInstance, inspectionContext.Thread, inspectionContext.Timeout, inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoExpansion, inspectionContext.FuncEvalFlags, inspectionContext.Radix, inspectionContext.Language, inspectionContext.ReturnValue, inspectionContext.AdditionalVisualizationData, inspectionContext.AdditionalVisualizationDataPriority, inspectionContext.ReturnValues); // GetFrameArguments returns an array of formatted argument values. We'll pass // ourselves (GetFrameName) as the continuation of the GetFrameArguments call. inspectionContext.GetFrameArguments( workList, frame, result => { var argumentValues = result.Arguments; try { var builder = ArrayBuilder <string> .GetInstance(); foreach (var argument in argumentValues) { var formattedArgument = argument as DkmSuccessEvaluationResult; // Not expecting Expandable bit, at least not from this EE. Debug.Assert((formattedArgument == null) || (formattedArgument.Flags & DkmEvaluationResultFlags.Expandable) == 0); builder.Add(formattedArgument?.Value); } var frameName = _instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, builder); builder.Free(); completionRoutine(new DkmGetFrameNameAsyncResult(frameName)); } catch (Exception e) when(ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { completionRoutine(DkmGetFrameNameAsyncResult.CreateErrorResult(e)); } finally { foreach (var argument in argumentValues) { argument.Close(); } } }); } else { var frameName = _instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, null); completionRoutine(new DkmGetFrameNameAsyncResult(frameName)); } }
private static string TryGetFrameNameHelper(DkmInspectionContext inspectionContext, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags) { ImportedMethod currentMethod = TryGetCurrentMethod(inspectionContext, frame); if (currentMethod == null) { return(null); } string name = currentMethod.Name; if (argumentFlags == DkmVariableInfoFlags.None) { return(name); } var type = currentMethod.DeclaringType; if (type.IsStatic && type.Name == "Functions") { ; // No prefix for 'normal' functions } else { // static or instance method ? if (currentMethod.IsStatic) { name = type.FullName + "." + name; } else { name = type.FullName + ":" + name; } } Variable[] args = currentMethod.GetParameters(); if (args.Length == 0) { return(name + "()"); } StringBuilder nameBuilder = new StringBuilder(); nameBuilder.Append(name); nameBuilder.Append('('); bool first = true; bool showTypes = argumentFlags.HasFlag(DkmVariableInfoFlags.Types); bool showNames = argumentFlags.HasFlag(DkmVariableInfoFlags.Names); foreach (Variable arg in args) { if (first) { first = false; } else { nameBuilder.Append(", "); } XSharpType argType = arg.Type; if (showNames) { nameBuilder.Append(arg.Name); } if (showNames && showTypes) { if (arg.In && arg.Out) { nameBuilder.Append(" REF "); } else if (arg.Out) { nameBuilder.Append(" OUT "); } else { nameBuilder.Append(" AS "); } } if (showTypes) { nameBuilder.Append(argType.ToString()); } } nameBuilder.Append(')'); var result = nameBuilder.ToString(); if (result.Contains(clArgs)) { result = result.Replace(clArgs, "[ClipperArguments]"); } return(result); }
void IDkmLanguageFrameDecoder.GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { _languageFrameDecoder.GetFrameName(inspectionContext, workList, frame, argumentFlags, completionRoutine); }
internal static bool Includes(this DkmVariableInfoFlags flags, DkmVariableInfoFlags desired) { return((flags & desired) == desired); }
string IDkmLanguageInstructionDecoder.GetMethodName(DkmLanguageInstructionAddress languageInstructionAddress, DkmVariableInfoFlags argumentFlags) { return(_languageInstructionDecoder.GetMethodName(languageInstructionAddress, argumentFlags)); }
public void GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { var insAddr = frame.InstructionAddress as DkmCustomInstructionAddress; if (insAddr == null) { Debug.Fail("GetFrameName called on a Python frame without a proper instruction address."); throw new InvalidOperationException(); } var loc = new SourceLocation(insAddr.AdditionalData, frame.Process); completionRoutine(new DkmGetFrameNameAsyncResult(loc.FunctionName)); }
void IDkmLanguageFrameDecoder.GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine <DkmGetFrameNameAsyncResult> completionRoutine) { try { Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types | DkmVariableInfoFlags.Values)) == argumentFlags, "Unexpected argumentFlags", "argumentFlags = {0}", argumentFlags); var instructionAddress = (DkmClrInstructionAddress)frame.InstructionAddress; var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); if (argumentFlags.Includes(DkmVariableInfoFlags.Values)) { // No need to compute the Expandable bit on // argument values since that can be expensive. inspectionContext = DkmInspectionContext.Create( inspectionContext.InspectionSession, inspectionContext.RuntimeInstance, inspectionContext.Thread, inspectionContext.Timeout, inspectionContext.EvaluationFlags | DkmEvaluationFlags.NoExpansion, inspectionContext.FuncEvalFlags, inspectionContext.Radix, inspectionContext.Language, inspectionContext.ReturnValue, inspectionContext.AdditionalVisualizationData, inspectionContext.AdditionalVisualizationDataPriority, inspectionContext.ReturnValues); // GetFrameArguments returns an array of formatted argument values. We'll pass // ourselves (GetFrameName) as the continuation of the GetFrameArguments call. inspectionContext.GetFrameArguments( workList, frame, result => { try { var builder = ArrayBuilder <string> .GetInstance(); foreach (var argument in result.Arguments) { var evaluatedArgument = argument as DkmSuccessEvaluationResult; // Not expecting Expandable bit, at least not from this EE. Debug.Assert((evaluatedArgument == null) || (evaluatedArgument.Flags & DkmEvaluationResultFlags.Expandable) == 0); builder.Add((evaluatedArgument != null) ? evaluatedArgument.Value : null); } var frameName = _instructionDecoder.GetName(instructionAddress, includeParameterTypes, includeParameterNames, builder); builder.Free(); completionRoutine(new DkmGetFrameNameAsyncResult(frameName)); } // TODO: Consider calling DkmComponentManager.ReportCurrentNonFatalException() to // trigger a non-fatal Watson when this occurs. catch (Exception e) when(!ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e)) { completionRoutine(DkmGetFrameNameAsyncResult.CreateErrorResult(e)); } finally { foreach (var argument in result.Arguments) { argument.Close(); } } }); } else { var frameName = _instructionDecoder.GetName(instructionAddress, includeParameterTypes, includeParameterNames, null); completionRoutine(new DkmGetFrameNameAsyncResult(frameName)); } } catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e)) { throw ExceptionUtilities.Unreachable; } }
private string GetName(string source, string methodName, DkmVariableInfoFlags argumentFlags, Type[] typeArguments = null, string[] argumentValues = null) { var serializedTypeArgumentNames = typeArguments?.Select(t => t?.AssemblyQualifiedName).ToArray(); return GetName(source, methodName, argumentFlags, serializedTypeArgumentNames, argumentValues); }
public void GetFrameName(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags, DkmCompletionRoutine<DkmGetFrameNameAsyncResult> completionRoutine) { var insAddr = frame.InstructionAddress as DkmCustomInstructionAddress; if (insAddr == null) { Debug.Fail("GetFrameName called on a Python frame without a proper instruction address."); throw new InvalidOperationException(); } var loc = new SourceLocation(insAddr.AdditionalData, frame.Process); completionRoutine(new DkmGetFrameNameAsyncResult(loc.FunctionName)); }
private string GetName(string source, string methodName, DkmVariableInfoFlags argumentFlags, string[] typeArguments, string[] argumentValues = null) { Debug.Assert((argumentFlags & (DkmVariableInfoFlags.Names | DkmVariableInfoFlags.Types)) == argumentFlags, "Unexpected argumentFlags", "argumentFlags = {0}", argumentFlags); var instructionDecoder = CSharpInstructionDecoder.Instance; var method = GetConstructedMethod(source, methodName, typeArguments, instructionDecoder); var includeParameterTypes = argumentFlags.Includes(DkmVariableInfoFlags.Types); var includeParameterNames = argumentFlags.Includes(DkmVariableInfoFlags.Names); ArrayBuilder<string> builder = null; if (argumentValues != null) { builder = ArrayBuilder<string>.GetInstance(); builder.AddRange(argumentValues); } var name = instructionDecoder.GetName(method, includeParameterTypes, includeParameterNames, builder); if (builder != null) { builder.Free(); } return name; }
private static string TryGetFrameNameHelper(DkmInspectionContext inspectionContext, DkmStackWalkFrame frame, DkmVariableInfoFlags argumentFlags) { ImportedMethod currentMethod = TryGetCurrentMethod(inspectionContext, frame); if (currentMethod == null) { return(null); } string name = currentMethod.Name; if (string.Equals(name, "$.main", StringComparison.Ordinal)) { return("<Main Block>"); } if (argumentFlags == DkmVariableInfoFlags.None) { return(name); } Variable[] args = currentMethod.GetParameters(); if (args.Length == 0) { return(name); } StringBuilder nameBuilder = new StringBuilder(); nameBuilder.Append(name); nameBuilder.Append('('); bool first = true; bool showTypes = argumentFlags.HasFlag(DkmVariableInfoFlags.Types); bool showNames = argumentFlags.HasFlag(DkmVariableInfoFlags.Names); foreach (Variable arg in args) { if (first) { first = false; } else { nameBuilder.Append("; "); } IrisType argType = arg.Type; if (argType.IsByRef) { nameBuilder.Append("var "); argType = argType.GetElementType(); } if (showNames) { nameBuilder.Append(arg.Name); } if (showNames && showTypes) { nameBuilder.Append(" : "); } if (showTypes) { nameBuilder.Append(argType); } } nameBuilder.Append(')'); return(nameBuilder.ToString()); }