130fdc8d8SChris Lattner //===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/Target/ThreadPlanBase.h"
1130fdc8d8SChris Lattner 
1230fdc8d8SChris Lattner // C Includes
1330fdc8d8SChris Lattner // C++ Includes
1430fdc8d8SChris Lattner // Other libraries and framework includes
1530fdc8d8SChris Lattner // Project includes
1630fdc8d8SChris Lattner //
1730fdc8d8SChris Lattner #include "lldb/Breakpoint/Breakpoint.h"
18b9c1b51eSKate Stone #include "lldb/Breakpoint/BreakpointLocation.h"
19b9c1b51eSKate Stone #include "lldb/Breakpoint/BreakpointSite.h"
20b9c1b51eSKate Stone #include "lldb/Breakpoint/StoppointCallbackContext.h"
2130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
2230fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
23f4b47e15SGreg Clayton #include "lldb/Target/StopInfo.h"
246f9e6901SZachary Turner #include "lldb/Utility/Log.h"
25bf9a7730SZachary Turner #include "lldb/Utility/Stream.h"
2630fdc8d8SChris Lattner 
2730fdc8d8SChris Lattner using namespace lldb;
2830fdc8d8SChris Lattner using namespace lldb_private;
2930fdc8d8SChris Lattner 
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
31*05097246SAdrian Prantl // ThreadPlanBase: This one always stops, and never has anything particular to
32*05097246SAdrian Prantl // do.
3330fdc8d8SChris Lattner // FIXME: The "signal handling" policies should probably go here.
3430fdc8d8SChris Lattner //----------------------------------------------------------------------
3530fdc8d8SChris Lattner 
36b9c1b51eSKate Stone ThreadPlanBase::ThreadPlanBase(Thread &thread)
37b9c1b51eSKate Stone     : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
38b9c1b51eSKate Stone                  eVoteNoOpinion) {
3906e827ccSJim Ingham // Set the tracer to a default tracer.
40773d981cSJim Ingham // FIXME: need to add a thread settings variable to pix various tracers...
41773d981cSJim Ingham #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
42773d981cSJim Ingham 
43773d981cSJim Ingham #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
44773d981cSJim Ingham   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread));
45773d981cSJim Ingham #else
4606e827ccSJim Ingham   ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
47773d981cSJim Ingham #endif
4806e827ccSJim Ingham   new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState());
4906e827ccSJim Ingham   SetThreadPlanTracer(new_tracer_sp);
50cf274f91SJim Ingham   SetIsMasterPlan(true);
5130fdc8d8SChris Lattner }
5230fdc8d8SChris Lattner 
53b9c1b51eSKate Stone ThreadPlanBase::~ThreadPlanBase() {}
5430fdc8d8SChris Lattner 
55b9c1b51eSKate Stone void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
5630fdc8d8SChris Lattner   s->Printf("Base thread plan.");
5730fdc8d8SChris Lattner }
5830fdc8d8SChris Lattner 
59b9c1b51eSKate Stone bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
6030fdc8d8SChris Lattner 
61b9c1b51eSKate Stone bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
62*05097246SAdrian Prantl   // The base plan should defer to its tracer, since by default it always
63*05097246SAdrian Prantl   // handles the stop.
6406e827ccSJim Ingham   if (TracerExplainsStop())
6506e827ccSJim Ingham     return false;
6606e827ccSJim Ingham   else
6730fdc8d8SChris Lattner     return true;
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner 
70b9c1b51eSKate Stone Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
71221d51cfSJim Ingham   StopInfoSP stop_info_sp = m_thread.GetStopInfo();
72b9c1b51eSKate Stone   if (stop_info_sp) {
73221d51cfSJim Ingham     bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
74221d51cfSJim Ingham     if (should_notify)
75221d51cfSJim Ingham       return eVoteYes;
76221d51cfSJim Ingham     else
77221d51cfSJim Ingham       return eVoteNoOpinion;
78b9c1b51eSKate Stone   } else
79221d51cfSJim Ingham     return eVoteNoOpinion;
80221d51cfSJim Ingham }
81221d51cfSJim Ingham 
82b9c1b51eSKate Stone bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
8330fdc8d8SChris Lattner   m_stop_vote = eVoteYes;
8430fdc8d8SChris Lattner   m_run_vote = eVoteYes;
8530fdc8d8SChris Lattner 
865160ce5cSGreg Clayton   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
870f16e73aSJim Ingham 
8860c4118cSJim Ingham   StopInfoSP stop_info_sp = GetPrivateStopInfo();
89b9c1b51eSKate Stone   if (stop_info_sp) {
90b15bfc75SJim Ingham     StopReason reason = stop_info_sp->GetStopReason();
91b9c1b51eSKate Stone     switch (reason) {
9230fdc8d8SChris Lattner     case eStopReasonInvalid:
9330fdc8d8SChris Lattner     case eStopReasonNone:
94444586b5SJim Ingham       // This
95444586b5SJim Ingham       m_run_vote = eVoteNoOpinion;
9630fdc8d8SChris Lattner       m_stop_vote = eVoteNo;
9730fdc8d8SChris Lattner       return false;
98f4b47e15SGreg Clayton 
9930fdc8d8SChris Lattner     case eStopReasonBreakpoint:
100fd158f41SJohnny Chen     case eStopReasonWatchpoint:
101b9c1b51eSKate Stone       if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
102*05097246SAdrian Prantl         // If we are going to stop for a breakpoint, then unship the other
103*05097246SAdrian Prantl         // plans at this point.  Don't force the discard, however, so Master
104*05097246SAdrian Prantl         // plans can stay in place if they want to.
1050f16e73aSJim Ingham         if (log)
106b9c1b51eSKate Stone           log->Printf(
107b9c1b51eSKate Stone               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
108b9c1b51eSKate Stone               " (breakpoint hit.)",
109b9c1b51eSKate Stone               m_thread.GetID());
11030fdc8d8SChris Lattner         m_thread.DiscardThreadPlans(false);
111f4b47e15SGreg Clayton         return true;
11230fdc8d8SChris Lattner       }
113f4b47e15SGreg Clayton       // If we aren't going to stop at this breakpoint, and it is internal,
114*05097246SAdrian Prantl       // don't report this stop or the subsequent running event. Otherwise we
115*05097246SAdrian Prantl       // will post the stopped & running, but the stopped event will get marked
116b9c1b51eSKate Stone       // with "restarted" so the UI will know to wait and expect the consequent
117b9c1b51eSKate Stone       // "running".
118b9c1b51eSKate Stone       if (stop_info_sp->ShouldNotify(event_ptr)) {
119f4b47e15SGreg Clayton         m_stop_vote = eVoteYes;
120f4b47e15SGreg Clayton         m_run_vote = eVoteYes;
121b9c1b51eSKate Stone       } else {
122f4b47e15SGreg Clayton         m_stop_vote = eVoteNo;
123f4b47e15SGreg Clayton         m_run_vote = eVoteNo;
124f4b47e15SGreg Clayton       }
125f4b47e15SGreg Clayton       return false;
12630fdc8d8SChris Lattner 
127f4b47e15SGreg Clayton       // TODO: the break below was missing, was this intentional??? If so
128f4b47e15SGreg Clayton       // please mention it
129f4b47e15SGreg Clayton       break;
130f4b47e15SGreg Clayton 
13130fdc8d8SChris Lattner     case eStopReasonException:
132*05097246SAdrian Prantl       // If we crashed, discard thread plans and stop.  Don't force the
133*05097246SAdrian Prantl       // discard, however, since on rerun the target may clean up this
134*05097246SAdrian Prantl       // exception and continue normally from there.
1350f16e73aSJim Ingham       if (log)
136b9c1b51eSKate Stone         log->Printf(
137b9c1b51eSKate Stone             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
138b9c1b51eSKate Stone             " (exception: %s)",
139b9c1b51eSKate Stone             m_thread.GetID(), stop_info_sp->GetDescription());
14030fdc8d8SChris Lattner       m_thread.DiscardThreadPlans(false);
14130fdc8d8SChris Lattner       return true;
142f4b47e15SGreg Clayton 
14390ba8115SGreg Clayton     case eStopReasonExec:
144*05097246SAdrian Prantl       // If we crashed, discard thread plans and stop.  Don't force the
145*05097246SAdrian Prantl       // discard, however, since on rerun the target may clean up this
146*05097246SAdrian Prantl       // exception and continue normally from there.
14790ba8115SGreg Clayton       if (log)
148b9c1b51eSKate Stone         log->Printf(
149b9c1b51eSKate Stone             "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
150b9c1b51eSKate Stone             " (exec.)",
151b9c1b51eSKate Stone             m_thread.GetID());
15290ba8115SGreg Clayton       m_thread.DiscardThreadPlans(false);
15390ba8115SGreg Clayton       return true;
15490ba8115SGreg Clayton 
155f85defaeSAndrew Kaylor     case eStopReasonThreadExiting:
15630fdc8d8SChris Lattner     case eStopReasonSignal:
157b9c1b51eSKate Stone       if (stop_info_sp->ShouldStop(event_ptr)) {
1580f16e73aSJim Ingham         if (log)
159b9c1b51eSKate Stone           log->Printf(
160b9c1b51eSKate Stone               "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
161b9c1b51eSKate Stone               " (signal: %s)",
162b9c1b51eSKate Stone               m_thread.GetID(), stop_info_sp->GetDescription());
16330fdc8d8SChris Lattner         m_thread.DiscardThreadPlans(false);
16430fdc8d8SChris Lattner         return true;
165b9c1b51eSKate Stone       } else {
16630fdc8d8SChris Lattner         // We're not going to stop, but while we are here, let's figure out
16730fdc8d8SChris Lattner         // whether to report this.
168b15bfc75SJim Ingham         if (stop_info_sp->ShouldNotify(event_ptr))
16930fdc8d8SChris Lattner           m_stop_vote = eVoteYes;
17030fdc8d8SChris Lattner         else
17130fdc8d8SChris Lattner           m_stop_vote = eVoteNo;
172f4b47e15SGreg Clayton       }
17330fdc8d8SChris Lattner       return false;
174f4b47e15SGreg Clayton 
17530fdc8d8SChris Lattner     default:
17630fdc8d8SChris Lattner       return true;
17730fdc8d8SChris Lattner     }
17830fdc8d8SChris Lattner 
179b9c1b51eSKate Stone   } else {
180444586b5SJim Ingham     m_run_vote = eVoteNoOpinion;
181f4b47e15SGreg Clayton     m_stop_vote = eVoteNo;
182f4b47e15SGreg Clayton   }
18330fdc8d8SChris Lattner 
18430fdc8d8SChris Lattner   // If there's no explicit reason to stop, then we will continue.
18530fdc8d8SChris Lattner   return false;
18630fdc8d8SChris Lattner }
18730fdc8d8SChris Lattner 
188b9c1b51eSKate Stone bool ThreadPlanBase::StopOthers() { return false; }
18930fdc8d8SChris Lattner 
190b9c1b51eSKate Stone StateType ThreadPlanBase::GetPlanRunState() { return eStateRunning; }
19130fdc8d8SChris Lattner 
192b9c1b51eSKate Stone bool ThreadPlanBase::WillStop() { return true; }
19330fdc8d8SChris Lattner 
194b9c1b51eSKate Stone bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
195b9c1b51eSKate Stone                                   bool current_plan) {
196b9c1b51eSKate Stone   // Reset these to the default values so we don't set them wrong, then not get
197*05097246SAdrian Prantl   // asked for a while, then return the wrong answer.
198444586b5SJim Ingham   m_run_vote = eVoteNoOpinion;
199444586b5SJim Ingham   m_stop_vote = eVoteNo;
200444586b5SJim Ingham   return true;
201444586b5SJim Ingham }
202444586b5SJim Ingham 
20330fdc8d8SChris Lattner // The base plan is never done.
204b9c1b51eSKate Stone bool ThreadPlanBase::MischiefManaged() {
20530fdc8d8SChris Lattner   // The base plan is never done.
20630fdc8d8SChris Lattner   return false;
20730fdc8d8SChris Lattner }
208