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); }
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); }
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)); }
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); }
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); }
public DkmStackWalkFrame PmipStackFrame() { PmipFunctionDataItem pmipFunction; if (!TryGetPmipFunction(out pmipFunction)) { return(_frame); } var ip = $"0x{_frame.InstructionAddress.CPUInstructionPart.InstructionPointer:X}"; var call = $"((char*(*)(void*)){pmipFunction.PmipFunction})((void*){ip})"; var result = ""; var isNull = true; var eval = EvaluateExpression(call, r => { isNull = r.Address.InstructionAddress.CPUInstructionPart.InstructionPointer == 0; result = r.Value; }); if (!eval || isNull) { return(_frame); } return(DkmStackWalkFrame.Create( _stackContext.Thread, _frame.InstructionAddress, _frame.FrameBase, _frame.FrameSize, _frame.Flags, result, _frame.Registers, _frame.Annotations)); }
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()); }
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 }); }