private static void EvaluateDebuggerDisplayStringAndContinue( DkmClrValue value, WorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string str, CompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> onCompleted, CompletionRoutine <Exception> onException) { DkmCompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine = result => { try { onCompleted(result); } catch (Exception e) when(ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { onException(e); } }; if (str == null) { completionRoutine(default(DkmEvaluateDebuggerDisplayStringAsyncResult)); } else { value.EvaluateDebuggerDisplayString(workList.InnerWorkList, inspectionContext, targetType, str, completionRoutine); } }
private void GetResultAndContinue( EvalResult result, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, bool useDebuggerDisplay, CompletionRoutine <DkmEvaluationResult> completionRoutine) { var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine <Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext)); var innerWorkList = workList.InnerWorkList; EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name, displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value, displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName, displayType => workList.ContinueWith(() => completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))), onException), onException), onException); } else { completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false)); } }
private static void EvaluateDebuggerDisplayStringAndContinue( DkmClrValue value, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string str, CompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> onCompleted, CompletionRoutine <Exception> onException) { DkmCompletionRoutine <DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine = result => { try { onCompleted(result); } catch (Exception e) { onException(e); } }; if (str == null) { completionRoutine(default(DkmEvaluateDebuggerDisplayStringAsyncResult)); } else { value.EvaluateDebuggerDisplayString(workList, inspectionContext, targetType, str, completionRoutine); } }
internal void GetResultAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmClrType declaredType, DkmInspectionContext inspectionContext, EvalResultDataItem parent, CompletionRoutine <DkmEvaluationResult> completionRoutine) { var value = dataItem.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine <Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, dataItem, inspectionContext)); value.EvaluateDebuggerDisplayStringAndContinue(workList, inspectionContext, targetType, attribute.Name, displayName => ContinueWithExceptionHandling( () => value.EvaluateDebuggerDisplayStringAndContinue(workList, inspectionContext, targetType, attribute.Value, displayValue => ContinueWithExceptionHandling( () => value.EvaluateDebuggerDisplayStringAndContinue(workList, inspectionContext, targetType, attribute.TypeName, displayType => ContinueWithExceptionHandling( () => completionRoutine(GetResult(inspectionContext, dataItem, declaredType, displayName.Result, displayValue.Result, displayType.Result, parent)), onException)), onException)), onException)); } else { completionRoutine(GetResult(inspectionContext, dataItem, declaredType, displayName: null, displayValue: null, displayType: null, parent: parent)); } }
/// <summary> /// Run the continuation synchronously if there is no current /// continuation. Otherwise hold on to the continuation for /// the current execution to complete. /// </summary> internal void ContinueWith(CompletionRoutine completionRoutine) { Debug.Assert(_completionRoutine == null); _completionRoutine = completionRoutine; if (_state != State.Executing) { Execute(); } }
internal static void ContinueWithExceptionHandling(CompletionRoutine onCompleted, CompletionRoutine <Exception> onException) { try { onCompleted(); } catch (Exception e) when(ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { onException(e); } }
void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine <DkmGetChildrenAsyncResult> completionRoutine) { var dataItem = evaluationResult.GetDataItem <EvalResultDataItem>(); if (dataItem == null) { // We don't know about this result. Call next implementation evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine); return; } var expansion = dataItem.Expansion; if (expansion == null) { var enumContext = DkmEvaluationResultEnumContext.Create(0, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult)); completionRoutine(new DkmGetChildrenAsyncResult(new DkmEvaluationResult[0], enumContext)); return; } // Evaluate children with InspectionContext that is not the root. inspectionContext = inspectionContext.With(NotRoot); var rows = ArrayBuilder <EvalResult> .GetInstance(); int index = 0; expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, 0, initialRequestSize, visitAll: true, index: ref index); var numRows = rows.Count; Debug.Assert(index >= numRows); Debug.Assert(initialRequestSize >= numRows); var initialChildren = new DkmEvaluationResult[numRows]; CompletionRoutine <Exception> onException = e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e)); var wl = new WorkList(workList, onException); wl.ContinueWith(() => GetEvaluationResultsAndContinue(evaluationResult, rows, initialChildren, 0, numRows, wl, inspectionContext, () => wl.ContinueWith( () => { var enumContext = DkmEvaluationResultEnumContext.Create(index, evaluationResult.StackFrame, inspectionContext, new EnumContextDataItem(evaluationResult)); completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext)); rows.Free(); }), onException)); }
internal void Execute() { while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) when(ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { _onException(e); } } }
internal void Execute() { while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) { _onException(e); } } }
void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine <DkmEvaluationEnumAsyncResult> completionRoutine) { var enumContextDataItem = enumContext.GetDataItem <EnumContextDataItem>(); if (enumContextDataItem == null) { // We don't know about this result. Call next implementation enumContext.GetItems(workList, startIndex, count, completionRoutine); return; } var evaluationResult = enumContextDataItem.Result; var dataItem = evaluationResult.GetDataItem <EvalResultDataItem>(); var expansion = dataItem.Expansion; if (expansion == null) { completionRoutine(new DkmEvaluationEnumAsyncResult(new DkmEvaluationResult[0])); return; } var inspectionContext = enumContext.InspectionContext; var rows = ArrayBuilder <EvalResult> .GetInstance(); int index = 0; expansion.GetRows(this, rows, inspectionContext, dataItem, dataItem.Value, startIndex, count, visitAll: false, index: ref index); var numRows = rows.Count; Debug.Assert(count >= numRows); var results = new DkmEvaluationResult[numRows]; CompletionRoutine <Exception> onException = e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e)); var wl = new WorkList(workList, onException); wl.ContinueWith(() => GetEvaluationResultsAndContinue(evaluationResult, rows, results, 0, numRows, wl, inspectionContext, () => wl.ContinueWith( () => { completionRoutine(new DkmEvaluationEnumAsyncResult(results)); rows.Free(); }), onException)); }
private void Execute() { Debug.Assert(_state != State.Executing); _state = State.Executing; while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) { _onException(e); } } _state = State.Executed; }
private void GetEvaluationResultsAndContinue( DkmEvaluationResult parent, ArrayBuilder <EvalResult> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, CompletionRoutine onCompleted, CompletionRoutine <Exception> onException) { DkmCompletionRoutine <DkmEvaluationAsyncResult> completionRoutine = result => { try { results[index] = result.Result; GetEvaluationResultsAndContinue(parent, rows, results, index + 1, numRows, workList, inspectionContext, onCompleted, onException); } catch (Exception e) { onException(e); } }; if (index < numRows) { GetChild( parent, workList, rows[index], child => workList.ContinueWith(() => completionRoutine(child))); } else { onCompleted(); } }
private void GetRootResultAndContinue(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmInspectionContext inspectionContext, string resultName, CompletionRoutine <DkmEvaluationResult> completionRoutine) { var type = value.Type.GetLmrType(); if (type.IsTypeVariables()) { var expansion = new TypeVariablesExpansion(type); var dataItem = new EvalResultDataItem( ExpansionKind.Default, resultName, typeDeclaringMember: null, declaredType: type, parent: null, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable)); // Note: We're not including value.EvalFlags in Flags parameter // below (there shouldn't be a reason to do so). completionRoutine(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.TypeVariablesName, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: "", EditableValue: null, Type: "", Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); } else { if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0) { CreateEvaluationResultAndContinue( ResultsViewExpansion.CreateResultsOnlyRow(inspectionContext, resultName, declaredType, value, null, this.Formatter), workList, inspectionContext, value.StackFrame, completionRoutine); } else { ReadOnlyCollection <string> formatSpecifiers; var fullName = this.Formatter.TrimAndGetFormatSpecifiers(resultName, out formatSpecifiers); var dataItem = CreateDataItem( inspectionContext, resultName, typeDeclaringMember: null, declaredType: declaredType.GetLmrType(), value: value, parent: null, expansionFlags: ExpansionFlags.All, childShouldParenthesize: this.Formatter.NeedsParentheses(fullName), fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: value.EvalFlags, evalFlags: inspectionContext.EvaluationFlags); GetResultAndContinue(dataItem, workList, declaredType, inspectionContext, parent: null, completionRoutine: completionRoutine); } } }
private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine) { switch (dataItem.Kind) { case ExpansionKind.Error: completionRoutine(DkmFailedEvaluationResult.Create( inspectionContext, StackFrame: stackFrame, Name: dataItem.Name, FullName: dataItem.FullName, ErrorMessage: dataItem.DisplayValue, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); break; case ExpansionKind.NonPublicMembers: case ExpansionKind.StaticMembers: completionRoutine(CreateEvaluationResult( inspectionContext, dataItem.Value, dataItem.Name, typeName: string.Empty, display: null, dataItem: dataItem)); break; case ExpansionKind.RawView: completionRoutine(CreateEvaluationResult( inspectionContext, dataItem.Value, Resources.RawView, typeName: string.Empty, display: null, dataItem: dataItem)); break; case ExpansionKind.ResultsView: completionRoutine(CreateEvaluationResult( inspectionContext, dataItem.Value, dataItem.Name, typeName: string.Empty, display: Resources.ResultsViewValueWarning, dataItem: dataItem)); break; case ExpansionKind.TypeVariables: var value = dataItem.Value; completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, dataItem.Name, dataItem.FullName, dataItem.Flags, dataItem.DisplayValue, EditableValue: null, Type: dataItem.DisplayValue, Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; default: Debug.Assert((dataItem.Kind == ExpansionKind.Default) || (dataItem.Kind == ExpansionKind.PointerDereference)); // This call will evaluate DebuggerDisplayAttributes. GetResultAndContinue( dataItem, workList, declaredType: DkmClrType.Create(dataItem.Value.Type.AppDomain, dataItem.DeclaredType), inspectionContext: inspectionContext, parent: dataItem.Parent, completionRoutine: completionRoutine); break; } }
internal void ContinueWith(CompletionRoutine completionRoutine) { Debug.Assert(_completionRoutine == null); _completionRoutine = completionRoutine; }
private void GetResultAndContinue( EvalResultDataItem dataItem, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, EvalResultDataItem parent, CompletionRoutine<DkmEvaluationResult> completionRoutine) { var value = dataItem.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine<Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, dataItem, inspectionContext)); EvaluateDebuggerDisplayStringAndContinue(value, workList, inspectionContext, targetType, attribute.Name, displayName => EvaluateDebuggerDisplayStringAndContinue(value, workList, inspectionContext, targetType, attribute.Value, displayValue => EvaluateDebuggerDisplayStringAndContinue(value, workList, inspectionContext, targetType, attribute.TypeName, displayType => { completionRoutine(GetResult(inspectionContext, dataItem, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, parent)); }, onException), onException), onException); } else { completionRoutine(GetResult(inspectionContext, dataItem, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, parent: parent)); } }
private void CreateEvaluationResultAndContinue(EvalResultDataItem dataItem, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine<DkmEvaluationResult> completionRoutine) { switch (dataItem.Kind) { case ExpansionKind.Error: completionRoutine(DkmFailedEvaluationResult.Create( inspectionContext, StackFrame: stackFrame, Name: dataItem.Name, FullName: dataItem.FullName, ErrorMessage: dataItem.DisplayValue, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); break; case ExpansionKind.NativeView: { var value = dataItem.Value; var name = Resources.NativeView; var fullName = dataItem.FullName; var display = dataItem.Name; DkmEvaluationResult evalResult; if (value.IsError()) { evalResult = DkmFailedEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, ErrorMessage: display, Flags: dataItem.Flags, Type: null, DataItem: dataItem); } else { // For Native View, create a DkmIntermediateEvaluationResult. // This will allow the C++ EE to take over expansion. var process = inspectionContext.RuntimeInstance.Process; var cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); evalResult = DkmIntermediateEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, Expression: display, IntermediateLanguage: cpp, TargetRuntime: process.GetNativeRuntimeInstance(), DataItem: dataItem); } completionRoutine(evalResult); } break; case ExpansionKind.NonPublicMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.NonPublicMembers, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: dataItem.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; case ExpansionKind.StaticMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Formatter.StaticMembersString, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Class, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: dataItem.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; case ExpansionKind.RawView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.RawView, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: null, EditableValue: dataItem.EditableValue, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: dataItem.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; case ExpansionKind.DynamicView: case ExpansionKind.ResultsView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, dataItem.Name, dataItem.FullName, dataItem.Flags, dataItem.DisplayValue, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Method, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: dataItem.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; case ExpansionKind.TypeVariable: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, dataItem.Name, dataItem.FullName, dataItem.Flags, dataItem.DisplayValue, EditableValue: null, Type: dataItem.DisplayValue, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: dataItem.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); break; case ExpansionKind.PointerDereference: case ExpansionKind.Default: // This call will evaluate DebuggerDisplayAttributes. GetResultAndContinue( dataItem, workList, declaredType: DkmClrType.Create(dataItem.Value.Type.AppDomain, dataItem.DeclaredTypeAndInfo.Type), declaredTypeInfo: dataItem.DeclaredTypeAndInfo.Info, inspectionContext: inspectionContext, parent: dataItem.Parent, completionRoutine: completionRoutine); break; default: throw ExceptionUtilities.UnexpectedValue(dataItem.Kind); } }
private void GetEvaluationResultsAndContinue(ArrayBuilder <EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine) { if (index >= numRows) { completionRoutine(); } else { CreateEvaluationResultAndContinue(rows[index], workList, inspectionContext, stackFrame, result => ContinueWithExceptionHandling( () => StoreResultAndContinue(result, rows, results, index, numRows, workList, inspectionContext, stackFrame, completionRoutine), e => { // If we fail to store a result, just stop enumerating rows (rather than attempting to store // an error message in the current row, etc). This is because it may have been the act of // indexing into the results store that threw (so it would just throw again here). The user // experience is less than ideal (there's no real indication that something went wrong), // however, it seems like it's better to enumerate/display some rows than none. We will // receive a non-fatal Watson report in this case, so the problem won't go unnoticed. completionRoutine(); })); } }
internal void ContinueWith(CompletionRoutine completionRoutine) { Debug.Assert(_completionRoutine == null); _completionRoutine = completionRoutine; }
private void GetEvaluationResultsAndContinue(ArrayBuilder<EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine) { if (index < numRows) { CreateEvaluationResultAndContinue(rows[index], workList, inspectionContext, stackFrame, result => workList.ContinueWith( () => { results[index] = result; GetEvaluationResultsAndContinue(rows, results, index + 1, numRows, workList, inspectionContext, stackFrame, completionRoutine); })); } else { completionRoutine(); } }
internal void Execute() { while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) when (ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { _onException(e); } } }
internal WorkList(DkmWorkList workList, CompletionRoutine <Exception> onException) { InnerWorkList = workList; _onException = onException; _state = State.Initialized; }
private void GetEvaluationResultsAndContinue(ArrayBuilder <EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine) { if (index < numRows) { CreateEvaluationResultAndContinue(rows[index], workList, inspectionContext, stackFrame, result => workList.ContinueWith( () => { results[index] = result; GetEvaluationResultsAndContinue(rows, results, index + 1, numRows, workList, inspectionContext, stackFrame, completionRoutine); })); } else { completionRoutine(); } }
internal WorkList(DkmWorkList workList, CompletionRoutine<Exception> onException) { InnerWorkList = workList; _onException = onException; _state = State.Initialized; }
private void GetResultAndContinue( EvalResult result, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, bool useDebuggerDisplay, CompletionRoutine<DkmEvaluationResult> completionRoutine) { var value = result.Value; // Value may have been replaced (specifically, for Nullable<T>). DebuggerDisplayInfo displayInfo; if (value.TryGetDebuggerDisplayInfo(out displayInfo)) { var targetType = displayInfo.TargetType; var attribute = displayInfo.Attribute; CompletionRoutine<Exception> onException = e => completionRoutine(CreateEvaluationResultFromException(e, result, inspectionContext)); var innerWorkList = workList.InnerWorkList; EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Name, displayName => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.Value, displayValue => EvaluateDebuggerDisplayStringAndContinue(value, innerWorkList, inspectionContext, targetType, attribute.TypeName, displayType => workList.ContinueWith(() => completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName.Result, displayValue.Result, displayType.Result, useDebuggerDisplay))), onException), onException), onException); } else { completionRoutine(GetResult(inspectionContext, result, declaredType, declaredTypeInfo, displayName: null, displayValue: null, displayType: null, useDebuggerDisplay: false)); } }
private void StoreResultAndContinue(DkmEvaluationResult result, ArrayBuilder <EvalResultDataItem> rows, DkmEvaluationResult[] results, int index, int numRows, DkmWorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine completionRoutine) { results[index] = result; index++; if (index < numRows) { GetEvaluationResultsAndContinue(rows, results, index, numRows, workList, inspectionContext, stackFrame, completionRoutine); } else { completionRoutine(); } }
private void GetRootResultAndContinue( DkmClrValue value, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, string name, string fullName, ReadOnlyCollection <string> formatSpecifiers, CompletionRoutine <DkmEvaluationResult> completionRoutine) { Debug.Assert(formatSpecifiers != null); var type = value.Type.GetLmrType(); if (type.IsTypeVariables()) { Debug.Assert(type.Equals(declaredType.GetLmrType())); var declaredTypeAndInfo = new TypeAndCustomInfo(declaredType, declaredTypeInfo); var expansion = new TypeVariablesExpansion(declaredTypeAndInfo); var dataItem = new EvalResult( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, useDebuggerDisplay: false, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable)); // Note: We're not including value.EvalFlags in Flags parameter // below (there shouldn't be a reason to do so). completionRoutine(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.TypeVariablesName, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: "", EditableValue: null, Type: "", Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem.ToDataItem())); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0) { var dataItem = ResultsViewExpansion.CreateResultsOnlyRow( inspectionContext, name, fullName, formatSpecifiers, declaredType, declaredTypeInfo, value, this); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0) { var dataItem = DynamicViewExpansion.CreateMembersOnlyRow( inspectionContext, name, value, this); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable( inspectionContext, name, fullName, formatSpecifiers, declaredType, declaredTypeInfo, value, this); if (dataItem != null) { CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var useDebuggerDisplay = (inspectionContext.EvaluationFlags & NotRoot) != 0; var expansionFlags = (inspectionContext.EvaluationFlags & NoResults) != 0 ? ExpansionFlags.IncludeBaseMembers : ExpansionFlags.All; dataItem = CreateDataItem( inspectionContext, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: new TypeAndCustomInfo(declaredType, declaredTypeInfo), value: value, useDebuggerDisplay: useDebuggerDisplay, expansionFlags: expansionFlags, childShouldParenthesize: (fullName == null) ? false : FullNameProvider.ClrExpressionMayRequireParentheses(inspectionContext, fullName), fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: value.EvalFlags, evalFlags: inspectionContext.EvaluationFlags); GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, useDebuggerDisplay, completionRoutine); } } }
private void GetEvaluationResultsAndContinue( DkmEvaluationResult parent, ArrayBuilder<EvalResult> rows, DkmEvaluationResult[] results, int index, int numRows, WorkList workList, DkmInspectionContext inspectionContext, CompletionRoutine onCompleted, CompletionRoutine<Exception> onException) { DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine = result => { try { results[index] = result.Result; GetEvaluationResultsAndContinue(parent, rows, results, index + 1, numRows, workList, inspectionContext, onCompleted, onException); } catch (Exception e) { onException(e); } }; if (index < numRows) { GetChild( parent, workList, rows[index], child => workList.ContinueWith(() => completionRoutine(child))); } else { onCompleted(); } }
private static void EvaluateDebuggerDisplayStringAndContinue( DkmClrValue value, WorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string str, CompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> onCompleted, CompletionRoutine<Exception> onException) { DkmCompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine = result => { try { onCompleted(result); } catch (Exception e) when (ExpressionEvaluatorFatalError.ReportNonFatalException(e, DkmComponentManager.ReportCurrentNonFatalException)) { onException(e); } }; if (str == null) { completionRoutine(default(DkmEvaluateDebuggerDisplayStringAsyncResult)); } else { value.EvaluateDebuggerDisplayString(workList.InnerWorkList, inspectionContext, targetType, str, completionRoutine); } }
private void GetRootResultAndContinue( DkmClrValue value, WorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, string name, CompletionRoutine<DkmEvaluationResult> completionRoutine) { var type = value.Type.GetLmrType(); if (type.IsTypeVariables()) { Debug.Assert(type.Equals(declaredType.GetLmrType())); var declaredTypeAndInfo = new TypeAndCustomInfo(type, declaredTypeInfo); var expansion = new TypeVariablesExpansion(declaredTypeAndInfo); var dataItem = new EvalResultDataItem( ExpansionKind.Default, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: declaredTypeAndInfo, parent: null, value: value, displayValue: null, expansion: expansion, childShouldParenthesize: false, fullName: null, childFullNamePrefixOpt: null, formatSpecifiers: Formatter.NoFormatSpecifiers, category: DkmEvaluationResultCategory.Data, flags: DkmEvaluationResultFlags.ReadOnly, editableValue: null, inspectionContext: inspectionContext); Debug.Assert(dataItem.Flags == (DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable)); // Note: We're not including value.EvalFlags in Flags parameter // below (there shouldn't be a reason to do so). completionRoutine(DkmSuccessEvaluationResult.Create( InspectionContext: inspectionContext, StackFrame: value.StackFrame, Name: Resources.TypeVariablesName, FullName: dataItem.FullName, Flags: dataItem.Flags, Value: "", EditableValue: null, Type: "", Category: dataItem.Category, Access: value.Access, StorageType: value.StorageType, TypeModifierFlags: value.TypeModifierFlags, Address: value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: dataItem)); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.ResultsOnly) != 0) { var dataItem = ResultsViewExpansion.CreateResultsOnlyRow( inspectionContext, name, declaredType, declaredTypeInfo, value, this.Formatter); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else if ((inspectionContext.EvaluationFlags & DkmEvaluationFlags.DynamicView) != 0) { var dataItem = DynamicViewExpansion.CreateMembersOnlyRow( inspectionContext, name, value, this.Formatter); CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { var dataItem = ResultsViewExpansion.CreateResultsOnlyRowIfSynthesizedEnumerable( inspectionContext, name, declaredType, declaredTypeInfo, value, this.Formatter); if (dataItem != null) { CreateEvaluationResultAndContinue( dataItem, workList, inspectionContext, value.StackFrame, completionRoutine); } else { ReadOnlyCollection<string> formatSpecifiers; var fullName = this.Formatter.TrimAndGetFormatSpecifiers(name, out formatSpecifiers); dataItem = CreateDataItem( inspectionContext, name, typeDeclaringMemberAndInfo: default(TypeAndCustomInfo), declaredTypeAndInfo: new TypeAndCustomInfo(declaredType.GetLmrType(), declaredTypeInfo), value: value, parent: null, expansionFlags: ExpansionFlags.All, childShouldParenthesize: this.Formatter.NeedsParentheses(fullName), fullName: fullName, formatSpecifiers: formatSpecifiers, category: DkmEvaluationResultCategory.Other, flags: value.EvalFlags, evalFlags: inspectionContext.EvaluationFlags); GetResultAndContinue(dataItem, workList, declaredType, declaredTypeInfo, inspectionContext, parent: null, completionRoutine: completionRoutine); } } }
/// <summary> /// Run the continuation synchronously if there is no current /// continuation. Otherwise hold on to the continuation for /// the current execution to complete. /// </summary> internal void ContinueWith(CompletionRoutine completionRoutine) { Debug.Assert(_completionRoutine == null); _completionRoutine = completionRoutine; if (_state != State.Executing) { Execute(); } }
private static void EvaluateDebuggerDisplayStringAndContinue( DkmClrValue value, WorkList workList, DkmInspectionContext inspectionContext, DkmClrType targetType, string str, CompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> onCompleted, CompletionRoutine<Exception> onException) { DkmCompletionRoutine<DkmEvaluateDebuggerDisplayStringAsyncResult> completionRoutine = result => { try { onCompleted(result); } catch (Exception e) { onException(e); } workList.Execute(); }; if (str == null) { completionRoutine(default(DkmEvaluateDebuggerDisplayStringAsyncResult)); } else { value.EvaluateDebuggerDisplayString(workList.InnerWorkList, inspectionContext, targetType, str, completionRoutine); } }
internal WorkList(DkmWorkList workList, CompletionRoutine <Exception> onException) { InnerWorkList = workList; _onException = onException; }
internal WorkList(DkmWorkList workList, CompletionRoutine<Exception> onException) { InnerWorkList = workList; _onException = onException; }
private void CreateEvaluationResultAndContinue(EvalResult result, WorkList workList, DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame, CompletionRoutine <DkmEvaluationResult> completionRoutine) { switch (result.Kind) { case ExpansionKind.Error: completionRoutine(DkmFailedEvaluationResult.Create( inspectionContext, StackFrame: stackFrame, Name: result.Name, FullName: result.FullName, ErrorMessage: result.DisplayValue, Flags: DkmEvaluationResultFlags.None, Type: null, DataItem: null)); break; case ExpansionKind.NativeView: { var value = result.Value; var name = Resources.NativeView; var fullName = result.FullName; var display = result.Name; DkmEvaluationResult evalResult; if (value.IsError()) { evalResult = DkmFailedEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, ErrorMessage: display, Flags: result.Flags, Type: null, DataItem: result.ToDataItem()); } else { // For Native View, create a DkmIntermediateEvaluationResult. // This will allow the C++ EE to take over expansion. var process = inspectionContext.RuntimeInstance.Process; var cpp = process.EngineSettings.GetLanguage(new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp)); evalResult = DkmIntermediateEvaluationResult.Create( inspectionContext, stackFrame, Name: name, FullName: fullName, Expression: display, IntermediateLanguage: cpp, TargetRuntime: process.GetNativeRuntimeInstance(), DataItem: result.ToDataItem()); } completionRoutine(evalResult); } break; case ExpansionKind.NonPublicMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.NonPublicMembers, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.StaticMembers: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: StaticMembersString, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Class, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.RawView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, Name: Resources.RawView, FullName: result.FullName, Flags: result.Flags, Value: null, EditableValue: result.EditableValue, Type: string.Empty, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.DynamicView: case ExpansionKind.ResultsView: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: string.Empty, Category: DkmEvaluationResultCategory.Method, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.TypeVariable: completionRoutine(DkmSuccessEvaluationResult.Create( inspectionContext, stackFrame, result.Name, result.FullName, result.Flags, result.DisplayValue, EditableValue: null, Type: result.DisplayValue, Category: DkmEvaluationResultCategory.Data, Access: DkmEvaluationResultAccessType.None, StorageType: DkmEvaluationResultStorageType.None, TypeModifierFlags: DkmEvaluationResultTypeModifierFlags.None, Address: result.Value.Address, CustomUIVisualizers: null, ExternalModules: null, DataItem: result.ToDataItem())); break; case ExpansionKind.PointerDereference: case ExpansionKind.Default: // This call will evaluate DebuggerDisplayAttributes. GetResultAndContinue( result, workList, declaredType: result.DeclaredTypeAndInfo.ClrType, declaredTypeInfo: result.DeclaredTypeAndInfo.Info, inspectionContext: inspectionContext, useDebuggerDisplay: result.UseDebuggerDisplay, completionRoutine: completionRoutine); break; default: throw ExceptionUtilities.UnexpectedValue(result.Kind); } }
internal void Execute() { while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) { _onException(e); } } }
private void Execute() { Debug.Assert(_state != State.Executing); _state = State.Executing; while (_completionRoutine != null) { var completionRoutine = _completionRoutine; _completionRoutine = null; try { completionRoutine(); } catch (Exception e) { _onException(e); } } _state = State.Executed; }