void remove_lmf_breakpoint() { if (lmf_breakpoint == null) return; /* * We reused an already existing single-stepping breakpoint at the requested location. */ if (lmf_breakpoint.Breakpoint == lmf_breakpoint.StolenBreakpoint) return; inferior.RemoveBreakpoint (lmf_breakpoint.Breakpoint.ID); /* * We stole the single-stepping breakpoint -> restore it here. */ if (lmf_breakpoint.StolenBreakpoint != null) { int dr_index; TargetAddress address = lmf_breakpoint.StolenBreakpoint.Address; int id = inferior.InsertHardwareBreakpoint (address, true, out dr_index); temp_breakpoint = new TemporaryBreakpointData (id, address); Report.Debug (DebugFlags.SSE, "{0} restored stolen breakpoint: {1}", this, temp_breakpoint); } lmf_breakpoint = null; }
void insert_lmf_breakpoint(TargetAddress lmf_address) { lmf_breakpoint = new LMFBreakpointData (lmf_address); /* * Insert a breakpoint on the last managed frame (LMF). We use a hardware breakpoint for this * since the JIT might inspect / modify the callsite and we don't know whether we're at a safe * spot right now. * * If we already have a single-stepping breakpoint, we "steal" it here, so we only use one single * hardware register internally in the SSE. * */ if (temp_breakpoint != null) { Report.Debug (DebugFlags.SSE, "{0} stealing temporary breakpoint {1} at {2} -> lmf breakpoint at {2}.", temp_breakpoint.ID, temp_breakpoint.Address, lmf_address); lmf_breakpoint.StolenBreakpoint = temp_breakpoint; temp_breakpoint = null; /* * The breakpoint is already at the requested location -> keep and reuse it. */ if (lmf_address == temp_breakpoint.Address) { lmf_breakpoint.Breakpoint = lmf_breakpoint.StolenBreakpoint; return; } inferior.RemoveBreakpoint (lmf_breakpoint.StolenBreakpoint.ID); } /* * The SSE's internal hardware breakpoint register is now free. */ int dr_index; int id = inferior.InsertHardwareBreakpoint (lmf_address, true, out dr_index); Report.Debug (DebugFlags.SSE, "{0} inserted lmf breakpoint: {1} {2} {3}", this, lmf_address, id, dr_index); lmf_breakpoint.Breakpoint = new TemporaryBreakpointData (id, lmf_address); }