1ac7ddfbfSEd Maste //===-- ThreadPlanBase.cpp --------------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
10ac7ddfbfSEd Maste #include "lldb/Target/ThreadPlanBase.h"
11ac7ddfbfSEd Maste
12ac7ddfbfSEd Maste //
13ac7ddfbfSEd Maste #include "lldb/Breakpoint/Breakpoint.h"
14435933ddSDimitry Andric #include "lldb/Breakpoint/BreakpointLocation.h"
15435933ddSDimitry Andric #include "lldb/Breakpoint/BreakpointSite.h"
16435933ddSDimitry Andric #include "lldb/Breakpoint/StoppointCallbackContext.h"
17ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
18ac7ddfbfSEd Maste #include "lldb/Target/RegisterContext.h"
19ac7ddfbfSEd Maste #include "lldb/Target/StopInfo.h"
20f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
21f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
22ac7ddfbfSEd Maste
23ac7ddfbfSEd Maste using namespace lldb;
24ac7ddfbfSEd Maste using namespace lldb_private;
25ac7ddfbfSEd Maste
26ac7ddfbfSEd Maste //----------------------------------------------------------------------
274ba319b5SDimitry Andric // ThreadPlanBase: This one always stops, and never has anything particular to
284ba319b5SDimitry Andric // do.
29ac7ddfbfSEd Maste // FIXME: The "signal handling" policies should probably go here.
30ac7ddfbfSEd Maste //----------------------------------------------------------------------
31ac7ddfbfSEd Maste
ThreadPlanBase(Thread & thread)32435933ddSDimitry Andric ThreadPlanBase::ThreadPlanBase(Thread &thread)
33435933ddSDimitry Andric : ThreadPlan(ThreadPlan::eKindBase, "base plan", thread, eVoteYes,
34435933ddSDimitry Andric eVoteNoOpinion) {
35ac7ddfbfSEd Maste // Set the tracer to a default tracer.
36ac7ddfbfSEd Maste // FIXME: need to add a thread settings variable to pix various tracers...
37ac7ddfbfSEd Maste #define THREAD_PLAN_USE_ASSEMBLY_TRACER 1
38ac7ddfbfSEd Maste
39ac7ddfbfSEd Maste #ifdef THREAD_PLAN_USE_ASSEMBLY_TRACER
40ac7ddfbfSEd Maste ThreadPlanTracerSP new_tracer_sp(new ThreadPlanAssemblyTracer(m_thread));
41ac7ddfbfSEd Maste #else
42ac7ddfbfSEd Maste ThreadPlanTracerSP new_tracer_sp(new ThreadPlanTracer(m_thread));
43ac7ddfbfSEd Maste #endif
44ac7ddfbfSEd Maste new_tracer_sp->EnableTracing(m_thread.GetTraceEnabledState());
45ac7ddfbfSEd Maste SetThreadPlanTracer(new_tracer_sp);
46ac7ddfbfSEd Maste SetIsMasterPlan(true);
47ac7ddfbfSEd Maste }
48ac7ddfbfSEd Maste
~ThreadPlanBase()49435933ddSDimitry Andric ThreadPlanBase::~ThreadPlanBase() {}
50ac7ddfbfSEd Maste
GetDescription(Stream * s,lldb::DescriptionLevel level)51435933ddSDimitry Andric void ThreadPlanBase::GetDescription(Stream *s, lldb::DescriptionLevel level) {
52ac7ddfbfSEd Maste s->Printf("Base thread plan.");
53ac7ddfbfSEd Maste }
54ac7ddfbfSEd Maste
ValidatePlan(Stream * error)55435933ddSDimitry Andric bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; }
56ac7ddfbfSEd Maste
DoPlanExplainsStop(Event * event_ptr)57435933ddSDimitry Andric bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) {
584ba319b5SDimitry Andric // The base plan should defer to its tracer, since by default it always
594ba319b5SDimitry Andric // handles the stop.
60*b5893f02SDimitry Andric return !TracerExplainsStop();
61ac7ddfbfSEd Maste }
62ac7ddfbfSEd Maste
ShouldReportStop(Event * event_ptr)63435933ddSDimitry Andric Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) {
64ac7ddfbfSEd Maste StopInfoSP stop_info_sp = m_thread.GetStopInfo();
65435933ddSDimitry Andric if (stop_info_sp) {
66ac7ddfbfSEd Maste bool should_notify = stop_info_sp->ShouldNotify(event_ptr);
67ac7ddfbfSEd Maste if (should_notify)
68ac7ddfbfSEd Maste return eVoteYes;
69ac7ddfbfSEd Maste else
70ac7ddfbfSEd Maste return eVoteNoOpinion;
71435933ddSDimitry Andric } else
72ac7ddfbfSEd Maste return eVoteNoOpinion;
73ac7ddfbfSEd Maste }
74ac7ddfbfSEd Maste
ShouldStop(Event * event_ptr)75435933ddSDimitry Andric bool ThreadPlanBase::ShouldStop(Event *event_ptr) {
76ac7ddfbfSEd Maste m_stop_vote = eVoteYes;
77ac7ddfbfSEd Maste m_run_vote = eVoteYes;
78ac7ddfbfSEd Maste
79ac7ddfbfSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
80ac7ddfbfSEd Maste
81ac7ddfbfSEd Maste StopInfoSP stop_info_sp = GetPrivateStopInfo();
82435933ddSDimitry Andric if (stop_info_sp) {
83ac7ddfbfSEd Maste StopReason reason = stop_info_sp->GetStopReason();
84435933ddSDimitry Andric switch (reason) {
85ac7ddfbfSEd Maste case eStopReasonInvalid:
86ac7ddfbfSEd Maste case eStopReasonNone:
87ac7ddfbfSEd Maste // This
88ac7ddfbfSEd Maste m_run_vote = eVoteNoOpinion;
89ac7ddfbfSEd Maste m_stop_vote = eVoteNo;
90ac7ddfbfSEd Maste return false;
91ac7ddfbfSEd Maste
92ac7ddfbfSEd Maste case eStopReasonBreakpoint:
93ac7ddfbfSEd Maste case eStopReasonWatchpoint:
94435933ddSDimitry Andric if (stop_info_sp->ShouldStopSynchronous(event_ptr)) {
954ba319b5SDimitry Andric // If we are going to stop for a breakpoint, then unship the other
964ba319b5SDimitry Andric // plans at this point. Don't force the discard, however, so Master
974ba319b5SDimitry Andric // plans can stay in place if they want to.
98ac7ddfbfSEd Maste if (log)
99435933ddSDimitry Andric log->Printf(
100435933ddSDimitry Andric "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
101435933ddSDimitry Andric " (breakpoint hit.)",
102435933ddSDimitry Andric m_thread.GetID());
103ac7ddfbfSEd Maste m_thread.DiscardThreadPlans(false);
104ac7ddfbfSEd Maste return true;
105ac7ddfbfSEd Maste }
106ac7ddfbfSEd Maste // If we aren't going to stop at this breakpoint, and it is internal,
1074ba319b5SDimitry Andric // don't report this stop or the subsequent running event. Otherwise we
1084ba319b5SDimitry Andric // will post the stopped & running, but the stopped event will get marked
109435933ddSDimitry Andric // with "restarted" so the UI will know to wait and expect the consequent
110435933ddSDimitry Andric // "running".
111435933ddSDimitry Andric if (stop_info_sp->ShouldNotify(event_ptr)) {
112ac7ddfbfSEd Maste m_stop_vote = eVoteYes;
113ac7ddfbfSEd Maste m_run_vote = eVoteYes;
114435933ddSDimitry Andric } else {
115ac7ddfbfSEd Maste m_stop_vote = eVoteNo;
116ac7ddfbfSEd Maste m_run_vote = eVoteNo;
117ac7ddfbfSEd Maste }
118ac7ddfbfSEd Maste return false;
119ac7ddfbfSEd Maste
120ac7ddfbfSEd Maste // TODO: the break below was missing, was this intentional??? If so
121ac7ddfbfSEd Maste // please mention it
122ac7ddfbfSEd Maste break;
123ac7ddfbfSEd Maste
124ac7ddfbfSEd Maste case eStopReasonException:
1254ba319b5SDimitry Andric // If we crashed, discard thread plans and stop. Don't force the
1264ba319b5SDimitry Andric // discard, however, since on rerun the target may clean up this
1274ba319b5SDimitry Andric // exception and continue normally from there.
128ac7ddfbfSEd Maste if (log)
129435933ddSDimitry Andric log->Printf(
130435933ddSDimitry Andric "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
131435933ddSDimitry Andric " (exception: %s)",
132435933ddSDimitry Andric m_thread.GetID(), stop_info_sp->GetDescription());
133ac7ddfbfSEd Maste m_thread.DiscardThreadPlans(false);
134ac7ddfbfSEd Maste return true;
135ac7ddfbfSEd Maste
136ac7ddfbfSEd Maste case eStopReasonExec:
1374ba319b5SDimitry Andric // If we crashed, discard thread plans and stop. Don't force the
1384ba319b5SDimitry Andric // discard, however, since on rerun the target may clean up this
1394ba319b5SDimitry Andric // exception and continue normally from there.
140ac7ddfbfSEd Maste if (log)
141435933ddSDimitry Andric log->Printf(
142435933ddSDimitry Andric "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
143435933ddSDimitry Andric " (exec.)",
144435933ddSDimitry Andric m_thread.GetID());
145ac7ddfbfSEd Maste m_thread.DiscardThreadPlans(false);
146ac7ddfbfSEd Maste return true;
147ac7ddfbfSEd Maste
148ac7ddfbfSEd Maste case eStopReasonThreadExiting:
149ac7ddfbfSEd Maste case eStopReasonSignal:
150435933ddSDimitry Andric if (stop_info_sp->ShouldStop(event_ptr)) {
151ac7ddfbfSEd Maste if (log)
152435933ddSDimitry Andric log->Printf(
153435933ddSDimitry Andric "Base plan discarding thread plans for thread tid = 0x%4.4" PRIx64
154435933ddSDimitry Andric " (signal: %s)",
155435933ddSDimitry Andric m_thread.GetID(), stop_info_sp->GetDescription());
156ac7ddfbfSEd Maste m_thread.DiscardThreadPlans(false);
157ac7ddfbfSEd Maste return true;
158435933ddSDimitry Andric } else {
159ac7ddfbfSEd Maste // We're not going to stop, but while we are here, let's figure out
160ac7ddfbfSEd Maste // whether to report this.
161ac7ddfbfSEd Maste if (stop_info_sp->ShouldNotify(event_ptr))
162ac7ddfbfSEd Maste m_stop_vote = eVoteYes;
163ac7ddfbfSEd Maste else
164ac7ddfbfSEd Maste m_stop_vote = eVoteNo;
165ac7ddfbfSEd Maste }
166ac7ddfbfSEd Maste return false;
167ac7ddfbfSEd Maste
168ac7ddfbfSEd Maste default:
169ac7ddfbfSEd Maste return true;
170ac7ddfbfSEd Maste }
171ac7ddfbfSEd Maste
172435933ddSDimitry Andric } else {
173ac7ddfbfSEd Maste m_run_vote = eVoteNoOpinion;
174ac7ddfbfSEd Maste m_stop_vote = eVoteNo;
175ac7ddfbfSEd Maste }
176ac7ddfbfSEd Maste
177ac7ddfbfSEd Maste // If there's no explicit reason to stop, then we will continue.
178ac7ddfbfSEd Maste return false;
179ac7ddfbfSEd Maste }
180ac7ddfbfSEd Maste
StopOthers()181435933ddSDimitry Andric bool ThreadPlanBase::StopOthers() { return false; }
182ac7ddfbfSEd Maste
GetPlanRunState()183435933ddSDimitry Andric StateType ThreadPlanBase::GetPlanRunState() { return eStateRunning; }
184ac7ddfbfSEd Maste
WillStop()185435933ddSDimitry Andric bool ThreadPlanBase::WillStop() { return true; }
186ac7ddfbfSEd Maste
DoWillResume(lldb::StateType resume_state,bool current_plan)187435933ddSDimitry Andric bool ThreadPlanBase::DoWillResume(lldb::StateType resume_state,
188435933ddSDimitry Andric bool current_plan) {
189435933ddSDimitry Andric // Reset these to the default values so we don't set them wrong, then not get
1904ba319b5SDimitry Andric // asked for a while, then return the wrong answer.
191ac7ddfbfSEd Maste m_run_vote = eVoteNoOpinion;
192ac7ddfbfSEd Maste m_stop_vote = eVoteNo;
193ac7ddfbfSEd Maste return true;
194ac7ddfbfSEd Maste }
195ac7ddfbfSEd Maste
196ac7ddfbfSEd Maste // The base plan is never done.
MischiefManaged()197435933ddSDimitry Andric bool ThreadPlanBase::MischiefManaged() {
198ac7ddfbfSEd Maste // The base plan is never done.
199ac7ddfbfSEd Maste return false;
200ac7ddfbfSEd Maste }
201