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(); } }
public void Enable() { DkmNativeModuleInstance module = entryAddress.ModuleInstance; FunctionTraceDataItem traceDataItem = new FunctionTraceDataItem { Tracer = this }; entryBp = DkmRuntimeInstructionBreakpoint.Create( Guids.Source.FunctionTraceEnter, null, entryAddress, false, null); entryBp.SetDataItem(DkmDataCreationDisposition.CreateAlways, traceDataItem); entryBp.Enable(); }