130fdc8d8SChris Lattner //===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner 
930fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanBase.h"
1030fdc8d8SChris Lattner 
1130fdc8d8SChris Lattner //
1230fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
13b9c1b51eSKate Stone #include "lldb/Breakpoint/BreakpointLocation.h"
14b9c1b51eSKate Stone #include "lldb/Breakpoint/BreakpointSite.h"
15b9c1b51eSKate Stone #include "lldb/Breakpoint/StoppointCallbackContext.h"
1630fdc8d8SChris Lattner #include "lldb/Target/Process.h"
1730fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
18f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
196f9e6901SZachary Turner #include "lldb/Utility/Log.h"
20bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner using namespace lldb;
2330fdc8d8SChris Lattner using namespace lldb_private;
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner //----------------------------------------------------------------------
2605097246SAdrian Prantl // ThreadPlanBase: This one always stops, and never has anything particular to
2705097246SAdrian Prantl // do.
2830fdc8d8SChris Lattner // FIXME: The "signal handling" policies should probably go here.
2930fdc8d8SChris Lattner //----------------------------------------------------------------------
3030fdc8d8SChris Lattner 
31b9c1b51eSKate Stone ThreadPlanBase::ThreadPlanBase(Thread &thread)
32b9c1b51eSKate Stone     : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
33b9c1b51eSKate Stone                  eVoteNoOpinion) {
3406e827ccSJim Ingham // Set the tracer to a default tracer.
35773d981cSJim Ingham // FIXME: need to add a thread settings variable to pix various tracers...
36773d981cSJim Ingham #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
37773d981cSJim Ingham 
38773d981cSJim Ingham #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
39773d981cSJim Ingham   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread));
40773d981cSJim Ingham #else
4106e827ccSJim Ingham   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
42773d981cSJim Ingham #endif
4306e827ccSJim Ingham   new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState());
4406e827ccSJim Ingham   SetThreadPlanTracer(new_tracer_sp);
45cf274f91SJim Ingham   SetIsMasterPlan(true);
4630fdc8d8SChris Lattner }
4730fdc8d8SChris Lattner 
48b9c1b51eSKate Stone ThreadPlanBase::~ThreadPlanBase() {}
4930fdc8d8SChris Lattner 
50b9c1b51eSKate Stone void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
5130fdc8d8SChris Lattner   s->Printf("Base thread plan.");
5230fdc8d8SChris Lattner }
5330fdc8d8SChris Lattner 
54b9c1b51eSKate Stone bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
5530fdc8d8SChris Lattner 
56b9c1b51eSKate Stone bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
5705097246SAdrian Prantl   // The base plan should defer to its tracer, since by default it always
5805097246SAdrian Prantl   // handles the stop.
59a6682a41SJonas Devlieghere   return !TracerExplainsStop();
6030fdc8d8SChris Lattner }
6130fdc8d8SChris Lattner 
62b9c1b51eSKate Stone Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
63221d51cfSJim Ingham   StopInfoSP stop_info_sp = m_thread.GetStopInfo();
64b9c1b51eSKate Stone   if (stop_info_sp) {
65221d51cfSJim Ingham     bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
66221d51cfSJim Ingham     if (should_notify)
67221d51cfSJim Ingham       return eVoteYes;
68221d51cfSJim Ingham     else
69221d51cfSJim Ingham       return eVoteNoOpinion;
70b9c1b51eSKate Stone   } else
71221d51cfSJim Ingham     return eVoteNoOpinion;
72221d51cfSJim Ingham }
73221d51cfSJim Ingham 
74b9c1b51eSKate Stone bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
7530fdc8d8SChris Lattner   m_stop_vote = eVoteYes;
7630fdc8d8SChris Lattner   m_run_vote = eVoteYes;
7730fdc8d8SChris Lattner 
785160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
790f16e73aSJim Ingham 
8060c4118cSJim Ingham   StopInfoSP stop_info_sp = GetPrivateStopInfo();
81b9c1b51eSKate Stone   if (stop_info_sp) {
82b15bfc75SJim Ingham     StopReason reason = stop_info_sp->GetStopReason();
83b9c1b51eSKate Stone     switch (reason) {
8430fdc8d8SChris Lattner     case eStopReasonInvalid:
8530fdc8d8SChris Lattner     case eStopReasonNone:
86444586b5SJim Ingham       // This
87444586b5SJim Ingham       m_run_vote = eVoteNoOpinion;
8830fdc8d8SChris Lattner       m_stop_vote = eVoteNo;
8930fdc8d8SChris Lattner       return false;
90f4b47e15SGreg Clayton 
9130fdc8d8SChris Lattner     case eStopReasonBreakpoint:
92fd158f41SJohnny Chen     case eStopReasonWatchpoint:
93b9c1b51eSKate Stone       if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
9405097246SAdrian Prantl         // If we are going to stop for a breakpoint, then unship the other
9505097246SAdrian Prantl         // plans at this point.  Don't force the discard, however, so Master
9605097246SAdrian Prantl         // plans can stay in place if they want to.
970f16e73aSJim Ingham         if (log)
98b9c1b51eSKate Stone           log->Printf(
99b9c1b51eSKate Stone               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
100b9c1b51eSKate Stone               " (breakpoint hit.)",
101b9c1b51eSKate Stone               m_thread.GetID());
10230fdc8d8SChris Lattner         m_thread.DiscardThreadPlans(false);
103f4b47e15SGreg Clayton         return true;
10430fdc8d8SChris Lattner       }
105f4b47e15SGreg Clayton       // If we aren't going to stop at this breakpoint, and it is internal,
10605097246SAdrian Prantl       // don't report this stop or the subsequent running event. Otherwise we
10705097246SAdrian Prantl       // will post the stopped & running, but the stopped event will get marked
108b9c1b51eSKate Stone       // with "restarted" so the UI will know to wait and expect the consequent
109b9c1b51eSKate Stone       // "running".
110b9c1b51eSKate Stone       if (stop_info_sp->ShouldNotify(event_ptr)) {
111f4b47e15SGreg Clayton         m_stop_vote = eVoteYes;
112f4b47e15SGreg Clayton         m_run_vote = eVoteYes;
113b9c1b51eSKate Stone       } else {
114f4b47e15SGreg Clayton         m_stop_vote = eVoteNo;
115f4b47e15SGreg Clayton         m_run_vote = eVoteNo;
116f4b47e15SGreg Clayton       }
117f4b47e15SGreg Clayton       return false;
11830fdc8d8SChris Lattner 
119f4b47e15SGreg Clayton       // TODO: the break below was missing, was this intentional??? If so
120f4b47e15SGreg Clayton       // please mention it
121f4b47e15SGreg Clayton       break;
122f4b47e15SGreg Clayton 
12330fdc8d8SChris Lattner     case eStopReasonException:
12405097246SAdrian Prantl       // If we crashed, discard thread plans and stop.  Don't force the
12505097246SAdrian Prantl       // discard, however, since on rerun the target may clean up this
12605097246SAdrian Prantl       // exception and continue normally from there.
1270f16e73aSJim Ingham       if (log)
128b9c1b51eSKate Stone         log->Printf(
129b9c1b51eSKate Stone             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
130b9c1b51eSKate Stone             " (exception: %s)",
131b9c1b51eSKate Stone             m_thread.GetID(), stop_info_sp->GetDescription());
13230fdc8d8SChris Lattner       m_thread.DiscardThreadPlans(false);
13330fdc8d8SChris Lattner       return true;
134f4b47e15SGreg Clayton 
13590ba8115SGreg Clayton     case eStopReasonExec:
13605097246SAdrian Prantl       // If we crashed, discard thread plans and stop.  Don't force the
13705097246SAdrian Prantl       // discard, however, since on rerun the target may clean up this
13805097246SAdrian Prantl       // exception and continue normally from there.
13990ba8115SGreg Clayton       if (log)
140b9c1b51eSKate Stone         log->Printf(
141b9c1b51eSKate Stone             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
142b9c1b51eSKate Stone             " (exec.)",
143b9c1b51eSKate Stone             m_thread.GetID());
14490ba8115SGreg Clayton       m_thread.DiscardThreadPlans(false);
14590ba8115SGreg Clayton       return true;
14690ba8115SGreg Clayton 
147f85defaeSAndrew Kaylor     case eStopReasonThreadExiting:
14830fdc8d8SChris Lattner     case eStopReasonSignal:
149b9c1b51eSKate Stone       if (stop_info_sp->ShouldStop(event_ptr)) {
1500f16e73aSJim Ingham         if (log)
151b9c1b51eSKate Stone           log->Printf(
152b9c1b51eSKate Stone               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
153b9c1b51eSKate Stone               " (signal: %s)",
154b9c1b51eSKate Stone               m_thread.GetID(), stop_info_sp->GetDescription());
15530fdc8d8SChris Lattner         m_thread.DiscardThreadPlans(false);
15630fdc8d8SChris Lattner         return true;
157b9c1b51eSKate Stone       } else {
15830fdc8d8SChris Lattner         // We're not going to stop, but while we are here, let's figure out
15930fdc8d8SChris Lattner         // whether to report this.
160b15bfc75SJim Ingham         if (stop_info_sp->ShouldNotify(event_ptr))
16130fdc8d8SChris Lattner           m_stop_vote = eVoteYes;
16230fdc8d8SChris Lattner         else
16330fdc8d8SChris Lattner           m_stop_vote = eVoteNo;
164f4b47e15SGreg Clayton       }
16530fdc8d8SChris Lattner       return false;
166f4b47e15SGreg Clayton 
16730fdc8d8SChris Lattner     default:
16830fdc8d8SChris Lattner       return true;
16930fdc8d8SChris Lattner     }
17030fdc8d8SChris Lattner 
171b9c1b51eSKate Stone   } else {
172444586b5SJim Ingham     m_run_vote = eVoteNoOpinion;
173f4b47e15SGreg Clayton     m_stop_vote = eVoteNo;
174f4b47e15SGreg Clayton   }
17530fdc8d8SChris Lattner 
17630fdc8d8SChris Lattner   // If there's no explicit reason to stop, then we will continue.
17730fdc8d8SChris Lattner   return false;
17830fdc8d8SChris Lattner }
17930fdc8d8SChris Lattner 
180b9c1b51eSKate Stone bool ThreadPlanBase::StopOthers() { return false; }
18130fdc8d8SChris Lattner 
182b9c1b51eSKate Stone StateType ThreadPlanBase::GetPlanRunState() { return eStateRunning; }
18330fdc8d8SChris Lattner 
184b9c1b51eSKate Stone bool ThreadPlanBase::WillStop() { return true; }
18530fdc8d8SChris Lattner 
186b9c1b51eSKate Stone bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
187b9c1b51eSKate Stone                                   bool current_plan) {
188b9c1b51eSKate Stone   // Reset these to the default values so we don't set them wrong, then not get
18905097246SAdrian Prantl   // asked for a while, then return the wrong answer.
190444586b5SJim Ingham   m_run_vote = eVoteNoOpinion;
191444586b5SJim Ingham   m_stop_vote = eVoteNo;
192444586b5SJim Ingham   return true;
193444586b5SJim Ingham }
194444586b5SJim Ingham 
19530fdc8d8SChris Lattner // The base plan is never done.
196b9c1b51eSKate Stone bool ThreadPlanBase::MischiefManaged() {
19730fdc8d8SChris Lattner   // The base plan is never done.
19830fdc8d8SChris Lattner   return false;
19930fdc8d8SChris Lattner }
200