public static void VscxOnModuleInstanceLoad(this DkmProcess process, DkmModuleInstance module, DkmWorkList workList) {
      AutoAttachToChildHandler handler = process.GetDataItem<AutoAttachToChildHandler>();
      if (handler == null || module.TagValue != DkmModuleInstance.Tag.NativeModuleInstance)
        return;

      handler.OnModuleInstanceLoad((DkmNativeModuleInstance)module, workList);
    }
示例#2
0
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     if (formatSpecifiers == null)
     {
         formatSpecifiers = Formatter.NoFormatSpecifiers;
     }
     if (resultFullName != null)
     {
         ReadOnlyCollection<string> otherSpecifiers;
         resultFullName = FullNameProvider.GetClrExpressionAndFormatSpecifiers(inspectionContext, resultFullName, out otherSpecifiers);
         foreach (var formatSpecifier in otherSpecifiers)
         {
             formatSpecifiers = Formatter.AddFormatSpecifier(formatSpecifiers, formatSpecifier);
         }
     }
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     wl.ContinueWith(
         () => GetRootResultAndContinue(
             value,
             wl,
             declaredType,
             declaredTypeInfo,
             inspectionContext,
             resultName,
             resultFullName,
             formatSpecifiers,
             result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result)))));
 }
 /// <summary>
 /// This method is called by the debug engine to get the text representation of the return
 /// value 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 of the return value for</param>
 /// <param name="completionRoutine">Completion routine to call when work is completed</param>
 void IDkmLanguageFrameDecoder.GetFrameReturnType(
     DkmInspectionContext inspectionContext,
     DkmWorkList workList,
     DkmStackWalkFrame frame,
     DkmCompletionRoutine<DkmGetFrameReturnTypeAsyncResult> completionRoutine)
 {
     string name = TryGetFrameReturnTypeHelper(inspectionContext, frame) ?? "<Unknown>";
     completionRoutine(new DkmGetFrameReturnTypeAsyncResult(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));
 }
示例#5
0
        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;
            }

            completionRoutine(GetChildren(inspectionContext, evaluationResult, dataItem, initialRequestSize));
        }
 void IDkmClrResultProvider.GetResult(DkmClrValue value, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo declaredTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     // TODO: Use full name
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationAsyncResult.CreateErrorResult(e)));
     GetRootResultAndContinue(
         value,
         wl,
         declaredType,
         declaredTypeInfo,
         inspectionContext,
         resultName,
         result => wl.ContinueWith(() => completionRoutine(new DkmEvaluationAsyncResult(result))));
     wl.Execute();
 }
    public void OnModuleInstanceLoad(DkmNativeModuleInstance module, DkmWorkList workList) {
      bool isKernel32 = module.Name.Equals(
          "Kernel32.dll", 
          StringComparison.CurrentCultureIgnoreCase);
      bool isAdvapi32 = module.Name.Equals(
          "Advapi32.dll", 
          StringComparison.CurrentCultureIgnoreCase);

      // For historical reasons, Kernel32.dll contains CreateProcess and Advapi32.dll contains
      // CreateProcessAsUser.
      if (isKernel32) {
        HookCreateProcess(module, 
                          "CreateProcessW",
                          CreateFrameAnalyzer(module, _createProcessParams));
      } else if (isAdvapi32) {
        HookCreateProcess(module, 
                          "CreateProcessAsUserW",
                          CreateFrameAnalyzer(module, _createProcessAsUserParams));
      }
    }
示例#8
0
        public void GetChildren(DkmEvaluationResult result, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) {
            var asyncEvalResult = result.GetDataItem<CppViewEvaluationResult>();
            if (asyncEvalResult != null) {
                asyncEvalResult.GetChildren(result, workList, initialRequestSize, inspectionContext, completionRoutine);
                return;
            }

            var pyEvalResult =
                (IPythonEvaluationResult)result.GetDataItem<PyObjectEvaluationResult>() ??
                (IPythonEvaluationResult)result.GetDataItem<GlobalsEvaluationResult>();
            if (pyEvalResult != null) {
                var childResults = pyEvalResult.GetChildren(this, result, inspectionContext);
                completionRoutine(
                    new DkmGetChildrenAsyncResult(
                        new DkmEvaluationResult[0],
                        DkmEvaluationResultEnumContext.Create(
                            childResults.Count,
                            result.StackFrame,
                            inspectionContext,
                            new EvaluationResults { Results = childResults.ToArray() })));
                return;
            }

            Debug.Fail("GetChildren called on an unsupported DkmEvaluationResult.");
            throw new NotSupportedException();
        }
示例#9
0
        public void GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine) {
            var evalResults = enumContext.GetDataItem<EvaluationResults>();
            if (evalResults == null) {
                Debug.Fail("GetItems called on a DkmEvaluationResultEnumContext without an associated EvaluationResults.");
                throw new NotSupportedException();
            }

            var result = evalResults.Results.Skip(startIndex).Take(count).ToArray();
            completionRoutine(new DkmEvaluationEnumAsyncResult(result));
        }
示例#10
0
 public void GetChildren(DkmEvaluationResult result, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine) {
     CppEvaluationResult.GetChildren(workList, initialRequestSize, CppEvaluationResult.InspectionContext, (cppResult) => {
         completionRoutine(cppResult);
     });
 }
示例#11
0
        public void GetFrameLocals(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmGetFrameLocalsAsyncResult> completionRoutine) {
            var pythonFrame = PyFrameObject.TryCreate(stackFrame);
            if (pythonFrame == null) {
                Debug.Fail("Non-Python frame passed to GetFrameLocals.");
                throw new NotSupportedException();
            }

            var cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
            var evalResults = new List<DkmEvaluationResult>();

            var f_code = pythonFrame.f_code.Read();
            var f_localsplus = pythonFrame.f_localsplus;

            // Process cellvars and freevars first, because function arguments can appear in both cellvars and varnames if the argument is captured by a closure,
            // in which case we want to use the cellvar because the regular var slot will then be unused by Python (and in Python 3.4+, nulled out).
            var namesSeen = new HashSet<string>();
            var cellNames = f_code.co_cellvars.Read().ReadElements().Concat(f_code.co_freevars.Read().ReadElements());
            var cellSlots = f_localsplus.Skip(f_code.co_nlocals.Read());
            foreach (var pair in cellNames.Zip(cellSlots, (nameObj, cellSlot) => new { nameObj, cellSlot = cellSlot })) {
                var nameObj = pair.nameObj;
                var cellSlot = pair.cellSlot;

                var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                if (name == null) {
                    continue;
                }
                namesSeen.Add(name);

                if (cellSlot.IsNull) {
                    continue;
                }

                var cell = cellSlot.Read() as PyCellObject;
                if (cell == null) {
                    continue;
                }

                var localPtr = cell.ob_ref;
                if (localPtr.IsNull) {
                    continue;
                }

                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(localPtr, name), cppEval);
                evalResults.Add(evalResult);
            }

            PyTupleObject co_varnames = f_code.co_varnames.Read();
            foreach (var pair in co_varnames.ReadElements().Zip(f_localsplus, (nameObj, varSlot) => new { nameObj, cellSlot = varSlot })) {
                var nameObj = pair.nameObj;
                var varSlot = pair.cellSlot;

                var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                if (name == null) {
                    continue;
                }

                // Check for function argument that was promoted to a cell.
                if (!namesSeen.Add(name)) {
                    continue;
                }

                if (varSlot.IsNull) {
                    continue;
                }

                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(varSlot, name), cppEval);
                evalResults.Add(evalResult);
            }

            var globals = pythonFrame.f_globals.TryRead();
            if (globals != null) {
                var globalsEvalResult = new GlobalsEvaluationResult { Globals = globals };
                DkmEvaluationResult evalResult = DkmSuccessEvaluationResult.Create(
                    inspectionContext, stackFrame, "[Globals]", null,
                    DkmEvaluationResultFlags.ReadOnly | DkmEvaluationResultFlags.Expandable,
                    null, null, null,
                    DkmEvaluationResultCategory.Property,
                    DkmEvaluationResultAccessType.None,
                    DkmEvaluationResultStorageType.None,
                    DkmEvaluationResultTypeModifierFlags.None,
                    null, null, null, globalsEvalResult);

                // If it is a top-level module frame, show globals inline; otherwise, show them under the [Globals] node.
                if (f_code.co_name.Read().ToStringOrNull() == "<module>") {
                    evalResults.AddRange(globalsEvalResult.GetChildren(this, evalResult, inspectionContext));
                } else {
                    evalResults.Add(evalResult);

                    // Show any globals that are directly referenced by the function inline even in local frames.
                    var globalVars = (from pair in globals.ReadElements()
                                      let nameObj = pair.Key as IPyBaseStringObject
                                      where nameObj != null
                                      select new { Name = nameObj.ToString(), Value = pair.Value }
                                     ).ToLookup(v => v.Name, v => v.Value);

                    PyTupleObject co_names = f_code.co_names.Read();
                    foreach (var nameObj in co_names.ReadElements()) {
                        var name = (nameObj.Read() as IPyBaseStringObject).ToStringOrNull();
                        if (name == null) {
                            continue;
                        }

                        // If this is a used name but it was not in varnames or freevars, it is a directly referenced global.
                        if (!namesSeen.Add(name)) {
                            continue;
                        }

                        var varSlot = globalVars[name].FirstOrDefault();
                        if (varSlot.Process != null) {
                            evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, new PythonEvaluationResult(varSlot, name), cppEval);
                            evalResults.Add(evalResult);
                        }
                    }
                }
            }

            var enumContext = DkmEvaluationResultEnumContext.Create(evalResults.Count, stackFrame, inspectionContext,
                new EvaluationResults { Results = evalResults.OrderBy(er => er.Name) });
            completionRoutine(new DkmGetFrameLocalsAsyncResult(enumContext));
        }
示例#12
0
 void IDkmClrResultProvider.GetChildren(DkmEvaluationResult evaluationResult, DkmWorkList workList, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     evaluationResult.GetChildren(workList, initialRequestSize, inspectionContext, completionRoutine);
 }
示例#13
0
 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 WorkList(DkmWorkList workList, CompletionRoutine<Exception> onException)
 {
     InnerWorkList = workList;
     _onException = onException;
 }
示例#15
0
        private void EvaluateExpressionViaInterpreter(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
            var thread = stackFrame.Thread;
            var process = thread.Process;

            if (_evalLoopThreadId.Read() != (ulong)thread.SystemPart.Id) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text,
                    "Arbitrary Python expressions can only be evaluated on a thread which is stopped in Python code at a breakpoint or " +
                    "after a step-in or a step-over operation. Only expressions involving global and local variables, object field access, " +
                    "and indexing of built-in collection types with literals can be evaluated in the current context.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            var pythonFrame = PyFrameObject.TryCreate(stackFrame);
            if (pythonFrame == null) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Could not obtain a Python frame object for the current frame.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            byte[] input = Encoding.UTF8.GetBytes(expression.Text + "\0");
            if (input.Length > ExpressionEvaluationBufferSize) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Expression is too long.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            _evalLoopFrame.Write(pythonFrame.Address);
            process.WriteMemory(_evalLoopInput.Address, input);

            bool timedOut;
            using (_evalCompleteEvent = new AutoResetEvent(false)) {
                thread.BeginFuncEvalExecution(DkmFuncEvalFlags.None);
                timedOut = !_evalCompleteEvent.WaitOne(ExpressionEvaluationTimeout);
                _evalCompleteEvent = null;
            }

            if (timedOut) {
                new RemoteComponent.AbortingEvalExecutionRequest().SendLower(process);

                // We need to stop the process before we can report end of func eval completion
                using (_evalAbortedEvent = new AutoResetEvent(false)) {
                    process.AsyncBreak(false);

                    if (!_evalAbortedEvent.WaitOne(20000)) {
                        // This is a catastrophic error, since we can't report func eval completion unless we can stop the process,
                        // and VS will hang until we do report completion. At this point we can only kill the debuggee so that the
                        // VS at least gets back to a reasonable state.
                        _evalAbortedEvent = null;
                        process.Terminate(1);

                        completionRoutine(DkmEvaluateExpressionAsyncResult.CreateErrorResult(new Exception("Couldn't abort a failed expression evaluation.")));
                        return;
                    }

                    _evalAbortedEvent = null;
                }

                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Evaluation timed out.",
                    DkmEvaluationResultFlags.Invalid, null)));
                return;
            }

            ulong objPtr = _evalLoopResult.Read();
            var obj = PyObject.FromAddress(process, objPtr);
            var exc_type = PyObject.FromAddress(process, _evalLoopExcType.Read());
            var exc_value = PyObject.FromAddress(process, _evalLoopExcValue.Read());
            var exc_str = (PyObject.FromAddress(process, _evalLoopExcStr.Read()) as IPyBaseStringObject).ToStringOrNull();
            var sehCode = _evalLoopSEHCode.Read();

            if (obj != null) {
                var cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame);
                var pyEvalResult =  new PythonEvaluationResult(obj, expression.Text) { Flags = DkmEvaluationResultFlags.SideEffect };
                var evalResult = CreatePyObjectEvaluationResult(inspectionContext, stackFrame, null, pyEvalResult, cppEval, null, hasCppView: true, isOwned: true);
                _evalLoopResult.Write(0); // don't let the eval loop decref the object - we will do it ourselves later, when eval result is closed
                completionRoutine(new DkmEvaluateExpressionAsyncResult(evalResult));
            } else if (sehCode != 0) {
                string errorText = string.Format("Structured exception {0:x08} ", sehCode);
                if (Enum.IsDefined(typeof(EXCEPTION_CODE), sehCode)) {
                    errorText += "(" + (EXCEPTION_CODE)sehCode + ") ";
                }
                errorText += "raised while evaluating expression";
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, errorText,
                    DkmEvaluationResultFlags.Invalid, null)));
            } else if (exc_type != null) {
                string typeName;
                var typeObject = exc_type as PyTypeObject;
                if (typeObject != null) {
                    typeName = typeObject.tp_name.Read().ReadUnicode();
                } else {
                    typeName = "<unknown exception type>";
                }

                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, typeName + " raised while evaluating expression: " + exc_str,
                    DkmEvaluationResultFlags.Invalid, null)));
            } else {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text, "Unknown error occurred while evaluating expression.",
                    DkmEvaluationResultFlags.Invalid, null)));
            }
        }
示例#16
0
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            try
            {
                var dataItem = enumContext.GetDataItem<EnumContextDataItem>();
                if (dataItem == null)
                {
                    // We don't know about this result.  Call next implementation
                    enumContext.GetItems(workList, startIndex, count, completionRoutine);
                    return;
                }

                completionRoutine(GetItems(enumContext.InspectionContext, dataItem.EvalResultDataItem, startIndex, count));
            }
            catch (Exception e) when (ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
            {
                throw ExceptionUtilities.Unreachable;
            }
        }
 private void GetChildrenAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, DkmStackWalkFrame stackFrame, int initialRequestSize, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmGetChildrenAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     int index = 0;
     if (expansion != null)
     {
         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];
     var wl = new WorkList(workList, e => completionRoutine(DkmGetChildrenAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, initialChildren, 0, numRows, wl, inspectionContext, stackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 var enumContext = DkmEvaluationResultEnumContext.Create(index, stackFrame, inspectionContext, new EnumContextDataItem(dataItem));
                 completionRoutine(new DkmGetChildrenAsyncResult(initialChildren, enumContext));
                 rows.Free();
             }));
     wl.Execute();
 }
示例#18
0
        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));
        }
示例#19
0
 void IDkmClrResultProvider.GetResult(DkmClrValue clrValue, DkmWorkList workList, DkmClrType declaredType, DkmClrCustomTypeInfo customTypeInfo, DkmInspectionContext inspectionContext, ReadOnlyCollection<string> formatSpecifiers, string resultName, string resultFullName, DkmCompletionRoutine<DkmEvaluationAsyncResult> completionRoutine)
 {
     clrValue.GetResult(
         workList,
         declaredType,
         customTypeInfo,
         inspectionContext,
         formatSpecifiers,
         resultName,
         resultFullName,
         result =>
         {
             var type = declaredType.GetLmrType();
             if (type.IsPointer)
             {
                 var r = (DkmSuccessEvaluationResult)result.Result;
                 // TODO: Why aren't modopts for & properties included?
                 r.GetChildren(
                     workList,
                     1,
                     inspectionContext,
                     children =>
                     {
                         var c = (DkmSuccessEvaluationResult)children.InitialChildren[0];
                         r = DkmSuccessEvaluationResult.Create(
                             c.InspectionContext,
                             c.StackFrame,
                             r.Name,
                             r.FullName,
                             c.Flags,
                             c.Value,
                             r.EditableValue,
                             r.Type,
                             r.Category,
                             r.Access,
                             r.StorageType,
                             r.TypeModifierFlags,
                             null,
                             r.CustomUIVisualizers,
                             null,
                             null);
                         completionRoutine(new DkmEvaluationAsyncResult(r));
                     });
             }
             else
             {
                 completionRoutine(result);
             }
         });
 }
示例#20
0
 void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     enumContext.GetItems(workList, startIndex, count, completionRoutine);
 }
示例#21
0
 public void EvaluateExpression(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
     var name = expression.Text;
     GetFrameLocals(inspectionContext, workList, stackFrame, getFrameLocalsResult => {
         getFrameLocalsResult.EnumContext.GetItems(workList, 0, int.MaxValue, localGetItemsResult => {
             var vars = localGetItemsResult.Items.OfType<DkmSuccessEvaluationResult>();
             var globals = vars.FirstOrDefault(er => er.Name == "[Globals]");
             if (globals == null) {
                 if (!EvaluateExpressionByWalkingObjects(vars, inspectionContext, workList, expression, stackFrame, completionRoutine)) {
                     EvaluateExpressionViaInterpreter(inspectionContext, workList, expression, stackFrame, completionRoutine);
                 }
             } else {
                 globals.GetChildren(workList, 0, inspectionContext, globalsGetChildrenResult => {
                     globalsGetChildrenResult.EnumContext.GetItems(workList, 0, int.MaxValue, globalsGetItemsResult => {
                         vars = vars.Concat(globalsGetItemsResult.Items.OfType<DkmSuccessEvaluationResult>());
                         if (!EvaluateExpressionByWalkingObjects(vars, inspectionContext, workList, expression, stackFrame, completionRoutine)) {
                             EvaluateExpressionViaInterpreter(inspectionContext, workList, expression, stackFrame, completionRoutine);
                         }
                     });
                 });
             }
         });
     });
 }
示例#22
0
        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));
        }
示例#23
0
        /// <summary>
        /// Tries to evaluate the given expression by treating it as a chain of member access and indexing operations (e.g. <c>fob[0].oar.baz['abc'].blah</c>),
        /// and looking up the corresponding members in data model provided by <see cref="GetFrameLocals"/>.
        /// </summary>
        /// <param name="vars">List of variables, in the context of which the expression is evaluated.</param>
        /// <returns>
        /// <c>true</c> if evaluation was successful, or if it failed and no fallback is possible (e.g. expression is invalid).
        /// <c>false</c> if evaluation was not successful due to the limitations of this evaluator, and it may be possible to evaluate it correctly by other means.
        /// </returns>
        private bool EvaluateExpressionByWalkingObjects(IEnumerable<DkmSuccessEvaluationResult> vars, DkmInspectionContext inspectionContext, DkmWorkList workList, DkmLanguageExpression expression, DkmStackWalkFrame stackFrame, DkmCompletionRoutine<DkmEvaluateExpressionAsyncResult> completionRoutine) {
            var pyrtInfo = stackFrame.Thread.Process.GetPythonRuntimeInfo();

            var parserOptions = new ParserOptions { ErrorSink = new StringErrorSink() };
            var parser = Parser.CreateParser(new StringReader(expression.Text), pyrtInfo.LanguageVersion, parserOptions);

            var expr = ((ReturnStatement)parser.ParseTopExpression().Body).Expression;
            string errorText = parserOptions.ErrorSink.ToString();
            if (!string.IsNullOrEmpty(errorText)) {
                completionRoutine(new DkmEvaluateExpressionAsyncResult(DkmFailedEvaluationResult.Create(
                    inspectionContext, stackFrame, expression.Text, expression.Text,
                    errorText, DkmEvaluationResultFlags.Invalid, null)));
                return true;
            }

            // Unroll the AST into a sequence of member access and indexing operations, if possible.
            var path = new Stack<string>();
            var reprBuilder = new ReprBuilder(new ReprOptions(stackFrame.Thread.Process));
            while (true) {
                var memberExpr = expr as MemberExpression;
                if (memberExpr != null) {
                    path.Push(memberExpr.Name);
                    expr = memberExpr.Target;
                    continue;
                }

                var indexingExpr = expr as IndexExpression;
                if (indexingExpr != null) {
                    var indexExpr = indexingExpr.Index as ConstantExpression;
                    if (indexExpr != null) {
                        reprBuilder.Clear();
                        reprBuilder.AppendFormat("[{0:PY}]", indexExpr.Value);
                        path.Push(reprBuilder.ToString());
                        expr = indexingExpr.Target;
                        continue;
                    }
                }

                break;
            }

            var varExpr = expr as NameExpression;
            if (varExpr == null) {
                return false;
            }
            path.Push(varExpr.Name);

            // Walk the path through Locals
            while (true) {
                var name = path.Pop();

                var evalResult = vars.FirstOrDefault(er => er.Name == name);
                if (evalResult == null) {
                    return false;
                }

                if (path.Count == 0) {
                    // Clone the evaluation result, but use expression text as its name.
                    DkmDataItem dataItem =
                        (DkmDataItem)evalResult.GetDataItem<PyObjectEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<GlobalsEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<CppViewEvaluationResult>() ??
                        (DkmDataItem)evalResult.GetDataItem<RawEvaluationResult>();
                    evalResult = DkmSuccessEvaluationResult.Create(
                        evalResult.InspectionContext,
                        evalResult.StackFrame,
                        expression.Text,
                        expression.Text,
                        evalResult.Flags,
                        evalResult.Value,
                        evalResult.EditableValue,
                        evalResult.Type,
                        evalResult.Category,
                        evalResult.Access,
                        evalResult.StorageType,
                        evalResult.TypeModifierFlags,
                        evalResult.Address,
                        evalResult.CustomUIVisualizers,
                        evalResult.ExternalModules,
                        dataItem);

                    completionRoutine(new DkmEvaluateExpressionAsyncResult(evalResult));
                    return true;
                }

                var childWorkList = DkmWorkList.Create(null);
                evalResult.GetChildren(childWorkList, 0, inspectionContext, getChildrenResult =>
                    getChildrenResult.EnumContext.GetItems(childWorkList, 0, int.MaxValue, getItemsResult =>
                        vars = getItemsResult.Items.OfType<DkmSuccessEvaluationResult>()));
                childWorkList.Execute();
            }
        }
示例#24
0
 internal WorkList(DkmWorkList workList, CompletionRoutine<Exception> onException)
 {
     InnerWorkList = workList;
     _onException = onException;
     _state = State.Initialized;
 }
示例#25
0
        public void ManyItemsSync()
        {
            const int n = 10000;
            var value = CreateDkmClrValue(Enumerable.Range(0, n).ToArray());
            var evalResult = FormatResult("a", value);
            IDkmClrResultProvider resultProvider = new CSharpResultProvider();
            var workList = new DkmWorkList();

            // GetChildren
            var getChildrenResult = default(DkmGetChildrenAsyncResult);
            resultProvider.GetChildren(evalResult, workList, n, DefaultInspectionContext, r => getChildrenResult = r);
            Assert.Equal(workList.Length, 0);
            Assert.Equal(getChildrenResult.InitialChildren.Length, n);

            // GetItems
            var getItemsResult = default(DkmEvaluationEnumAsyncResult);
            resultProvider.GetItems(getChildrenResult.EnumContext, workList, 0, n, r => getItemsResult = r);
            Assert.Equal(workList.Length, 0);
            Assert.Equal(getItemsResult.Items.Length, n);
        }
示例#26
0
 public void GetFrameReturnType(DkmInspectionContext inspectionContext, DkmWorkList workList, DkmStackWalkFrame frame, DkmCompletionRoutine<DkmGetFrameReturnTypeAsyncResult> completionRoutine) {
     completionRoutine(new DkmGetFrameReturnTypeAsyncResult(null));
 }
 private void GetItemsAndContinue(EvalResultDataItem dataItem, DkmWorkList workList, int startIndex, int count, DkmInspectionContext inspectionContext, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
 {
     var expansion = dataItem.Expansion;
     var value = dataItem.Value;
     var rows = ArrayBuilder<EvalResultDataItem>.GetInstance();
     if (expansion != null)
     {
         int index = 0;
         expansion.GetRows(this, rows, inspectionContext, dataItem, value, startIndex, count, visitAll: false, index: ref index);
     }
     var numRows = rows.Count;
     Debug.Assert(count >= numRows);
     var results = new DkmEvaluationResult[numRows];
     var wl = new WorkList(workList, e => completionRoutine(DkmEvaluationEnumAsyncResult.CreateErrorResult(e)));
     GetEvaluationResultsAndContinue(rows, results, 0, numRows, wl, inspectionContext, value.StackFrame,
         () => wl.ContinueWith(
             () =>
             {
                 completionRoutine(new DkmEvaluationEnumAsyncResult(results));
                 rows.Free();
             }));
     wl.Execute();
 }
示例#28
0
        public void MultipleItemsAsync()
        {
            var source =
@"using System.Diagnostics;
[DebuggerDisplay(""{F}"")]
class C
{
    object F;
}";
            var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlib(GetAssembly(source)));
            using (runtime.Load())
            {
                int n = 10;
                var type = runtime.GetType("C");
                // C[] with alternating null and non-null values.
                var value = CreateDkmClrValue(Enumerable.Range(0, n).Select(i => (i % 2) == 0 ? type.Instantiate() : null).ToArray());
                var evalResult = FormatResult("a", value);

                IDkmClrResultProvider resultProvider = new CSharpResultProvider();
                var workList = new DkmWorkList();

                // GetChildren
                var getChildrenResult = default(DkmGetChildrenAsyncResult);
                resultProvider.GetChildren(evalResult, workList, n, DefaultInspectionContext, r => getChildrenResult = r);
                Assert.Equal(workList.Length, 1);
                workList.Execute();
                Assert.Equal(getChildrenResult.InitialChildren.Length, n);

                // GetItems
                var getItemsResult = default(DkmEvaluationEnumAsyncResult);
                resultProvider.GetItems(getChildrenResult.EnumContext, workList, 0, n, r => getItemsResult = r);
                Assert.Equal(workList.Length, 1);
                workList.Execute();
                Assert.Equal(getItemsResult.Items.Length, n);
            }
        }
        void IDkmClrResultProvider.GetItems(DkmEvaluationResultEnumContext enumContext, DkmWorkList workList, int startIndex, int count, DkmCompletionRoutine<DkmEvaluationEnumAsyncResult> completionRoutine)
        {
            var dataItem = enumContext.GetDataItem<EnumContextDataItem>();
            if (dataItem == null)
            {
                // We don't know about this result.  Call next implementation
                enumContext.GetItems(workList, startIndex, count, completionRoutine);
                return;
            }

            GetItemsAndContinue(dataItem.EvalResultDataItem, workList, startIndex, count, enumContext.InspectionContext, completionRoutine);
        }
示例#30
0
        public void MultipleItemsAndExceptions()
        {
            var source =
@"using System.Diagnostics;
[DebuggerDisplay(""{P}"")]
class C
{
    public C(int f) { this.f = f; }
    private readonly int f;
    object P
    {
        get
        {
            if (this.f % 4 == 3) throw new System.ArgumentException();
            return this.f;
        }
    }
}";
            var runtime = new DkmClrRuntimeInstance(ReflectionUtilities.GetMscorlib(GetAssembly(source)));
            using (runtime.Load())
            {
                int n = 10;
                int nFailures = 2;
                var type = runtime.GetType("C");
                var value = CreateDkmClrValue(Enumerable.Range(0, n).Select(i => type.Instantiate(i)).ToArray());
                var evalResult = FormatResult("a", value);

                IDkmClrResultProvider resultProvider = new CSharpResultProvider();
                var workList = new DkmWorkList();

                // GetChildren
                var getChildrenResult = default(DkmGetChildrenAsyncResult);
                resultProvider.GetChildren(evalResult, workList, n, DefaultInspectionContext, r => getChildrenResult = r);
                Assert.Equal(workList.Length, 1);
                workList.Execute();
                var items = getChildrenResult.InitialChildren;
                Assert.Equal(items.Length, n);
                Assert.Equal(items.OfType<DkmFailedEvaluationResult>().Count(), nFailures);

                // GetItems
                var getItemsResult = default(DkmEvaluationEnumAsyncResult);
                resultProvider.GetItems(getChildrenResult.EnumContext, workList, 0, n, r => getItemsResult = r);
                Assert.Equal(workList.Length, 1);
                workList.Execute();
                items = getItemsResult.Items;
                Assert.Equal(items.Length, n);
                Assert.Equal(items.OfType<DkmFailedEvaluationResult>().Count(), nFailures);
            }
        }