1 //===-- ThreadPlanBase.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/ThreadPlanBase.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 //
17 #include "lldb/Breakpoint/StoppointCallbackContext.h"
18 #include "lldb/Breakpoint/BreakpointSite.h"
19 #include "lldb/Breakpoint/BreakpointLocation.h"
20 #include "lldb/Breakpoint/Breakpoint.h"
21 #include "lldb/Core/Stream.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 //----------------------------------------------------------------------
29 // ThreadPlanBase: This one always stops, and never has anything particular
30 // to do.
31 // FIXME: The "signal handling" policies should probably go here.
32 //----------------------------------------------------------------------
33 
34 ThreadPlanBase::ThreadPlanBase (Thread &thread) :
35     ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes, eVoteNoOpinion)
36 {
37 
38 }
39 
40 ThreadPlanBase::~ThreadPlanBase ()
41 {
42 
43 }
44 
45 void
46 ThreadPlanBase::GetDescription (Stream *s, lldb::DescriptionLevel level)
47 {
48     s->Printf ("Base thread plan.");
49 }
50 
51 bool
52 ThreadPlanBase::ValidatePlan (Stream *error)
53 {
54     return true;
55 }
56 
57 bool
58 ThreadPlanBase::PlanExplainsStop ()
59 {
60     return true;
61 }
62 
63 bool
64 ThreadPlanBase::ShouldStop (Event *event_ptr)
65 {
66     m_stop_vote = eVoteYes;
67     m_run_vote = eVoteYes;
68 
69     Thread::StopInfo stop_info;
70     if (m_thread.GetStopInfo(&stop_info))
71     {
72         StopReason reason = stop_info.GetStopReason();
73         switch (reason)
74         {
75             case eStopReasonInvalid:
76             case eStopReasonNone:
77             {
78                 m_run_vote = eVoteNo;
79                 m_stop_vote = eVoteNo;
80                 return false;
81             }
82             case eStopReasonBreakpoint:
83             {
84                 // The base plan checks for breakpoint hits.
85 
86                 BreakpointSiteSP bp_site_sp;
87                 //RegisterContext *reg_ctx = m_thread.GetRegisterContext();
88                 //lldb::addr_t pc = reg_ctx->GetPC();
89                 bp_site_sp = m_thread.GetProcess().GetBreakpointSiteList().FindByID (stop_info.GetBreakpointSiteID());
90 
91                 if (bp_site_sp && bp_site_sp->IsEnabled())
92                 {
93                     // We want to step over the breakpoint and then continue.  So push these two plans.
94 
95                     StoppointCallbackContext hit_context(event_ptr, &m_thread.GetProcess(), &m_thread,
96                                                          m_thread.GetStackFrameAtIndex(0).get());
97                     bool should_stop = m_thread.GetProcess().GetBreakpointSiteList().ShouldStop(&hit_context,
98                                                                                                 bp_site_sp->GetID());
99 
100                     if (!should_stop)
101                     {
102                         // If we aren't going to stop at this breakpoint, and it is internal,
103                         // don't report this stop or the subsequent running event.
104                         // Otherwise we will post the stopped & running, but the stopped event will get marked
105                         // with "restarted" so the UI will know to wait and expect the consequent "running".
106                         uint32_t i;
107                         bool is_wholly_internal = true;
108 
109                         for (i = 0; i < bp_site_sp->GetNumberOfOwners(); i++)
110                         {
111                             if (!bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint().IsInternal())
112                             {
113                                 is_wholly_internal = false;
114                                 break;
115                             }
116                         }
117                         if (is_wholly_internal)
118                         {
119                             m_stop_vote = eVoteNo;
120                             m_run_vote = eVoteNo;
121                         }
122                         else
123                         {
124                             m_stop_vote = eVoteYes;
125                             m_run_vote = eVoteYes;
126                         }
127 
128                     }
129                     else
130                     {
131                         // If we are going to stop for a breakpoint, then unship the other plans
132                         // at this point.  Don't force the discard, however, so Master plans can stay
133                         // in place if they want to.
134                         m_thread.DiscardThreadPlans(false);
135                     }
136 
137                     return should_stop;
138                 }
139             }
140             case eStopReasonException:
141                 // If we crashed, discard thread plans and stop.  Don't force the discard, however,
142                 // since on rerun the target may clean up this exception and continue normally from there.
143                 m_thread.DiscardThreadPlans(false);
144                 return true;
145             case eStopReasonSignal:
146             {
147                 // Check the signal handling, and if we are stopping for the signal,
148                 // discard the plans and stop.
149                 UnixSignals &signals = m_thread.GetProcess().GetUnixSignals();
150                 uint32_t signo = stop_info.GetSignal();
151                 if (signals.GetShouldStop(signo))
152                 {
153                     m_thread.DiscardThreadPlans(false);
154                     return true;
155                 }
156                 else
157                 {
158                     // We're not going to stop, but while we are here, let's figure out
159                     // whether to report this.
160                     if (signals.GetShouldNotify(signo))
161                         m_stop_vote = eVoteYes;
162                     else
163                         m_stop_vote = eVoteNo;
164 
165                     return false;
166                 }
167             }
168             default:
169                 return true;
170         }
171 
172     }
173 
174     // If there's no explicit reason to stop, then we will continue.
175     return false;
176 }
177 
178 bool
179 ThreadPlanBase::StopOthers ()
180 {
181     return false;
182 }
183 
184 StateType
185 ThreadPlanBase::RunState ()
186 {
187     return eStateRunning;
188 }
189 
190 bool
191 ThreadPlanBase::WillStop ()
192 {
193     return true;
194 }
195 
196 // The base plan is never done.
197 bool
198 ThreadPlanBase::MischiefManaged ()
199 {
200     // The base plan is never done.
201     return false;
202 }
203 
204