1 //===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Target/ThreadPlanBase.h"
10 
11 //
12 #include "lldb/Breakpoint/Breakpoint.h"
13 #include "lldb/Breakpoint/BreakpointLocation.h"
14 #include "lldb/Breakpoint/BreakpointSite.h"
15 #include "lldb/Breakpoint/StoppointCallbackContext.h"
16 #include "lldb/Target/Process.h"
17 #include "lldb/Target/RegisterContext.h"
18 #include "lldb/Target/StopInfo.h"
19 #include "lldb/Utility/Log.h"
20 #include "lldb/Utility/Stream.h"
21 
22 using namespace lldb;
23 using namespace lldb_private;
24 
25 //----------------------------------------------------------------------
26 // ThreadPlanBase: This one always stops, and never has anything particular to
27 // do.
28 // FIXME: The "signal handling" policies should probably go here.
29 //----------------------------------------------------------------------
30 
31 ThreadPlanBase::ThreadPlanBase(Thread &thread)
32     : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
33                  eVoteNoOpinion) {
34 // Set the tracer to a default tracer.
35 // FIXME: need to add a thread settings variable to pix various tracers...
36 #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
37 
38 #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
39   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread));
40 #else
41   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
42 #endif
43   new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState());
44   SetThreadPlanTracer(new_tracer_sp);
45   SetIsMasterPlan(true);
46 }
47 
48 ThreadPlanBase::~ThreadPlanBase() {}
49 
50 void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
51   s->Printf("Base thread plan.");
52 }
53 
54 bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
55 
56 bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
57   // The base plan should defer to its tracer, since by default it always
58   // handles the stop.
59   return !TracerExplainsStop();
60 }
61 
62 Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
63   StopInfoSP stop_info_sp = m_thread.GetStopInfo();
64   if (stop_info_sp) {
65     bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
66     if (should_notify)
67       return eVoteYes;
68     else
69       return eVoteNoOpinion;
70   } else
71     return eVoteNoOpinion;
72 }
73 
74 bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
75   m_stop_vote = eVoteYes;
76   m_run_vote = eVoteYes;
77 
78   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
79 
80   StopInfoSP stop_info_sp = GetPrivateStopInfo();
81   if (stop_info_sp) {
82     StopReason reason = stop_info_sp->GetStopReason();
83     switch (reason) {
84     case eStopReasonInvalid:
85     case eStopReasonNone:
86       // This
87       m_run_vote = eVoteNoOpinion;
88       m_stop_vote = eVoteNo;
89       return false;
90 
91     case eStopReasonBreakpoint:
92     case eStopReasonWatchpoint:
93       if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
94         // If we are going to stop for a breakpoint, then unship the other
95         // plans at this point.  Don't force the discard, however, so Master
96         // plans can stay in place if they want to.
97         if (log)
98           log->Printf(
99               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
100               " (breakpoint hit.)",
101               m_thread.GetID());
102         m_thread.DiscardThreadPlans(false);
103         return true;
104       }
105       // If we aren't going to stop at this breakpoint, and it is internal,
106       // don't report this stop or the subsequent running event. Otherwise we
107       // will post the stopped & running, but the stopped event will get marked
108       // with "restarted" so the UI will know to wait and expect the consequent
109       // "running".
110       if (stop_info_sp->ShouldNotify(event_ptr)) {
111         m_stop_vote = eVoteYes;
112         m_run_vote = eVoteYes;
113       } else {
114         m_stop_vote = eVoteNo;
115         m_run_vote = eVoteNo;
116       }
117       return false;
118 
119       // TODO: the break below was missing, was this intentional??? If so
120       // please mention it
121       break;
122 
123     case eStopReasonException:
124       // If we crashed, discard thread plans and stop.  Don't force the
125       // discard, however, since on rerun the target may clean up this
126       // exception and continue normally from there.
127       if (log)
128         log->Printf(
129             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
130             " (exception: %s)",
131             m_thread.GetID(), stop_info_sp->GetDescription());
132       m_thread.DiscardThreadPlans(false);
133       return true;
134 
135     case eStopReasonExec:
136       // If we crashed, discard thread plans and stop.  Don't force the
137       // discard, however, since on rerun the target may clean up this
138       // exception and continue normally from there.
139       if (log)
140         log->Printf(
141             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
142             " (exec.)",
143             m_thread.GetID());
144       m_thread.DiscardThreadPlans(false);
145       return true;
146 
147     case eStopReasonThreadExiting:
148     case eStopReasonSignal:
149       if (stop_info_sp->ShouldStop(event_ptr)) {
150         if (log)
151           log->Printf(
152               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
153               " (signal: %s)",
154               m_thread.GetID(), stop_info_sp->GetDescription());
155         m_thread.DiscardThreadPlans(false);
156         return true;
157       } else {
158         // We're not going to stop, but while we are here, let's figure out
159         // whether to report this.
160         if (stop_info_sp->ShouldNotify(event_ptr))
161           m_stop_vote = eVoteYes;
162         else
163           m_stop_vote = eVoteNo;
164       }
165       return false;
166 
167     default:
168       return true;
169     }
170 
171   } else {
172     m_run_vote = eVoteNoOpinion;
173     m_stop_vote = eVoteNo;
174   }
175 
176   // If there's no explicit reason to stop, then we will continue.
177   return false;
178 }
179 
180 bool ThreadPlanBase::StopOthers() { return false; }
181 
182 StateType ThreadPlanBase::GetPlanRunState() { return eStateRunning; }
183 
184 bool ThreadPlanBase::WillStop() { return true; }
185 
186 bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
187                                   bool current_plan) {
188   // Reset these to the default values so we don't set them wrong, then not get
189   // asked for a while, then return the wrong answer.
190   m_run_vote = eVoteNoOpinion;
191   m_stop_vote = eVoteNo;
192   return true;
193 }
194 
195 // The base plan is never done.
196 bool ThreadPlanBase::MischiefManaged() {
197   // The base plan is never done.
198   return false;
199 }
200