private void OnStepTargetBreakpoint(DkmThread thread) { if (_stepper == null) { Debug.Fail("OnStepTargetBreakpoint called but no step operation is in progress."); throw new InvalidOperationException(); } if (_stepper.StepKind == DkmStepKind.Into) { StepDone(thread).OnStepArbitration(DkmStepArbitrationReason.ExitRuntime, _process.GetPythonRuntimeInstance()); } else { // Just because we hit the return breakpoint doesn't mean that we've actually returned - it could be // a recursive call. Check stack depth to distinguish this from an actual return. var beginState = _stepper.GetDataItem <StepBeginState>(); if (beginState != null) { ulong retAddr, frameBase, vframe; thread.GetCurrentFrameInfo(out retAddr, out frameBase, out vframe); if (frameBase > beginState.FrameBase) { OnStepComplete(thread); } } } }
void IDkmRuntimeBreakpointReceived.OnRuntimeBreakpointReceived(DkmRuntimeBreakpoint runtimeBreakpoint, DkmThread thread, bool hasException, DkmEventDescriptorS eventDescriptor) { if (runtimeBreakpoint.SourceId == Guids.LocalComponentGuid) { ulong retAddr, frameBase, vframe; thread.GetCurrentFrameInfo(out retAddr, out frameBase, out vframe); new LocalComponent.HandleBreakpointRequest { BreakpointId = runtimeBreakpoint.UniqueId, ThreadId = thread.UniqueId, FrameBase = frameBase, VFrame = vframe, ReturnAddress = retAddr }.SendHigher(thread.Process); } else if (runtimeBreakpoint.SourceId == Guids.PythonTraceManagerSourceGuid || runtimeBreakpoint.SourceId == Guids.PythonStepTargetSourceGuid) { var traceManager = runtimeBreakpoint.Process.GetDataItem <TraceManager>(); if (traceManager != null) { traceManager.OnNativeBreakpointHit(runtimeBreakpoint, thread); } } else { Debug.Fail("RemoteComponent received a notification for a breakpoint that it does not know how to handle."); throw new ArgumentException(); } }
ulong GetReturnAddress(DkmThread thread) { // GetCurrentFrameInfo should provide the return address but the result is actually the current instruction address... so we have to go and lookup stack frame data at [ebp+4] var frameRegs = thread.GetCurrentRegisters(new DkmUnwoundRegister[0]); ulong address = 0; var x86Regs = frameRegs as DkmX86FrameRegisters; if (x86Regs != null) { byte[] ebpData = new byte[4]; if (x86Regs.GetRegisterValue(22, ebpData) == 4) { address = DebugHelpers.ReadPointerVariable(thread.Process, BitConverter.ToUInt32(ebpData, 0) + 4).GetValueOrDefault(0); } } if (address == 0) { thread.GetCurrentFrameInfo(out address, out _, out _); } return(address); }