コード例 #1
0
        public override object GetArgumentValue(DkmStackWalkFrame frame, int index)
        {
            byte[] argumentBuffer = ReadArgumentBytes(frame);

            int wordZeroIndex = 0;

            for (int i = 0; i < index; ++i)
            {
                wordZeroIndex += _parameters[i].GetPaddedSize(WordSize);
            }
            FunctionParameter requestedParameter = _parameters[index];
            int requestedParamSize = requestedParameter.GetSize(WordSize);

            byte[] result = new byte[requestedParamSize];

            Array.ConstrainedCopy(argumentBuffer, wordZeroIndex, result, 0, requestedParamSize);

            switch (requestedParamSize)
            {
            case 4:
                return(BitConverter.ToUInt32(result, 0));

            case 8:
                return(BitConverter.ToUInt64(result, 0));

            default:
                return(result);
            }
        }
コード例 #2
0
        public CppExpressionEvaluator(DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame)
        {
            _process = stackFrame.Process;
            var thread = stackFrame.Thread;

            if (stackFrame.InstructionAddress is DkmNativeInstructionAddress)
            {
                _nativeFrame = stackFrame;
            }
            else
            {
                var customAddr = stackFrame.InstructionAddress as DkmCustomInstructionAddress;
                if (customAddr == null)
                {
                    throw new ArgumentException();
                }

                var loc = new SourceLocation(customAddr.AdditionalData, _process);
                if (loc.NativeAddress == null)
                {
                    throw new ArgumentException();
                }

                _nativeFrame = DkmStackWalkFrame.Create(thread, loc.NativeAddress, stackFrame.FrameBase, stackFrame.FrameSize,
                                                        DkmStackWalkFrameFlags.None, null, stackFrame.Registers, null);
            }

            _cppInspectionContext = DkmInspectionContext.Create(inspectionContext.InspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, inspectionContext.Radix, CppLanguage, null);
        }
コード例 #3
0
ファイル: FrameDecoder.cs プロジェクト: belav/roslyn
 void IDkmLanguageFrameDecoder.GetFrameReturnType(
     DkmInspectionContext inspectionContext,
     DkmWorkList workList,
     DkmStackWalkFrame frame,
     DkmCompletionRoutine <DkmGetFrameReturnTypeAsyncResult> completionRoutine
     )
 {
     try
     {
         GetNameWithGenericTypeArguments(
             workList,
             frame,
             onSuccess: method =>
             completionRoutine(
                 new DkmGetFrameReturnTypeAsyncResult(
                     _instructionDecoder.GetReturnTypeName(method)
                     )
                 ),
             onFailure: e =>
             completionRoutine(DkmGetFrameReturnTypeAsyncResult.CreateErrorResult(e))
             );
     }
     catch (NotImplementedMetadataException)
     {
         inspectionContext.GetFrameReturnType(workList, frame, completionRoutine);
     }
     catch (Exception e) when(ExpressionEvaluatorFatalError.CrashIfFailFastEnabled(e))
     {
         throw ExceptionUtilities.Unreachable;
     }
 }
コード例 #4
0
        public override object GetArgumentValue(DkmStackWalkFrame frame, int index)
        {
            ulong esp       = (uint)frame.Registers.GetStackPointer();
            uint  esp2      = frame.VscxGetRegisterValue32(CpuRegister.Esp);
            uint  ebp       = frame.VscxGetRegisterValue32(CpuRegister.Ebp);
            ulong frameBase = (uint)frame.FrameBase;

            int stackOffset = 0;

            for (int i = 0; i < index; ++i)
            {
                stackOffset += _parameters[i].GetPaddedSize(WordSize);
            }

            // The return address (4 bytes) is at the top of the stack, so offset by 4 to skip the return
            // address.
            ulong stackAddress = esp + 4 + (ulong)stackOffset;
            int   paramSize    = _parameters[index].GetSize(WordSize);

            byte[] parameter = new byte[paramSize];

            frame.Process.ReadMemory(stackAddress, DkmReadMemoryFlags.None, parameter);
            switch (paramSize)
            {
            case 4:
                return(BitConverter.ToUInt32(parameter, 0));

            case 8:
                return(BitConverter.ToUInt64(parameter, 0));

            default:
                return(parameter);
            }
        }
コード例 #5
0
 public object[] GetAllArgumentValues(DkmStackWalkFrame frame)
 {
     object[] arguments = new object[_parameters.Count];
       for (int i = 0; i < _parameters.Count; ++i)
     arguments[i] = GetArgumentValue(frame, i);
       return arguments;
 }
コード例 #6
0
        public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
        {
            if (input == null)             // after last frame
            {
                return(null);
            }

            if (input.InstructionAddress == null)             // error case
            {
                return new[] { input }
            }
            ;

            if (input.InstructionAddress.ModuleInstance != null)             // code in existing module
            {
                return new[] { input }
            }
            ;

            var runner = new PmipRunner(stackContext, input);

            return(new[] { runner.PmipStackFrame() });
        }
    }
}
コード例 #7
0
ファイル: FunctionTracer.cs プロジェクト: zpublic/vs-chromium
        void IFunctionTracer.OnExitBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException)
        {
            FunctionTraceEntryDataItem traceDataItem = bp.GetDataItem <FunctionTraceEntryDataItem>();

            if (OnFunctionExited != null)
            {
                DkmStackWalkFrame  frame        = thread.GetTopStackWalkFrame(bp.RuntimeInstance);
                StackFrameAnalyzer exitAnalyzer = null;
                if (traceDataItem != null)
                {
                    DkmSystemInformationFlags systemInformationFlags =
                        frame.ModuleInstance.Process.SystemInformation.Flags;
                    bool isTarget64Bit = systemInformationFlags.HasFlag(DkmSystemInformationFlags.Is64Bit);
                    int  pointerSize   = (isTarget64Bit) ? 8 : 4;
                    exitAnalyzer = new CachedFrameAnalyzer(
                        frameAnalyzer.Parameters,
                        traceDataItem.EntryArgumentValues,
                        pointerSize);
                }
                OnFunctionExited(frame, exitAnalyzer);
            }

            // Since this was a one-shot breakpoint, it is unconditionally closed.
            bp.Close();
        }
コード例 #8
0
    public override object GetArgumentValue(DkmStackWalkFrame frame, int index) {
      ulong esp = (uint)frame.Registers.GetStackPointer();
      uint esp2 = frame.VscxGetRegisterValue32(CpuRegister.Esp);
      uint ebp = frame.VscxGetRegisterValue32(CpuRegister.Ebp);
      ulong frameBase = (uint)frame.FrameBase;

      int stackOffset = 0;
      for (int i = 0; i < index; ++i)
        stackOffset += _parameters[i].GetPaddedSize(WordSize);

      // The return address (4 bytes) is at the top of the stack, so offset by 4 to skip the return
      // address.
      ulong stackAddress = esp + 4 + (ulong)stackOffset;
      int paramSize = _parameters[index].GetSize(WordSize);
      byte[] parameter = new byte[paramSize];

      frame.Process.ReadMemory(stackAddress, DkmReadMemoryFlags.None, parameter);
      switch (paramSize) {
        case 4:
          return BitConverter.ToUInt32(parameter, 0);
        case 8:
          return BitConverter.ToUInt64(parameter, 0);
        default:
          return parameter;
      }
    }
コード例 #9
0
ファイル: PyFrameObject.cs プロジェクト: zooba/PTVS
        public static unsafe PyFrameObject TryCreate(DkmStackWalkFrame frame) {
            var process = frame.Process;

            if (frame.InstructionAddress == null) {
                return null;
            } 
            if (frame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid && !IsInEvalFrame(frame)) {
                return null;
            }

            var cppLanguage = DkmLanguage.Create("C++", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.CppLanguageGuid));
            var inspectionSession = DkmInspectionSession.Create(process, null);
            var inspectionContext = DkmInspectionContext.Create(inspectionSession, process.GetNativeRuntimeInstance(), frame.Thread, 0,
                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, cppLanguage, null);

            CppExpressionEvaluator cppEval;
            try {
                cppEval = new CppExpressionEvaluator(inspectionContext, frame);
            } catch (ArgumentException) {
                Debug.Fail("Failed to create C++ expression evaluator while obtaining PyFrameObject from a native frame.");
                return null;
            }

            ulong framePtr;
            try {
                framePtr = cppEval.EvaluateUInt64("f");
            } catch (CppEvaluationException) {
                Debug.Fail("Failed to evaluate the 'f' parameter to PyEval_EvalFrameEx while obtaining PyFrameObject from a native frame.");
                return null;
            }

            return new PyFrameObject(frame.Process, framePtr);
        }
コード例 #10
0
ファイル: FunctionTracer.cs プロジェクト: zpublic/vs-chromium
        void IFunctionTracer.OnEntryBreakpointHit(DkmRuntimeBreakpoint bp, DkmThread thread, bool hasException)
        {
            // The function was just entered.  Install the exit breakpoint on the calling thread at the
            // return address, and notify any listeners.
            DkmStackWalkFrame frame = thread.GetTopStackWalkFrame(bp.RuntimeInstance);

            bool suppressExitBreakpoint = false;

            if (OnFunctionEntered != null)
            {
                OnFunctionEntered(frame, frameAnalyzer, out suppressExitBreakpoint);
            }

            if (!suppressExitBreakpoint)
            {
                ulong ret = frame.VscxGetReturnAddress();

                DkmInstructionAddress           retAddr = thread.Process.CreateNativeInstructionAddress(ret);
                DkmRuntimeInstructionBreakpoint exitBp  = DkmRuntimeInstructionBreakpoint.Create(
                    Guids.Source.FunctionTraceExit, thread, retAddr, false, null);
                // Capture the value of every argument now, since when the exit breakpoint gets hit, the
                // target function will have already returned and its frame will be cleaned up.
                exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
                                   new FunctionTraceEntryDataItem {
                    EntryArgumentValues = frameAnalyzer.GetAllArgumentValues(frame)
                });
                exitBp.SetDataItem(DkmDataCreationDisposition.CreateAlways,
                                   new FunctionTraceDataItem {
                    Tracer = this
                });
                exitBp.Enable();
            }
        }
コード例 #11
0
        private static bool IsInEvalFrame(DkmStackWalkFrame frame)
        {
            var   process    = frame.Process;
            var   pythonInfo = process.GetPythonRuntimeInfo();
            ulong addr       = 0;

            if (pythonInfo.LanguageVersion <= PythonLanguageVersion.V35)
            {
                if (frame.ModuleInstance == pythonInfo.DLLs.Python)
                {
                    addr = pythonInfo.DLLs.Python.GetFunctionAddress("PyEval_EvalFrameEx");
                }
            }
            else
            {
                if (frame.ModuleInstance == pythonInfo.DLLs.DebuggerHelper)
                {
                    addr = pythonInfo.DLLs.DebuggerHelper.GetFunctionAddress("EvalFrameFunc");
                }
            }

            if (addr == 0)
            {
                return(false);
            }

            return(frame.InstructionAddress.IsInSameFunction(process.CreateNativeInstructionAddress(addr)));
        }
コード例 #12
0
 private DkmSuccessEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     DkmEvaluationResultFlags flags,
     string value,
     string editableValue,
     string type,
     DkmEvaluationResultCategory category,
     DkmEvaluationResultAccessType access,
     DkmEvaluationResultStorageType storageType,
     DkmEvaluationResultTypeModifierFlags typeModifierFlags,
     DkmDataAddress address,
     ReadOnlyCollection<DkmCustomUIVisualizerInfo> customUIVisualizers,
     ReadOnlyCollection<DkmModuleInstance> externalModules,
     DkmDataItem dataItem) :
     base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
 {
     this.Value = value;
     this.EditableValue = editableValue;
     this.Category = category;
     this.Access = access;
     this.StorageType = storageType;
     this.TypeModifierFlags = typeModifierFlags;
     this.CustomUIVisualizers = customUIVisualizers;
 }
コード例 #13
0
        public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
        {
            if (input == null) // after last frame
            {
                return(null);
            }

            if (input.InstructionAddress == null) // error case
            {
                return new[] { input }
            }
            ;

            if (input.InstructionAddress.ModuleInstance != null && input.InstructionAddress.ModuleInstance.Module != null) // code in existing module
            {
                return new[] { input }
            }
            ;

            if (!_enabled) // environment variable not set
            {
                return new[] { input }
            }
            ;

            return(new[] { UnityMixedStackFrame(stackContext, input) });
        }
コード例 #14
0
        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;
            }
        }
コード例 #15
0
 public object GetArgumentValue(DkmStackWalkFrame frame, string name) {
   for (int i = 0; i < _parameters.Count; ++i) {
     if (_parameters[i].Name.Equals(name))
       return GetArgumentValue(frame, i);
   }
   return null;
 }
コード例 #16
0
 private DkmSuccessEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     DkmEvaluationResultFlags flags,
     string value,
     string editableValue,
     string type,
     DkmEvaluationResultCategory category,
     DkmEvaluationResultAccessType access,
     DkmEvaluationResultStorageType storageType,
     DkmEvaluationResultTypeModifierFlags typeModifierFlags,
     DkmDataAddress address,
     ReadOnlyCollection <DkmCustomUIVisualizerInfo> customUIVisualizers,
     ReadOnlyCollection <DkmModuleInstance> externalModules,
     DkmDataItem dataItem) :
     base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
 {
     this.Value               = value;
     this.EditableValue       = editableValue;
     this.Category            = category;
     this.Access              = access;
     this.StorageType         = storageType;
     this.TypeModifierFlags   = typeModifierFlags;
     this.CustomUIVisualizers = customUIVisualizers;
 }
コード例 #17
0
        private static string TryGetFrameReturnTypeHelper(DkmInspectionContext inspectionContext, DkmStackWalkFrame frame)
        {
            ImportedMethod currentMethod = TryGetCurrentMethod(inspectionContext, frame);
            if (currentMethod == null)
                return null;

            return currentMethod.ReturnType.ToString();
        }
コード例 #18
0
 public object[] GetAllArgumentValues(DkmStackWalkFrame frame)
 {
     object[] arguments = new object[_parameters.Count];
     for (int i = 0; i < _parameters.Count; ++i)
     {
         arguments[i] = GetArgumentValue(frame, i);
     }
     return(arguments);
 }
コード例 #19
0
 public ExpressionEvaluation(DkmProcess process, DkmStackWalkFrame stackFrame, DkmInspectionSession inspectionSession, LuaFunctionData functionData, ulong frameBaseAddress, LuaClosureData luaClosure)
 {
     this.process           = process;
     this.stackFrame        = stackFrame;
     this.inspectionSession = inspectionSession;
     this.functionData      = functionData;
     this.frameBaseAddress  = frameBaseAddress;
     this.luaClosure        = luaClosure;
 }
コード例 #20
0
        public static ulong VscxGetReturnAddress(this DkmStackWalkFrame frame)
        {
            ulong ret;
            ulong frameBase;
            ulong vframe;

            frame.Thread.GetCurrentFrameInfo(out ret, out frameBase, out vframe);
            return(ret);
        }
コード例 #21
0
 public static DkmEvaluationResultEnumContext Create(int Count, DkmStackWalkFrame StackFrame, DkmInspectionContext InspectionContext, DkmDataItem DataItem)
 {
     var enumContext = new DkmEvaluationResultEnumContext(Count, InspectionContext);
     if (DataItem != null)
     {
         enumContext.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
     }
     return enumContext;
 }
コード例 #22
0
 /// <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));
 }
コード例 #23
0
        /// <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));
        }
コード例 #24
0
 /// <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));
 }
コード例 #25
0
        public static DkmEvaluationResultEnumContext Create(int Count, DkmStackWalkFrame StackFrame, DkmInspectionContext InspectionContext, DkmDataItem DataItem)
        {
            var enumContext = new DkmEvaluationResultEnumContext(Count, InspectionContext);

            if (DataItem != null)
            {
                enumContext.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
            }
            return(enumContext);
        }
コード例 #26
0
        DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
        {
            // The HelloWorld sample is a very simple debugger component which modified the call stack
            // so that there is a '[Hello World]' frame at the top of the call stack. All the frames
            // below this are left the same.

            if (input == null) // null input frame indicates the end of the call stack. This sample does nothing on end-of-stack.
            {
                return(null);
            }

            // Get the HelloWorldDataItem which is associated with this stack walk. This
            // lets us keep data associated with this stack walk.
            HelloWordDataItem dataItem = HelloWordDataItem.GetInstance(stackContext);

            DkmStackWalkFrame[] frames;

            // Now use this data item to see if we are looking at the first (top-most) frame
            if (dataItem.State == State.Initial)
            {
                // On the top most frame, we want to return back two different frames. First
                // we place the '[Hello World]' frame, and under that we put the input frame.

                frames = new DkmStackWalkFrame[2];

                // Create the hello world frame object, and stick it in the array
                frames[0] = DkmStackWalkFrame.Create(
                    stackContext.Thread,
                    null,                          // Annotated frame, so no instruction address
                    input.FrameBase,               // Use the same frame base as the input frame
                    0,                             // annoted frame uses zero bytes
                    DkmStackWalkFrameFlags.None,
                    "[Hello World]",               // Description of the frame which will appear in the call stack
                    null,                          // Annotated frame, so no registers
                    null
                    );

                // Add the input frame into the array as well
                frames[1] = input;

                // Update our state so that on the next frame we know not to add '[Hello World]' again.
                dataItem.State = State.HelloWorldFrameAdded;
            }
            else
            {
                // We have already added '[Hello World]' to this call stack, so just return
                // the input frame.

                frames = new DkmStackWalkFrame[1] {
                    input
                };
            }

            return(frames);
        }
コード例 #27
0
        internal static DkmInspectionSession CreateInspectionSession(DkmProcess process, DkmThread thread, SupportBreakpointHitMessage data, out DkmStackWalkFrame frame)
        {
            const int CV_ALLREG_VFRAME   = 0x00007536;
            var       vFrameRegister     = DkmUnwoundRegister.Create(CV_ALLREG_VFRAME, new ReadOnlyCollection <byte>(BitConverter.GetBytes(data.vframe)));
            var       registers          = thread.GetCurrentRegisters(new[] { vFrameRegister });
            var       instructionAddress = process.CreateNativeInstructionAddress(registers.GetInstructionPointer());

            frame = DkmStackWalkFrame.Create(thread, instructionAddress, data.frameBase, 0, DkmStackWalkFrameFlags.None, null, registers, null);

            return(DkmInspectionSession.Create(process, null));
        }
コード例 #28
0
 public object GetArgumentValue(DkmStackWalkFrame frame, string name)
 {
     for (int i = 0; i < _parameters.Count; ++i)
     {
         if (_parameters[i].Name.Equals(name))
         {
             return(GetArgumentValue(frame, i));
         }
     }
     return(null);
 }
コード例 #29
0
        /// <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));
        }
コード例 #30
0
ファイル: FrameDecoder.cs プロジェクト: belav/roslyn
        private void GetNameWithGenericTypeArguments(
            DkmWorkList workList,
            DkmStackWalkFrame frame,
            Action <TMethodSymbol> onSuccess,
            Action <Exception> onFailure
            )
        {
            // NOTE: We could always call GetClrGenericParameters, pass them to GetMethod and have that
            // return a constructed method symbol, but it seems unwise to call GetClrGenericParameters
            // for all frames (as this call requires a round-trip to the debuggee process).
            var instructionAddress = (DkmClrInstructionAddress)frame.InstructionAddress;
            var compilation        = _instructionDecoder.GetCompilation(instructionAddress.ModuleInstance);
            var method             = _instructionDecoder.GetMethod(compilation, instructionAddress);
            var typeParameters     = _instructionDecoder.GetAllTypeParameters(method);

            if (!typeParameters.IsEmpty)
            {
                frame.GetClrGenericParameters(
                    workList,
                    result =>
                {
                    try
                    {
                        // DkmGetClrGenericParametersAsyncResult.ParameterTypeNames will throw if ErrorCode != 0.
                        var serializedTypeNames =
                            (result.ErrorCode == 0) ? result.ParameterTypeNames : null;
                        var typeArguments = _instructionDecoder.GetTypeSymbols(
                            compilation,
                            method,
                            serializedTypeNames
                            );
                        if (!typeArguments.IsEmpty)
                        {
                            method = _instructionDecoder.ConstructMethod(
                                method,
                                typeParameters,
                                typeArguments
                                );
                        }
                        onSuccess(method);
                    }
                    catch (Exception e)
                    {
                        onFailure(e);
                    }
                }
                    );
            }
            else
            {
                onSuccess(method);
            }
        }
コード例 #31
0
        public CppExpressionEvaluator(DkmThread thread, ulong frameBase, ulong vframe) {
            _process = thread.Process;

            var inspectionSession = DkmInspectionSession.Create(_process, null);
            _cppInspectionContext = DkmInspectionContext.Create(inspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, CppLanguage, null);

            const int CV_ALLREG_VFRAME = 0x00007536;
            var vframeReg = DkmUnwoundRegister.Create(CV_ALLREG_VFRAME, new ReadOnlyCollection<byte>(BitConverter.GetBytes(vframe)));
            var regs = thread.GetCurrentRegisters(new[] { vframeReg });
            var iaddr = _process.CreateNativeInstructionAddress(regs.GetInstructionPointer());
            _nativeFrame = DkmStackWalkFrame.Create(thread, iaddr, frameBase, 0, DkmStackWalkFrameFlags.None, null, regs, null);
        }
コード例 #32
0
		private static DkmInspectionContext CreateInspectionContext(DkmStackContext stackContext, DkmStackWalkFrame frame)
		{
			return DkmInspectionContext.Create(
				stackContext.InspectionSession,
				frame.RuntimeInstance,
				frame.Thread,
				1000,
				DkmEvaluationFlags.None,
				DkmFuncEvalFlags.None,
				10,
				CppLanguage,
				null);
		}
コード例 #33
0
 private DkmFailedEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     string errorMessage,
     DkmEvaluationResultFlags flags,
     string type,
     DkmDataItem dataItem) :
     base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
 {
     this.ErrorMessage = errorMessage;
 }
コード例 #34
0
 private DkmFailedEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     string errorMessage,
     DkmEvaluationResultFlags flags,
     string type,
     DkmDataItem dataItem) :
     base(inspectionContext, stackFrame, name, fullName, flags, type, dataItem)
 {
     this.ErrorMessage = errorMessage;
 }
コード例 #35
0
        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();
        }
コード例 #36
0
		public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
		{
			if (input == null) // after last frame
				return null;

			if (input.InstructionAddress == null) // error case
				return new[] { input };

			if (input.InstructionAddress.ModuleInstance != null) // code in existing module
				return new[] { input };

			var runner = new PmipRunner(stackContext, input);
			return new[] { runner.PmipStackFrame() };
		}
コード例 #37
0
        DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
        {
            // The HelloWorld sample is a very simple debugger component which modified the call stack
            // so that there is a '[Hello World]' frame at the top of the call stack. All the frames
            // below this are left the same.

            if (input == null) // null input frame indicates the end of the call stack. This sample does nothing on end-of-stack.
                return null;

            // Get the HelloWorldDataItem which is associated with this stack walk. This
            // lets us keep data associated with this stack walk.
            HelloWordDataItem dataItem = HelloWordDataItem.GetInstance(stackContext);
            DkmStackWalkFrame[] frames;

            // Now use this data item to see if we are looking at the first (top-most) frame
            if (dataItem.State == State.Initial)
            {
                // On the top most frame, we want to return back two different frames. First 
                // we place the '[Hello World]' frame, and under that we put the input frame.

                frames = new DkmStackWalkFrame[2];

                // Create the hello world frame object, and stick it in the array
                frames[0] = DkmStackWalkFrame.Create(
                    stackContext.Thread,
                    null,                          // Annotated frame, so no instruction address
                    input.FrameBase,               // Use the same frame base as the input frame
                    0,                             // annoted frame uses zero bytes
                    DkmStackWalkFrameFlags.None,
                    "[Hello World]",               // Description of the frame which will appear in the call stack
                    null,                          // Annotated frame, so no registers
                    null
                    );

                // Add the input frame into the array as well
                frames[1] = input;

                // Update our state so that on the next frame we know not to add '[Hello World]' again.
                dataItem.State = State.HelloWorldFrameAdded;
            }
            else
            {
                // We have already added '[Hello World]' to this call stack, so just return
                // the input frame.

                frames = new DkmStackWalkFrame[1] { input };
            }

            return frames;
        }
コード例 #38
0
ファイル: VSDebuggerProxy.cs プロジェクト: leculver/WinDbgCs
        public int GetCurrentStackFrameNumber(int threadId)
        {
            DkmStackWalkFrame frame = ExecuteOnMainThread(() => DkmStackFrame.ExtractFromDTEObject(VSContext.DTE.Debugger.CurrentStackFrame));

            DkmStackWalkFrame[] frames = threads[threadId].Frames.Value;

            for (int i = 0; i < frames.Length; i++)
            {
                if (frames[i].FrameBase == frame.FrameBase)
                {
                    return(i);
                }
            }
            return(-1);
        }
コード例 #39
0
 private DkmIntermediateEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     string expression,
     DkmLanguage intermediateLanguage,
     DkmRuntimeInstance targetRuntime,
     DkmDataItem dataItem) :
     base(inspectionContext, stackFrame, name, fullName, DkmEvaluationResultFlags.None, null, dataItem)
 {
     this.Expression           = expression;
     this.IntermediateLanguage = intermediateLanguage;
     this.TargetRuntime        = targetRuntime;
 }
コード例 #40
0
 private DkmIntermediateEvaluationResult(
     DkmInspectionContext inspectionContext,
     DkmStackWalkFrame stackFrame,
     string name,
     string fullName,
     string expression,
     DkmLanguage intermediateLanguage,
     DkmRuntimeInstance targetRuntime,
     DkmDataItem dataItem)
     : base(inspectionContext, stackFrame, name, fullName, DkmEvaluationResultFlags.None, null, dataItem)
 {
     this.Expression = expression;
     this.IntermediateLanguage = intermediateLanguage;
     this.TargetRuntime = targetRuntime;
 }
コード例 #41
0
        void createProcessTracer_OnFunctionEntered(
            DkmStackWalkFrame frame,
            StackFrameAnalyzer functionAnalyzer,
            out bool suppressExitBreakpoint)
        {
            // If this was not created with CREATE_SUSPENDED, then we can't automatically attach to this
            // child process.
            // TODO(zturner): OR in CREATE_SUSPENDED using WriteProcessMemory, then when the exit bp
            // hits, check if we OR'ed in CREATE_SUSPENDED, and if so, resume the process after the
            // attach.
            ProcessCreationFlags flags = (ProcessCreationFlags)
                                         Convert.ToUInt32(functionAnalyzer.GetArgumentValue(frame, "dwCreationFlags"));

            suppressExitBreakpoint = !flags.HasFlag(ProcessCreationFlags.CREATE_SUSPENDED);
        }
コード例 #42
0
        private byte[] ReadArgumentBytes(DkmStackWalkFrame frame)
        {
            // In the x64 calling convention, the first 4 arguments are passed in registers, and the
            // remaining arguments are passed on the stack.  However, space for all arguments is
            // allocated on the stack, even if the argument is passed one of the first 4 which is passed
            // by register.  Furthermore, a minimum of 4*WordSize bytes is allocated on the stack for
            // function parameters, even if the function accepts less than 4 arguments.
            int bytesRequired = 0;

            foreach (FunctionParameter param in _parameters)
            {
                bytesRequired += param.GetPaddedSize(WordSize);
            }
            byte[] stack = new byte[bytesRequired];

            ulong rsp = frame.Registers.GetStackPointer();

            // The first word on the stack is the return address, similar to in x86 calling conventions.
            frame.Process.ReadMemory(rsp + 8, DkmReadMemoryFlags.None, stack);

            // Since everything is padded, we should have a multiple-of-8 bytes.  The first four
            // arguments may or may not actually be on the stack since it's register spill-over space,
            // but they are guaranteed to be in RCX, RDX, R8, and R9 respectively.  So get their values
            // from the registers and then write them into our copy of the stack.
            Invariants.Assert(bytesRequired % 8 == 0);
            if (bytesRequired > 0)
            {
                ulong rcx = frame.VscxGetRegisterValue64(CpuRegister.Rcx);
                BitConverter.GetBytes(rcx).CopyTo(stack, 0);
            }
            if (bytesRequired > 8)
            {
                ulong rdx = frame.VscxGetRegisterValue64(CpuRegister.Rdx);
                BitConverter.GetBytes(rdx).CopyTo(stack, 8);
            }
            if (bytesRequired > 16)
            {
                ulong r8 = frame.VscxGetRegisterValue64(CpuRegister.R8);
                BitConverter.GetBytes(r8).CopyTo(stack, 16);
            }
            if (bytesRequired > 24)
            {
                ulong r9 = frame.VscxGetRegisterValue64(CpuRegister.R9);
                BitConverter.GetBytes(r9).CopyTo(stack, 24);
            }

            return(stack);
        }
コード例 #43
0
        public CppExpressionEvaluator(DkmThread thread, ulong frameBase, ulong vframe)
        {
            _process = thread.Process;

            var inspectionSession = DkmInspectionSession.Create(_process, null);

            _cppInspectionContext = DkmInspectionContext.Create(inspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, CppLanguage, null);

            const int CV_ALLREG_VFRAME = 0x00007536;
            var       vframeReg        = DkmUnwoundRegister.Create(CV_ALLREG_VFRAME, new ReadOnlyCollection <byte>(BitConverter.GetBytes(vframe)));
            var       regs             = thread.GetCurrentRegisters(new[] { vframeReg });
            var       iaddr            = _process.CreateNativeInstructionAddress(regs.GetInstructionPointer());

            _nativeFrame = DkmStackWalkFrame.Create(thread, iaddr, frameBase, 0, DkmStackWalkFrameFlags.None, null, regs, null);
        }
コード例 #44
0
        public static unsafe PyFrameObject TryCreate(DkmStackWalkFrame frame)
        {
            var process = frame.Process;

            if (frame.InstructionAddress == null)
            {
                return(null);
            }
            if (frame.RuntimeInstance.Id.RuntimeType != Guids.PythonRuntimeTypeGuid && !IsInEvalFrame(frame))
            {
                return(null);
            }

            var cppLanguage       = DkmLanguage.Create("C++", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.CppLanguageGuid));
            var inspectionSession = DkmInspectionSession.Create(process, null);
            var inspectionContext = DkmInspectionContext.Create(inspectionSession, process.GetNativeRuntimeInstance(), frame.Thread, 0,
                                                                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, 10, cppLanguage, null);

            CppExpressionEvaluator cppEval;

            try
            {
                cppEval = new CppExpressionEvaluator(inspectionContext, frame);
            }
            catch (ArgumentException)
            {
                Debug.Fail("Failed to create C++ expression evaluator while obtaining PyFrameObject from a native frame.");
                return(null);
            }

            ulong framePtr;

            try
            {
                framePtr = cppEval.EvaluateUInt64("f");
            }
            catch (CppEvaluationException)
            {
                Debug.Fail("Failed to evaluate the 'f' parameter to PyEval_EvalFrameEx while obtaining PyFrameObject from a native frame.");
                return(null);
            }

            return(new PyFrameObject(frame.Process, framePtr));
        }
コード例 #45
0
        public static DkmFailedEvaluationResult Create(DkmInspectionContext InspectionContext, DkmStackWalkFrame StackFrame, string Name, string FullName, string ErrorMessage, DkmEvaluationResultFlags Flags, string Type, DkmDataItem DataItem)
        {
            DkmFailedEvaluationResult result = new DkmFailedEvaluationResult
            {
                InspectionContext = InspectionContext,
                Name = Name,
                FullName = FullName,
                ErrorMessage = ErrorMessage,
                Flags = Flags,
                Type = Type
            };

            if (DataItem != null)
            {
                result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
            }

            return result;
        }
コード例 #46
0
ファイル: PyFrameObject.cs プロジェクト: zooba/PTVS
        private static bool IsInEvalFrame(DkmStackWalkFrame frame) {
            var process = frame.Process;
            var pythonInfo = process.GetPythonRuntimeInfo();
            ulong addr = 0;
            if (pythonInfo.LanguageVersion <= PythonLanguageVersion.V35) {
                if (frame.ModuleInstance == pythonInfo.DLLs.Python) {
                    addr = pythonInfo.DLLs.Python.GetFunctionAddress("PyEval_EvalFrameEx");
                }
            } else {
                if (frame.ModuleInstance == pythonInfo.DLLs.DebuggerHelper) {
                    addr = pythonInfo.DLLs.DebuggerHelper.GetFunctionAddress("EvalFrameFunc");
                }
            }

            if (addr == 0) {
                return false;
            }

            return frame.InstructionAddress.IsInSameFunction(process.CreateNativeInstructionAddress(addr));
        }
コード例 #47
0
 public static DkmIntermediateEvaluationResult Create(
     DkmInspectionContext InspectionContext,
     DkmStackWalkFrame StackFrame,
     string Name,
     string FullName,
     string Expression,
     DkmLanguage IntermediateLanguage,
     DkmRuntimeInstance TargetRuntime,
     DkmDataItem DataItem)
 {
     return(new DkmIntermediateEvaluationResult(
                InspectionContext,
                StackFrame,
                Name,
                FullName,
                Expression,
                IntermediateLanguage,
                TargetRuntime,
                DataItem));
 }
コード例 #48
0
 public static DkmFailedEvaluationResult Create(
     DkmInspectionContext InspectionContext,
     DkmStackWalkFrame StackFrame,
     string Name,
     string FullName,
     string ErrorMessage,
     DkmEvaluationResultFlags Flags,
     string Type,
     DkmDataItem DataItem)
 {
     return(new DkmFailedEvaluationResult(
                InspectionContext,
                StackFrame,
                Name,
                FullName,
                ErrorMessage,
                Flags,
                Type,
                DataItem));
 }
コード例 #49
0
 public static DkmFailedEvaluationResult Create(
     DkmInspectionContext InspectionContext,
     DkmStackWalkFrame StackFrame,
     string Name,
     string FullName,
     string ErrorMessage,
     DkmEvaluationResultFlags Flags,
     string Type,
     DkmDataItem DataItem)
 {
     return new DkmFailedEvaluationResult(
         InspectionContext,
         StackFrame,
         Name,
         FullName,
         ErrorMessage,
         Flags,
         Type,
         DataItem);
 }
コード例 #50
0
 public static DkmIntermediateEvaluationResult Create(
     DkmInspectionContext InspectionContext,
     DkmStackWalkFrame StackFrame,
     string Name,
     string FullName,
     string Expression,
     DkmLanguage IntermediateLanguage,
     DkmRuntimeInstance TargetRuntime,
     DkmDataItem DataItem)
 {
     return new DkmIntermediateEvaluationResult(
         InspectionContext,
         StackFrame,
         Name,
         FullName,
         Expression,
         IntermediateLanguage,
         TargetRuntime,
         DataItem);
 }
コード例 #51
0
    public override object GetArgumentValue(DkmStackWalkFrame frame, int index) {
      byte[] argumentBuffer = ReadArgumentBytes(frame);

      int wordZeroIndex = 0;
      for (int i=0; i < index; ++i)
        wordZeroIndex += _parameters[i].GetPaddedSize(WordSize);
      FunctionParameter requestedParameter = _parameters[index];
      int requestedParamSize = requestedParameter.GetSize(WordSize);
      byte[] result = new byte[requestedParamSize];

      Array.ConstrainedCopy(argumentBuffer, wordZeroIndex, result, 0, requestedParamSize);

      switch (requestedParamSize) {
        case 4:
          return BitConverter.ToUInt32(result, 0);
        case 8:
          return BitConverter.ToUInt64(result, 0);
        default:
          return result;
      }
    }
コード例 #52
0
        internal DkmEvaluationResult(
            DkmInspectionContext InspectionContext,
            DkmStackWalkFrame StackFrame,
            string Name,
            string FullName,
            DkmEvaluationResultFlags Flags,
            string Type,
            DkmDataItem DataItem)
        {
            this.InspectionContext = InspectionContext;
            this.StackFrame = StackFrame;
            this.Name = Name;
            this.FullName = FullName;
            this.Flags = Flags;
            this.Type = Type;

            if (DataItem != null)
            {
                this.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
            }
        }
コード例 #53
0
        private byte[] ReadArgumentBytes(DkmStackWalkFrame frame)
        {
            // In the x64 calling convention, the first 4 arguments are passed in registers, and the
              // remaining arguments are passed on the stack.  However, space for all arguments is
              // allocated on the stack, even if the argument is passed one of the first 4 which is passed
              // by register.  Furthermore, a minimum of 4*WordSize bytes is allocated on the stack for
              // function parameters, even if the function accepts less than 4 arguments.
              int bytesRequired = 0;
              foreach (FunctionParameter param in _parameters)
            bytesRequired += param.GetPaddedSize(WordSize);
              byte[] stack = new byte[bytesRequired];

              ulong rsp = frame.Registers.GetStackPointer();
              // The first word on the stack is the return address, similar to in x86 calling conventions.
              frame.Process.ReadMemory(rsp + 8, DkmReadMemoryFlags.None, stack);

              // Since everything is padded, we should have a multiple-of-8 bytes.  The first four
              // arguments may or may not actually be on the stack since it's register spill-over space,
              // but they are guaranteed to be in RCX, RDX, R8, and R9 respectively.  So get their values
              // from the registers and then write them into our copy of the stack.
              Debug.Assert(bytesRequired % 8 == 0);
              if (bytesRequired > 0) {
            ulong rcx = frame.VscxGetRegisterValue64(CpuRegister.Rcx);
            BitConverter.GetBytes(rcx).CopyTo(stack, 0);
              }
              if (bytesRequired > 8) {
            ulong rdx = frame.VscxGetRegisterValue64(CpuRegister.Rdx);
            BitConverter.GetBytes(rdx).CopyTo(stack, 8);
              }
              if (bytesRequired > 16) {
            ulong r8 = frame.VscxGetRegisterValue64(CpuRegister.R8);
            BitConverter.GetBytes(r8).CopyTo(stack, 16);
              }
              if (bytesRequired > 24) {
            ulong r9 = frame.VscxGetRegisterValue64(CpuRegister.R9);
            BitConverter.GetBytes(r9).CopyTo(stack, 24);
              }

              return stack;
        }
コード例 #54
0
        public static DkmSuccessEvaluationResult Create(DkmInspectionContext InspectionContext, DkmStackWalkFrame StackFrame, string Name, string FullName, DkmEvaluationResultFlags Flags, string Value, string EditableValue, string Type, DkmEvaluationResultCategory Category, DkmEvaluationResultAccessType Access, DkmEvaluationResultStorageType StorageType, DkmEvaluationResultTypeModifierFlags TypeModifierFlags, DkmDataAddress Address, ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers, ReadOnlyCollection<DkmModuleInstance> ExternalModules, DkmDataItem DataItem)
        {
            DkmSuccessEvaluationResult result = new DkmSuccessEvaluationResult
            {
                InspectionContext = InspectionContext,
                Name = Name,
                FullName = FullName,
                Flags = Flags,
                Value = Value,
                Type = Type,
                Category = Category,
                EditableValue = EditableValue,
                CustomUIVisualizers = CustomUIVisualizers
            };

            if (DataItem != null)
            {
                result.SetDataItem(DkmDataCreationDisposition.CreateNew, DataItem);
            }

            return result;
        }
コード例 #55
0
 public static DkmSuccessEvaluationResult Create(
     DkmInspectionContext InspectionContext,
     DkmStackWalkFrame StackFrame,
     string Name,
     string FullName,
     DkmEvaluationResultFlags Flags,
     string Value,
     string EditableValue,
     string Type,
     DkmEvaluationResultCategory Category,
     DkmEvaluationResultAccessType Access,
     DkmEvaluationResultStorageType StorageType,
     DkmEvaluationResultTypeModifierFlags TypeModifierFlags,
     DkmDataAddress Address,
     ReadOnlyCollection<DkmCustomUIVisualizerInfo> CustomUIVisualizers,
     ReadOnlyCollection<DkmModuleInstance> ExternalModules,
     DkmDataItem DataItem)
 {
     return new DkmSuccessEvaluationResult(
         InspectionContext,
         StackFrame,
         Name,
         FullName,
         Flags,
         Value,
         EditableValue,
         Type,
         Category,
         Access,
         StorageType,
         TypeModifierFlags,
         Address,
         CustomUIVisualizers,
         ExternalModules,
         DataItem);
 }
コード例 #56
0
        public CppExpressionEvaluator(DkmInspectionContext inspectionContext, DkmStackWalkFrame stackFrame) {
            _process = stackFrame.Process;
            var thread = stackFrame.Thread;

            if (stackFrame.InstructionAddress is DkmNativeInstructionAddress) {
                _nativeFrame = stackFrame;
            } else {
                var customAddr = stackFrame.InstructionAddress as DkmCustomInstructionAddress;
                if (customAddr == null) {
                    throw new ArgumentException();
                }

                var loc = new SourceLocation(customAddr.AdditionalData, _process);
                if (loc.NativeAddress == null) {
                    throw new ArgumentException();
                }

                _nativeFrame = DkmStackWalkFrame.Create(thread, loc.NativeAddress, stackFrame.FrameBase, stackFrame.FrameSize,
                    DkmStackWalkFrameFlags.None, null, stackFrame.Registers, null);
            }

            _cppInspectionContext = DkmInspectionContext.Create(inspectionContext.InspectionSession, _process.GetNativeRuntimeInstance(), thread, Timeout,
                DkmEvaluationFlags.TreatAsExpression | DkmEvaluationFlags.NoSideEffects, DkmFuncEvalFlags.None, inspectionContext.Radix, CppLanguage, null);
        }
コード例 #57
0
 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();
     }
 }
コード例 #58
0
 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();
 }
コード例 #59
0
 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);
     }
 }
コード例 #60
0
ファイル: ExpressionEvaluator.cs プロジェクト: omnimark/PTVS
        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)));
            }
        }