blob: 6570e1d103e0c7720c520be53e70b1605df327c1 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:241//===-- ThreadPlan.cpp ------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:563// 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
Chris Lattner30fdc8d2010-06-08 16:52:246//
7//===----------------------------------------------------------------------===//
8
Eugene Zelenkoe65b2cf2015-12-15 01:33:199#include "lldb/Target/ThreadPlan.h"
Jim Ingham06e827c2010-11-11 19:26:0910#include "lldb/Core/Debugger.h"
Jim Ingham06e827c2010-11-11 19:26:0911#include "lldb/Target/Process.h"
Kate Stoneb9c1b512016-09-06 20:57:5012#include "lldb/Target/RegisterContext.h"
Jim Ingham06e827c2010-11-11 19:26:0913#include "lldb/Target/Target.h"
Kate Stoneb9c1b512016-09-06 20:57:5014#include "lldb/Target/Thread.h"
Zachary Turner6f9e6902017-03-03 20:56:2815#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:2116#include "lldb/Utility/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:2417
18using namespace lldb;
19using namespace lldb_private;
20
21//----------------------------------------------------------------------
22// ThreadPlan constructor
23//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:5024ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread,
25 Vote stop_vote, Vote run_vote)
26 : m_thread(thread), m_stop_vote(stop_vote), m_run_vote(run_vote),
Jonas Devliegheree103ae92018-11-15 01:18:1527 m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false),
Kate Stoneb9c1b512016-09-06 20:57:5028 m_kind(kind), m_name(name), m_plan_complete_mutex(),
29 m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false),
30 m_plan_private(false), m_okay_to_discard(true), m_is_master_plan(false),
31 m_plan_succeeded(true) {
32 SetID(GetNextID());
Chris Lattner30fdc8d2010-06-08 16:52:2433}
34
35//----------------------------------------------------------------------
36// Destructor
37//----------------------------------------------------------------------
Eugene Zelenkoe65b2cf2015-12-15 01:33:1938ThreadPlan::~ThreadPlan() = default;
Chris Lattner30fdc8d2010-06-08 16:52:2439
Kate Stoneb9c1b512016-09-06 20:57:5040bool ThreadPlan::PlanExplainsStop(Event *event_ptr) {
41 if (m_cached_plan_explains_stop == eLazyBoolCalculate) {
42 bool actual_value = DoPlanExplainsStop(event_ptr);
43 m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo;
44 return actual_value;
45 } else {
46 return m_cached_plan_explains_stop == eLazyBoolYes;
47 }
48}
49
50bool ThreadPlan::IsPlanComplete() {
51 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
52 return m_plan_complete;
53}
54
55void ThreadPlan::SetPlanComplete(bool success) {
56 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
57 m_plan_complete = true;
58 m_plan_succeeded = success;
59}
60
61bool ThreadPlan::MischiefManaged() {
62 std::lock_guard<std::recursive_mutex> guard(m_plan_complete_mutex);
63 // Mark the plan is complete, but don't override the success flag.
64 m_plan_complete = true;
65 return true;
66}
67
68Vote ThreadPlan::ShouldReportStop(Event *event_ptr) {
69 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
70
71 if (m_stop_vote == eVoteNoOpinion) {
72 ThreadPlan *prev_plan = GetPreviousPlan();
73 if (prev_plan) {
74 Vote prev_vote = prev_plan->ShouldReportStop(event_ptr);
Pavel Labath05d382c2017-02-03 18:50:4575 LLDB_LOG(log, "returning previous thread plan vote: {0}", prev_vote);
Kate Stoneb9c1b512016-09-06 20:57:5076 return prev_vote;
Jim Ingham221d51c2013-05-08 00:35:1677 }
Kate Stoneb9c1b512016-09-06 20:57:5078 }
Pavel Labath05d382c2017-02-03 18:50:4579 LLDB_LOG(log, "Returning vote: {0}", m_stop_vote);
Kate Stoneb9c1b512016-09-06 20:57:5080 return m_stop_vote;
81}
82
83Vote ThreadPlan::ShouldReportRun(Event *event_ptr) {
84 if (m_run_vote == eVoteNoOpinion) {
85 ThreadPlan *prev_plan = GetPreviousPlan();
86 if (prev_plan)
87 return prev_plan->ShouldReportRun(event_ptr);
88 }
89 return m_run_vote;
90}
91
92bool ThreadPlan::StopOthers() {
93 ThreadPlan *prev_plan;
94 prev_plan = GetPreviousPlan();
95 return (prev_plan == nullptr) ? false : prev_plan->StopOthers();
96}
97
98void ThreadPlan::SetStopOthers(bool new_value) {
Adrian Prantl05097242018-04-30 16:49:0499 // SetStopOthers doesn't work up the hierarchy. You have to set the explicit
100 // ThreadPlan you want to affect.
Kate Stoneb9c1b512016-09-06 20:57:50101}
102
103bool ThreadPlan::WillResume(StateType resume_state, bool current_plan) {
104 m_cached_plan_explains_stop = eLazyBoolCalculate;
105
106 if (current_plan) {
107 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
108
109 if (log) {
110 RegisterContext *reg_ctx = m_thread.GetRegisterContext().get();
111 assert(reg_ctx);
112 addr_t pc = reg_ctx->GetPC();
113 addr_t sp = reg_ctx->GetSP();
114 addr_t fp = reg_ctx->GetFP();
115 log->Printf(
116 "%s Thread #%u (0x%p): tid = 0x%4.4" PRIx64 ", pc = 0x%8.8" PRIx64
117 ", sp = 0x%8.8" PRIx64 ", fp = 0x%8.8" PRIx64 ", "
118 "plan = '%s', state = %s, stop others = %d",
119 __FUNCTION__, m_thread.GetIndexID(), static_cast<void *>(&m_thread),
120 m_thread.GetID(), static_cast<uint64_t>(pc),
121 static_cast<uint64_t>(sp), static_cast<uint64_t>(fp), m_name.c_str(),
122 StateAsCString(resume_state), StopOthers());
Jim Ingham221d51c2013-05-08 00:35:16123 }
Kate Stoneb9c1b512016-09-06 20:57:50124 }
125 return DoWillResume(resume_state, current_plan);
Jim Ingham221d51c2013-05-08 00:35:16126}
127
Kate Stoneb9c1b512016-09-06 20:57:50128lldb::user_id_t ThreadPlan::GetNextID() {
129 static uint32_t g_nextPlanID = 0;
130 return ++g_nextPlanID;
Chris Lattner30fdc8d2010-06-08 16:52:24131}
132
Kate Stoneb9c1b512016-09-06 20:57:50133void ThreadPlan::DidPush() {}
134
135void ThreadPlan::WillPop() {}
136
137bool ThreadPlan::OkayToDiscard() {
138 return IsMasterPlan() ? m_okay_to_discard : true;
Chris Lattner30fdc8d2010-06-08 16:52:24139}
140
Kate Stoneb9c1b512016-09-06 20:57:50141lldb::StateType ThreadPlan::RunState() {
142 if (m_tracer_sp && m_tracer_sp->TracingEnabled() &&
143 m_tracer_sp->SingleStepEnabled())
144 return eStateStepping;
145 else
146 return GetPlanRunState();
147}
148
149bool ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) {
150 switch (reason) {
151 case eStopReasonWatchpoint:
152 case eStopReasonSignal:
153 case eStopReasonException:
154 case eStopReasonExec:
155 case eStopReasonThreadExiting:
156 case eStopReasonInstrumentation:
Chris Lattner30fdc8d2010-06-08 16:52:24157 return true;
Kate Stoneb9c1b512016-09-06 20:57:50158 default:
159 return false;
160 }
Jim Ingham9b03fa02015-07-23 19:55:02161}
162
Greg Clayton6e10f142013-07-30 00:23:06163//----------------------------------------------------------------------
164// ThreadPlanNull
165//----------------------------------------------------------------------
166
Kate Stoneb9c1b512016-09-06 20:57:50167ThreadPlanNull::ThreadPlanNull(Thread &thread)
168 : ThreadPlan(ThreadPlan::eKindNull, "Null Thread Plan", thread,
169 eVoteNoOpinion, eVoteNoOpinion) {}
Greg Clayton6e10f142013-07-30 00:23:06170
Eugene Zelenkoe65b2cf2015-12-15 01:33:19171ThreadPlanNull::~ThreadPlanNull() = default;
Greg Clayton6e10f142013-07-30 00:23:06172
Kate Stoneb9c1b512016-09-06 20:57:50173void ThreadPlanNull::GetDescription(Stream *s, lldb::DescriptionLevel level) {
174 s->PutCString("Null thread plan - thread has been destroyed.");
Greg Clayton6e10f142013-07-30 00:23:06175}
176
Kate Stoneb9c1b512016-09-06 20:57:50177bool ThreadPlanNull::ValidatePlan(Stream *error) {
Greg Clayton6e10f142013-07-30 00:23:06178#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50179 fprintf(stderr,
180 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
181 ", ptid = 0x%" PRIx64 ")",
182 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06183#else
Kate Stoneb9c1b512016-09-06 20:57:50184 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
185 if (log)
186 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
187 ", ptid = 0x%" PRIx64 ")",
188 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
189 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06190#endif
Kate Stoneb9c1b512016-09-06 20:57:50191 return true;
Greg Clayton6e10f142013-07-30 00:23:06192}
193
Kate Stoneb9c1b512016-09-06 20:57:50194bool ThreadPlanNull::ShouldStop(Event *event_ptr) {
Greg Clayton6e10f142013-07-30 00:23:06195#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50196 fprintf(stderr,
197 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
198 ", ptid = 0x%" PRIx64 ")",
199 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06200#else
Kate Stoneb9c1b512016-09-06 20:57:50201 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
202 if (log)
203 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
204 ", ptid = 0x%" PRIx64 ")",
205 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
206 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06207#endif
Kate Stoneb9c1b512016-09-06 20:57:50208 return true;
Greg Clayton6e10f142013-07-30 00:23:06209}
210
Kate Stoneb9c1b512016-09-06 20:57:50211bool ThreadPlanNull::WillStop() {
Greg Clayton6e10f142013-07-30 00:23:06212#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50213 fprintf(stderr,
214 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
215 ", ptid = 0x%" PRIx64 ")",
216 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06217#else
Kate Stoneb9c1b512016-09-06 20:57:50218 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
219 if (log)
220 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
221 ", ptid = 0x%" PRIx64 ")",
222 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
223 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06224#endif
Kate Stoneb9c1b512016-09-06 20:57:50225 return true;
Greg Clayton6e10f142013-07-30 00:23:06226}
227
Kate Stoneb9c1b512016-09-06 20:57:50228bool ThreadPlanNull::DoPlanExplainsStop(Event *event_ptr) {
Greg Clayton6e10f142013-07-30 00:23:06229#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50230 fprintf(stderr,
231 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
232 ", ptid = 0x%" PRIx64 ")",
233 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06234#else
Kate Stoneb9c1b512016-09-06 20:57:50235 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
236 if (log)
237 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
238 ", ptid = 0x%" PRIx64 ")",
239 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
240 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06241#endif
Kate Stoneb9c1b512016-09-06 20:57:50242 return true;
Greg Clayton6e10f142013-07-30 00:23:06243}
244
245// The null plan is never done.
Kate Stoneb9c1b512016-09-06 20:57:50246bool ThreadPlanNull::MischiefManaged() {
247// The null plan is never done.
Greg Clayton6e10f142013-07-30 00:23:06248#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50249 fprintf(stderr,
250 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
251 ", ptid = 0x%" PRIx64 ")",
252 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06253#else
Kate Stoneb9c1b512016-09-06 20:57:50254 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
255 if (log)
256 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
257 ", ptid = 0x%" PRIx64 ")",
258 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
259 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06260#endif
Kate Stoneb9c1b512016-09-06 20:57:50261 return false;
Greg Clayton6e10f142013-07-30 00:23:06262}
263
Kate Stoneb9c1b512016-09-06 20:57:50264lldb::StateType ThreadPlanNull::GetPlanRunState() {
265// Not sure what to return here. This is a dead thread.
Greg Clayton6e10f142013-07-30 00:23:06266#ifdef LLDB_CONFIGURATION_DEBUG
Kate Stoneb9c1b512016-09-06 20:57:50267 fprintf(stderr,
268 "error: %s called on thread that has been destroyed (tid = 0x%" PRIx64
269 ", ptid = 0x%" PRIx64 ")",
270 LLVM_PRETTY_FUNCTION, m_thread.GetID(), m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06271#else
Kate Stoneb9c1b512016-09-06 20:57:50272 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD));
273 if (log)
274 log->Error("%s called on thread that has been destroyed (tid = 0x%" PRIx64
275 ", ptid = 0x%" PRIx64 ")",
276 LLVM_PRETTY_FUNCTION, m_thread.GetID(),
277 m_thread.GetProtocolID());
Greg Clayton6e10f142013-07-30 00:23:06278#endif
Kate Stoneb9c1b512016-09-06 20:57:50279 return eStateRunning;
Greg Clayton6e10f142013-07-30 00:23:06280}