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) });
        }
示例#2
0
            internal string ExecuteExpression(string expression, DkmStackContext stackContext, DkmStackWalkFrame input, bool allowZero)
            {
                var compilerId         = new DkmCompilerId(DkmVendorId.Microsoft, DkmLanguageId.Cpp);
                var language           = DkmLanguage.Create("C++", compilerId);
                var languageExpression = DkmLanguageExpression.Create(language, DkmEvaluationFlags.None, expression, null);

                var inspectionContext = DkmInspectionContext.Create(stackContext.InspectionSession, input.RuntimeInstance, stackContext.Thread, 200, DkmEvaluationFlags.None, DkmFuncEvalFlags.None, 10, language, null);

                var    workList   = DkmWorkList.Create(null);
                string resultText = null;

                inspectionContext.EvaluateExpression(workList, languageExpression, input, res =>
                {
                    if (res.ErrorCode == 0)
                    {
                        var result = res.ResultObject as DkmSuccessEvaluationResult;

                        if (result != null && result.TagValue == DkmEvaluationResult.Tag.SuccessResult && (allowZero || result.Address.Value != 0))
                        {
                            resultText = result.Value;
                        }

                        res.ResultObject.Close();
                    }
                });

                workList.Execute();

                return(resultText);
            }
示例#3
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() });
        }
    }
}
示例#4
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);
        }
        /// <summary>
        /// Returns the instance of HelloWorldDataItem associated with the input DkmStackContext
        /// object. If there is not currently an associated HelloWorldDataItem, a new data item
        /// will be created.
        /// </summary>
        /// <param name="context">Object to obtain the data item from</param>
        /// <returns>The associated data item</returns>
        public static HelloWordDataItem GetInstance(DkmStackContext context)
        {
            HelloWordDataItem item = GetExistingInstance(context);
            if (item != null)
                return item;

            item = new HelloWordDataItem();
            context.SetDataItem<HelloWordDataItem>(DkmDataCreationDisposition.CreateNew, item);

            return item;
        }
		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);
		}
示例#7
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));
 }
        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;
        }
		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() };
		}
        /// <summary>
        /// Returns the instance of HelloWorldDataItem associated with the input DkmStackContext
        /// object. If there is not currently an associated HelloWorldDataItem, a new data item
        /// will be created.
        /// </summary>
        /// <param name="context">Object to obtain the data item from</param>
        /// <returns>The associated data item</returns>
        public static HelloWordDataItem GetInstance(DkmStackContext context)
        {
            HelloWordDataItem item = GetExistingInstance(context);

            if (item != null)
            {
                return(item);
            }

            item = new HelloWordDataItem();
            context.SetDataItem <HelloWordDataItem>(DkmDataCreationDisposition.CreateNew, item);

            return(item);
        }
示例#11
0
        DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
        {
            if (input == null)
            {
                return(null);
            }

            var filter = input.Process.GetDataItem <CallStackFilter>();

            try {
                if (filter != null)
                {
                    return(filter.FilterNextFrame(stackContext, input));
                }
            } catch (DkmException) {
            }
            return(new[] { input });
        }
        private static DkmStackWalkFrame UnityMixedStackFrame(DkmStackContext stackContext, DkmStackWalkFrame frame)
        {
            RefreshStackData(frame.Process.LivePart.Id);
            string name = null;

            if (TryGetDescriptionForIp(frame.InstructionAddress.CPUInstructionPart.InstructionPointer, out name))
            {
                return(DkmStackWalkFrame.Create(
                           stackContext.Thread,
                           frame.InstructionAddress,
                           frame.FrameBase,
                           frame.FrameSize,
                           frame.Flags,
                           name,
                           frame.Registers,
                           frame.Annotations));
            }

            return(frame);
        }
示例#13
0
        public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame nativeFrame)
        {
            PyFrameObject pythonFrame          = null;
            var           nativeModuleInstance = nativeFrame.ModuleInstance;

            if (nativeModuleInstance == _pyrtInfo.DLLs.DebuggerHelper)
            {
                if (_pyrtInfo.LanguageVersion < PythonLanguageVersion.V36 ||
                    (pythonFrame = PyFrameObject.TryCreate(nativeFrame)) == null)
                {
                    return(DebuggerOptions.ShowNativePythonFrames ? new[] { nativeFrame } : new DkmStackWalkFrame[0]);
                }
            }

            var result = new List <DkmStackWalkFrame>();

            if (pythonFrame == null)
            {
                var stackWalkData = stackContext.GetDataItem <StackWalkContextData>();
                if (stackWalkData == null)
                {
                    stackWalkData = new StackWalkContextData();
                    stackContext.SetDataItem(DkmDataCreationDisposition.CreateNew, stackWalkData);
                }
                bool?wasLastFrameNative = stackWalkData.IsLastFrameNative;

                if (nativeModuleInstance != _pyrtInfo.DLLs.Python && nativeModuleInstance != _pyrtInfo.DLLs.CTypes)
                {
                    stackWalkData.IsLastFrameNative = true;
                    if (wasLastFrameNative == false)
                    {
                        result.Add(DkmStackWalkFrame.Create(nativeFrame.Thread, null, nativeFrame.FrameBase, nativeFrame.FrameSize,
                                                            DkmStackWalkFrameFlags.NonuserCode, Strings.DebugCallStackNativeToPythonTransition, null, null));
                    }
                    else
                    {
                        stackWalkData.IsLastFrameNative = true;
                    }
                    result.Add(nativeFrame);
                    return(result.ToArray());
                }
                else
                {
                    stackWalkData.IsLastFrameNative = false;
                    if (wasLastFrameNative == true)
                    {
                        result.Add(DkmStackWalkFrame.Create(nativeFrame.Thread, null, nativeFrame.FrameBase, nativeFrame.FrameSize,
                                                            DkmStackWalkFrameFlags.NonuserCode, Strings.DebugCallStackPythonToNativeTransition, null, null));
                    }
                }

                pythonFrame = PyFrameObject.TryCreate(nativeFrame);
            }
            if (pythonFrame == null)
            {
                if (DebuggerOptions.ShowNativePythonFrames)
                {
                    result.Add(nativeFrame);
                }
                return(result.ToArray());
            }

            PyCodeObject code = pythonFrame.f_code.Read();
            var          loc  = new SourceLocation(
                code.co_filename.Read().ToStringOrNull(),
                pythonFrame.f_lineno.Read(),
                code.co_name.Read().ToStringOrNull(),
                nativeFrame.InstructionAddress as DkmNativeInstructionAddress);

            var pythonRuntime         = _process.GetPythonRuntimeInstance();
            var pythonModuleInstances = pythonRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>();
            var pyModuleInstance      = pythonModuleInstances.Where(m => m.FullName == loc.FileName).FirstOrDefault();

            if (pyModuleInstance == null)
            {
                pyModuleInstance = pythonModuleInstances.Single(m => m.Module.Id.Mvid == Guids.UnknownPythonModuleGuid);
            }

            var encodedLocation = loc.Encode();
            var instrAddr       = DkmCustomInstructionAddress.Create(pythonRuntime, pyModuleInstance, encodedLocation, 0, encodedLocation, null);
            var frame           = DkmStackWalkFrame.Create(
                nativeFrame.Thread,
                instrAddr,
                nativeFrame.FrameBase,
                nativeFrame.FrameSize,
                DkmStackWalkFrameFlags.None,
                null,
                nativeFrame.Registers,
                nativeFrame.Annotations);

            result.Add(frame);

            if (DebuggerOptions.ShowNativePythonFrames)
            {
                result.Add(nativeFrame);
            }
            return(result.ToArray());
        }
示例#14
0
        public Tuple <ulong, ulong, ulong>[] GetThreadStackTrace(uint threadId, byte[] threadContextBytes)
        {
            return(ExecuteOnDkmInitializedThread(() =>
            {
                DkmThread thread = GetThread(threadId);
                List <DkmStackFrame> frames = new List <DkmStackFrame>();
                DkmProcess process = thread.Process;

                using (DkmInspectionSession dkmInspectionSession = DkmInspectionSession.Create(process, null))
                {
                    using (DkmStackContext dkmStackContext = DkmStackContext.Create(dkmInspectionSession, thread, DkmCallStackFilterOptions.None, new DkmFrameFormatOptions(), new System.Collections.ObjectModel.ReadOnlyCollection <byte>(threadContextBytes), null))
                    {
                        bool done = false;

                        while (!done)
                        {
                            DkmWorkList dkmWorkList = DkmWorkList.Create(null);

                            dkmStackContext.GetNextFrames(dkmWorkList, int.MaxValue, (ar) =>
                            {
                                frames.AddRange(ar.Frames);
                                done = ar.Frames.Length == 0;
                            });

                            dkmWorkList.Execute();
                        }
                    }
                }

                threads[(int)threadId].Frames.Value = frames.ToArray();

                Tuple <ulong, ulong, ulong>[] result = new Tuple <ulong, ulong, ulong> [frames.Count];

                for (int i = 0; i < result.Length; i++)
                {
                    ulong stackOffset, instructionOffset;

                    switch (frames[i].Registers.TagValue)
                    {
                    case DkmFrameRegisters.Tag.X64Registers:
                        {
                            DkmX64FrameRegisters registers = (DkmX64FrameRegisters)frames[i].Registers;

                            instructionOffset = registers.Rip;
                            stackOffset = registers.Rsp;
                        }
                        break;

                    case DkmFrameRegisters.Tag.X86Registers:
                        {
                            DkmX86FrameRegisters registers = (DkmX86FrameRegisters)frames[i].Registers;

                            instructionOffset = registers.Eip;
                            stackOffset = registers.Esp;
                        }
                        break;

                    default:
                        throw new NotImplementedException("Unexpected DkmFrameRegisters.Tag");
                    }

                    bool found = false;
                    ulong frameOffset = 0;

                    for (int j = 0; !found && j < frames[i].Registers.UnwoundRegisters.Count; j++)
                    {
                        switch ((Dia2Lib.CV_HREG_e)frames[i].Registers.UnwoundRegisters[j].Identifier)
                        {
                        case Dia2Lib.CV_HREG_e.CV_AMD64_EBP:
                        case Dia2Lib.CV_HREG_e.CV_AMD64_RBP:
                            {
                                byte[] bytes = frames[i].Registers.UnwoundRegisters[j].Value.ToArray();

                                found = true;
                                frameOffset = bytes.Length == 8 ? BitConverter.ToUInt64(bytes, 0) : BitConverter.ToUInt32(bytes, 0);
                                break;
                            }
                        }
                    }

                    if (instructionOffset != frames[i].InstructionAddress.CPUInstructionPart.InstructionPointer)
                    {
                        throw new Exception("Instruction offset is not the same?");
                    }

                    result[i] = Tuple.Create(instructionOffset, stackOffset, frameOffset);
                }

                return result;
            }));
        }
 /// <summary>
 /// Returns the instance of HelloWorldDataItem associated with the input DkmStackContext
 /// object. If there is not currently an associated HelloWorldDataItem, return null.
 /// </summary>
 /// <param name="context">Object to obtain the data item from</param>
 /// <returns>[OPTIONAL] The associated data item</returns>
 public static HelloWordDataItem GetExistingInstance(DkmStackContext context)
 {
     return context.GetDataItem<HelloWordDataItem>();
 }
示例#16
0
 public PmipRunner(DkmStackContext stackContext, DkmStackWalkFrame frame)
 {
     _stackContext      = stackContext;
     _frame             = frame;
     _inspectionContext = CreateInspectionContext(stackContext, frame);
 }
 /// <summary>
 /// Returns the instance of HelloWorldDataItem associated with the input DkmStackContext
 /// object. If there is not currently an associated HelloWorldDataItem, return null.
 /// </summary>
 /// <param name="context">Object to obtain the data item from</param>
 /// <returns>[OPTIONAL] The associated data item</returns>
 public static HelloWordDataItem GetExistingInstance(DkmStackContext context)
 {
     return(context.GetDataItem <HelloWordDataItem>());
 }
示例#18
0
        public DkmStackWalkFrame[] FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame nativeFrame) {
            var nativeModuleInstance = nativeFrame.ModuleInstance;
            if (nativeModuleInstance == _pyrtInfo.DLLs.DebuggerHelper) {
                return DebuggerOptions.ShowNativePythonFrames ? new[] { nativeFrame } : new DkmStackWalkFrame[0];
            }

            var result = new List<DkmStackWalkFrame>();
            var stackWalkData = stackContext.GetDataItem<StackWalkContextData>();
            if (stackWalkData == null) {
                stackWalkData = new StackWalkContextData();
                stackContext.SetDataItem(DkmDataCreationDisposition.CreateNew, stackWalkData);
            }
            bool? wasLastFrameNative = stackWalkData.IsLastFrameNative;

            if (nativeModuleInstance != _pyrtInfo.DLLs.Python && nativeModuleInstance != _pyrtInfo.DLLs.CTypes) {
                stackWalkData.IsLastFrameNative = true;
                if (wasLastFrameNative == false) {
                    result.Add(DkmStackWalkFrame.Create(nativeFrame.Thread, null, nativeFrame.FrameBase, nativeFrame.FrameSize,
                        DkmStackWalkFrameFlags.NonuserCode, "[Native to Python Transition]", null, null));
                } else {
                    stackWalkData.IsLastFrameNative = true;
                }
                result.Add(nativeFrame);
                return result.ToArray();
            } else {
                stackWalkData.IsLastFrameNative = false;
                if (wasLastFrameNative == true) {
                    result.Add(DkmStackWalkFrame.Create(nativeFrame.Thread, null, nativeFrame.FrameBase, nativeFrame.FrameSize,
                        DkmStackWalkFrameFlags.NonuserCode, "[Python to Native Transition]", null, null));
                }
            }

            var pythonFrame = PyFrameObject.TryCreate(nativeFrame);
            if (pythonFrame == null) {
                if (DebuggerOptions.ShowNativePythonFrames) {
                    result.Add(nativeFrame);
                }
                return result.ToArray();
            }

            PyCodeObject code = pythonFrame.f_code.Read();
            var loc = new SourceLocation(
                code.co_filename.Read().ToStringOrNull(),
                pythonFrame.f_lineno.Read(),
                code.co_name.Read().ToStringOrNull(),
                nativeFrame.InstructionAddress as DkmNativeInstructionAddress);

            var pythonRuntime = _process.GetPythonRuntimeInstance();
            var pythonModuleInstances = pythonRuntime.GetModuleInstances().OfType<DkmCustomModuleInstance>();
            var pyModuleInstance = pythonModuleInstances.Where(m => m.FullName == loc.FileName).FirstOrDefault();
            if (pyModuleInstance == null) {
                pyModuleInstance = pythonModuleInstances.Single(m => m.Module.Id.Mvid == Guids.UnknownPythonModuleGuid);
            }

            var encodedLocation = loc.Encode();
            var instrAddr = DkmCustomInstructionAddress.Create(pythonRuntime, pyModuleInstance, encodedLocation, 0, encodedLocation, null);
            var frame = DkmStackWalkFrame.Create(
                nativeFrame.Thread,
                instrAddr,
                nativeFrame.FrameBase,
                nativeFrame.FrameSize,
                DkmStackWalkFrameFlags.None,
                null,
                nativeFrame.Registers,
                nativeFrame.Annotations);
            result.Add(frame);

            if (DebuggerOptions.ShowNativePythonFrames) {
                result.Add(nativeFrame);
            }
            return result.ToArray();
        }
示例#19
0
            DkmStackWalkFrame[] IDkmCallStackFilter.FilterNextFrame(DkmStackContext stackContext, DkmStackWalkFrame input)
            {
                if (input == null) // null input frame indicates the end of the call stack. This sample does nothing on end-of-stack.
                {
                    var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(stackContext.InspectionSession.Process);

                    processData.nullcFramePosition = 1;

                    return(null);
                }

                if (input.InstructionAddress == null)
                {
                    return(new DkmStackWalkFrame[1] {
                        input
                    });
                }

                if (input.InstructionAddress.ModuleInstance != null)
                {
                    if (input.BasicSymbolInfo != null && input.BasicSymbolInfo.MethodName == "ExecutorRegVm::RunCode")
                    {
                        var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(input.Thread.Process);

                        InitNullcDebugFunctions(processData, input.RuntimeInstance);

                        if (processData.nullcIsMissing)
                        {
                            return(new DkmStackWalkFrame[1] {
                                input
                            });
                        }

                        string vmInstructionStr = ExecuteExpression("instruction - codeBase", stackContext, input, true);

                        string ptrValue = DebugHelpers.Is64Bit(input.Thread.Process) ? "longValue" : "intValue";

                        string vmDataOffsetStr = ExecuteExpression($"(unsigned long long)regFilePtr[1].{ptrValue} - (unsigned long long)rvm->dataStack.data", stackContext, input, true);

                        if (vmInstructionStr != null && vmDataOffsetStr != null)
                        {
                            ulong vmInstruction = ulong.Parse(vmInstructionStr);

                            string stackFrameDesc = ExecuteExpression($"((char*(*)(unsigned, unsigned)){processData.nullcDebugGetVmAddressLocation})({vmInstruction}, 0),sb", stackContext, input, false);

                            var nullcCustomRuntime = input.Thread.Process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcVmRuntimeGuid);

                            if (stackFrameDesc != null && nullcCustomRuntime != null)
                            {
                                var flags = input.Flags;

                                flags = flags & ~(DkmStackWalkFrameFlags.NonuserCode | DkmStackWalkFrameFlags.UserStatusNotDetermined);
                                flags = flags | DkmStackWalkFrameFlags.InlineOptimized;

                                DkmCustomModuleInstance nullcModuleInstance = nullcCustomRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid);

                                if (nullcModuleInstance != null)
                                {
                                    DkmInstructionAddress instructionAddress = DkmCustomInstructionAddress.Create(nullcCustomRuntime, nullcModuleInstance, null, vmInstruction, null, null);

                                    var rawAnnotations = new List <DkmStackWalkFrameAnnotation>();

                                    // Additional unique request id
                                    rawAnnotations.Add(DkmStackWalkFrameAnnotation.Create(DebugHelpers.NullcCallStackDataBaseGuid, ulong.Parse(vmDataOffsetStr)));

                                    var annotations = new ReadOnlyCollection <DkmStackWalkFrameAnnotation>(rawAnnotations);

                                    DkmStackWalkFrame frame = DkmStackWalkFrame.Create(stackContext.Thread, instructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, annotations, nullcModuleInstance, null, null);

                                    return(new DkmStackWalkFrame[2] {
                                        frame, input
                                    });
                                }
                            }
                        }
                    }

                    return(new DkmStackWalkFrame[1] {
                        input
                    });
                }

                // Currently we want to provide info only for JiT frames
                if (!input.Flags.HasFlag(DkmStackWalkFrameFlags.UserStatusNotDetermined))
                {
                    return(new DkmStackWalkFrame[1] {
                        input
                    });
                }

                try
                {
                    var processData = DebugHelpers.GetOrCreateDataItem <NullcStackFilterDataItem>(input.Thread.Process);

                    InitNullcDebugFunctions(processData, input.RuntimeInstance);

                    if (processData.nullcIsMissing)
                    {
                        return new DkmStackWalkFrame[1] {
                                   input
                        }
                    }
                    ;

                    string stackFrameDesc = ExecuteExpression($"((char*(*)(void*, unsigned)){processData.nullcDebugGetNativeAddressLocation})((void*)0x{input.InstructionAddress.CPUInstructionPart.InstructionPointer:X}, 0),sb", stackContext, input, false);

                    if (stackFrameDesc != null)
                    {
                        var flags = input.Flags;

                        flags = flags & ~(DkmStackWalkFrameFlags.NonuserCode | DkmStackWalkFrameFlags.UserStatusNotDetermined);

                        if (stackFrameDesc == "[Transition to nullc]")
                        {
                            return(new DkmStackWalkFrame[1] {
                                DkmStackWalkFrame.Create(stackContext.Thread, input.InstructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, input.Annotations)
                            });
                        }

                        DkmStackWalkFrame frame = null;

                        var nullcCustomRuntime = input.Thread.Process.GetRuntimeInstances().OfType <DkmCustomRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid);
                        var nullcNativeRuntime = DebugHelpers.useDefaultRuntimeInstance ? input.Thread.Process.GetNativeRuntimeInstance() : input.Thread.Process.GetRuntimeInstances().OfType <DkmNativeRuntimeInstance>().FirstOrDefault(el => el.Id.RuntimeType == DebugHelpers.NullcRuntimeGuid);

                        if (DebugHelpers.useNativeInterfaces ? nullcNativeRuntime != null : nullcCustomRuntime != null)
                        {
                            DkmModuleInstance nullcModuleInstance;

                            if (DebugHelpers.useNativeInterfaces)
                            {
                                nullcModuleInstance = nullcNativeRuntime.GetModuleInstances().OfType <DkmNativeModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid);
                            }
                            else
                            {
                                nullcModuleInstance = nullcCustomRuntime.GetModuleInstances().OfType <DkmCustomModuleInstance>().FirstOrDefault(el => el.Module != null && el.Module.CompilerId.VendorId == DebugHelpers.NullcCompilerGuid);
                            }

                            if (nullcModuleInstance != null)
                            {
                                // If the top of the call stack is a nullc frame, nullc call stack wont have an entry for it and we start from 0, otherwise we start from default value of 1
                                if (input.Flags.HasFlag(DkmStackWalkFrameFlags.TopFrame))
                                {
                                    processData.nullcFramePosition = 0;
                                }

                                string stackFrameBase = ExecuteExpression($"((unsigned(*)(unsigned)){processData.nullcDebugGetReversedStackDataBase})({processData.nullcFramePosition})", stackContext, input, true);

                                processData.nullcFramePosition++;

                                if (int.TryParse(stackFrameBase, out int stackFrameBaseValue))
                                {
                                    DkmInstructionAddress instructionAddress;

                                    if (DebugHelpers.useNativeInterfaces)
                                    {
                                        var rva = (uint)(input.InstructionAddress.CPUInstructionPart.InstructionPointer - nullcModuleInstance.BaseAddress);

                                        instructionAddress = DkmNativeInstructionAddress.Create(nullcNativeRuntime, nullcModuleInstance as DkmNativeModuleInstance, rva, input.InstructionAddress.CPUInstructionPart);
                                    }
                                    else
                                    {
                                        instructionAddress = DkmCustomInstructionAddress.Create(nullcCustomRuntime, nullcModuleInstance as DkmCustomModuleInstance, null, input.InstructionAddress.CPUInstructionPart.InstructionPointer, null, input.InstructionAddress.CPUInstructionPart);
                                    }

                                    var rawAnnotations = new List <DkmStackWalkFrameAnnotation>();

                                    // Additional unique request id
                                    rawAnnotations.Add(DkmStackWalkFrameAnnotation.Create(DebugHelpers.NullcCallStackDataBaseGuid, (ulong)(stackFrameBaseValue)));

                                    var annotations = new ReadOnlyCollection <DkmStackWalkFrameAnnotation>(rawAnnotations);

                                    frame = DkmStackWalkFrame.Create(stackContext.Thread, instructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, annotations, nullcModuleInstance, null, null);
                                }
                            }
                        }

                        if (frame == null)
                        {
                            frame = DkmStackWalkFrame.Create(stackContext.Thread, input.InstructionAddress, input.FrameBase, input.FrameSize, flags, stackFrameDesc, input.Registers, input.Annotations);
                        }

                        return(new DkmStackWalkFrame[1] {
                            frame
                        });
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Failed to evaluate: " + ex.ToString());
                }

                return(new DkmStackWalkFrame[1] {
                    input
                });
            }
        public void OnBeginStepOut(DkmThread thread)
        {
            // When we're stepping out while in Python code, there are two possibilities. Either the stack looks like this:
            //
            //   PythonFrame1
            //   PythonFrame2
            //
            // or else it looks like this:
            //
            //   PythonFrame
            //   [Native to Python transition]
            //   NativeFrame
            //
            // In both cases, we use native breakpoints on the return address to catch the end of step-out operation.
            // For Python-to-native step-out, this is the only option. For Python-to-Python, it would seem that TraceFunc
            // can detect it via PyTrace_RETURN, but it doesn't actually know whether the return is to Python or to
            // native at the point where it's reported - and, in any case, we need to let PyEval_EvalFrameEx to return
            // before reporting the completion of that step-out (otherwise we will show the returning frame in call stack).

            // Find the destination for step-out by walking the call stack and finding either the first native frame
            // outside of Python and helper DLLs, or the second Python frame.
            var           inspectionSession  = DkmInspectionSession.Create(_process, null);
            var           frameFormatOptions = new DkmFrameFormatOptions(DkmVariableInfoFlags.None, DkmFrameNameFormatOptions.None, DkmEvaluationFlags.None, 10000, 10);
            var           stackContext       = DkmStackContext.Create(inspectionSession, thread, DkmCallStackFilterOptions.None, frameFormatOptions, null, null);
            DkmStackFrame frame = null;

            for (int pyFrameCount = 0; pyFrameCount != 2;)
            {
                DkmStackFrame[] frames   = null;
                var             workList = DkmWorkList.Create(null);
                stackContext.GetNextFrames(workList, 1, (result) => { frames = result.Frames; });
                workList.Execute();
                if (frames == null || frames.Length != 1)
                {
                    return;
                }
                frame = frames[0];

                var frameModuleInstance = frame.ModuleInstance;
                if (frameModuleInstance is DkmNativeModuleInstance &&
                    frameModuleInstance != _pyrtInfo.DLLs.Python &&
                    frameModuleInstance != _pyrtInfo.DLLs.DebuggerHelper &&
                    frameModuleInstance != _pyrtInfo.DLLs.CTypes)
                {
                    break;
                }
                else if (frame.RuntimeInstance != null && frame.RuntimeInstance.Id.RuntimeType == Guids.PythonRuntimeTypeGuid)
                {
                    ++pyFrameCount;
                }
            }

            var nativeAddr = frame.InstructionAddress as DkmNativeInstructionAddress;

            if (nativeAddr == null)
            {
                var customAddr = frame.InstructionAddress as DkmCustomInstructionAddress;
                if (customAddr == null)
                {
                    return;
                }

                var loc = new SourceLocation(customAddr.AdditionalData, thread.Process);
                nativeAddr = loc.NativeAddress;
                if (nativeAddr == null)
                {
                    return;
                }
            }

            var bp = DkmRuntimeInstructionBreakpoint.Create(Guids.PythonStepTargetSourceGuid, thread, nativeAddr, false, null);

            bp.Enable();

            _stepOutTargetBreakpoints.Add(bp);
        }
		public PmipRunner(DkmStackContext stackContext, DkmStackWalkFrame frame)
		{
			_stackContext = stackContext;
			_frame = frame;
			_inspectionContext = CreateInspectionContext(stackContext, frame);
		}