1 //===-- ThreadPlanStepOverBreakpoint.cpp ------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/Target/ThreadPlanStepOverBreakpoint.h"
11
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/lldb-private-log.h"
17 #include "lldb/Core/Log.h"
18 #include "lldb/Core/Stream.h"
19 #include "lldb/Target/Process.h"
20 #include "lldb/Target/RegisterContext.h"
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 //----------------------------------------------------------------------
26 // ThreadPlanStepOverBreakpoint: Single steps over a breakpoint bp_site_sp at the pc.
27 //----------------------------------------------------------------------
28
ThreadPlanStepOverBreakpoint(Thread & thread)29 ThreadPlanStepOverBreakpoint::ThreadPlanStepOverBreakpoint (Thread &thread) :
30 ThreadPlan (ThreadPlan::eKindStepOverBreakpoint, "Step over breakpoint trap",
31 thread,
32 eVoteNo,
33 eVoteNoOpinion), // We need to report the run since this happens
34 // first in the thread plan stack when stepping
35 // over a breakpoint
36 m_breakpoint_addr (LLDB_INVALID_ADDRESS),
37 m_auto_continue(false),
38 m_reenabled_breakpoint_site (false)
39
40 {
41 m_breakpoint_addr = m_thread.GetRegisterContext()->GetPC();
42 m_breakpoint_site_id = m_thread.GetProcess()->GetBreakpointSiteList().FindIDByAddress (m_breakpoint_addr);
43 }
44
~ThreadPlanStepOverBreakpoint()45 ThreadPlanStepOverBreakpoint::~ThreadPlanStepOverBreakpoint ()
46 {
47 }
48
49 void
GetDescription(Stream * s,lldb::DescriptionLevel level)50 ThreadPlanStepOverBreakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level)
51 {
52 s->Printf("Single stepping past breakpoint site %" PRIu64 " at 0x%" PRIx64, m_breakpoint_site_id, (uint64_t)m_breakpoint_addr);
53 }
54
55 bool
ValidatePlan(Stream * error)56 ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error)
57 {
58 return true;
59 }
60
61 bool
DoPlanExplainsStop(Event * event_ptr)62 ThreadPlanStepOverBreakpoint::DoPlanExplainsStop (Event *event_ptr)
63 {
64 StopInfoSP stop_info_sp = GetPrivateStopInfo ();
65 if (stop_info_sp)
66 {
67 StopReason reason = stop_info_sp->GetStopReason();
68 if (reason == eStopReasonTrace || reason == eStopReasonNone)
69 return true;
70 else
71 return false;
72 }
73 return false;
74 }
75
76 bool
ShouldStop(Event * event_ptr)77 ThreadPlanStepOverBreakpoint::ShouldStop (Event *event_ptr)
78 {
79 return false;
80 }
81
82 bool
StopOthers()83 ThreadPlanStepOverBreakpoint::StopOthers ()
84 {
85 return true;
86 }
87
88 StateType
GetPlanRunState()89 ThreadPlanStepOverBreakpoint::GetPlanRunState ()
90 {
91 return eStateStepping;
92 }
93
94 bool
DoWillResume(StateType resume_state,bool current_plan)95 ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current_plan)
96 {
97 if (current_plan)
98 {
99 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
100 if (bp_site_sp && bp_site_sp->IsEnabled())
101 m_thread.GetProcess()->DisableBreakpointSite (bp_site_sp.get());
102 }
103 return true;
104 }
105
106 bool
WillStop()107 ThreadPlanStepOverBreakpoint::WillStop ()
108 {
109 ReenableBreakpointSite ();
110 return true;
111 }
112
113 bool
MischiefManaged()114 ThreadPlanStepOverBreakpoint::MischiefManaged ()
115 {
116 lldb::addr_t pc_addr = m_thread.GetRegisterContext()->GetPC();
117
118 if (pc_addr == m_breakpoint_addr)
119 {
120 // If we are still at the PC of our breakpoint, then for some reason we didn't
121 // get a chance to run.
122 return false;
123 }
124 else
125 {
126 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
127 if (log)
128 log->Printf("Completed step over breakpoint plan.");
129 // Otherwise, re-enable the breakpoint we were stepping over, and we're done.
130 ReenableBreakpointSite ();
131 ThreadPlan::MischiefManaged ();
132 return true;
133 }
134 }
135
136 void
ReenableBreakpointSite()137 ThreadPlanStepOverBreakpoint::ReenableBreakpointSite ()
138 {
139 if (!m_reenabled_breakpoint_site)
140 {
141 m_reenabled_breakpoint_site = true;
142 BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr));
143 if (bp_site_sp)
144 {
145 m_thread.GetProcess()->EnableBreakpointSite (bp_site_sp.get());
146 }
147 }
148 }
149 void
ThreadDestroyed()150 ThreadPlanStepOverBreakpoint::ThreadDestroyed ()
151 {
152 ReenableBreakpointSite ();
153 }
154
155 void
SetAutoContinue(bool do_it)156 ThreadPlanStepOverBreakpoint::SetAutoContinue (bool do_it)
157 {
158 m_auto_continue = do_it;
159 }
160
161 bool
ShouldAutoContinue(Event * event_ptr)162 ThreadPlanStepOverBreakpoint::ShouldAutoContinue (Event *event_ptr)
163 {
164 return m_auto_continue;
165 }
166