16#include <unordered_set>
26 s.
Printf(
"Element %d: ", elem_idx);
27 plan->GetDescription(&s, desc_level);
43 bool include_internal)
const {
58 bool include_internal)
const {
64 bool any_public =
false;
65 if (!include_internal) {
66 for (
auto plan : stack) {
67 if (!plan->GetPrivate()) {
74 if (include_internal || any_public) {
77 s << stack_name <<
":\n";
78 for (
auto plan : stack) {
79 if (!include_internal && plan->GetPrivate())
98 "Asked for a checkpoint that didn't exist");
112 plan->ThreadDestroyed();
115 plan->ThreadDestroyed();
118 plan->ThreadDestroyed();
129 if (thread !=
nullptr) {
131 m_plans.push_back(null_plan_sp);
141 assert((
m_plans.size() > 0 || new_plan_sp->IsBasePlan()) &&
142 "Zeroth plan must be a base plan");
144 if (!new_plan_sp->GetThreadPlanTracer()) {
146 new_plan_sp->SetThreadPlanTracer(
m_plans.back()->GetThreadPlanTracer());
148 m_plans.push_back(new_plan_sp);
150 new_plan_sp->DidPush();
155 assert(
m_plans.size() > 1 &&
"Can't pop the base thread plan");
173 assert(
m_plans.size() > 1 &&
"Can't discard the base thread plan");
189 int stack_size =
m_plans.size();
191 if (up_to_plan_ptr ==
nullptr) {
192 for (
int i = stack_size - 1; i > 0; i--)
197 bool found_it =
false;
198 for (
int i = stack_size - 1; i > 0; i--) {
199 if (
m_plans[i].get() == up_to_plan_ptr) {
206 bool last_one =
false;
207 for (
int i = stack_size - 1; i > 0 && !last_one; i--) {
217 int stack_size =
m_plans.size();
218 for (
int i = stack_size - 1; i > 0; i--) {
226 int controlling_plan_idx;
231 for (controlling_plan_idx =
m_plans.size() - 1; controlling_plan_idx >= 0;
232 controlling_plan_idx--) {
233 if (
m_plans[controlling_plan_idx]->IsControllingPlan()) {
234 discard =
m_plans[controlling_plan_idx]->OkayToDiscard();
244 for (
int i =
m_plans.size() - 1; i > controlling_plan_idx; i--) {
251 if (controlling_plan_idx > 0) {
263 assert(
m_plans.size() != 0 &&
"There will always be a base plan.");
278 if (!completed_plan_sp->GetPrivate())
279 return completed_plan_sp;
285 bool skip_private)
const {
290 if (skip_private && plan_sp->GetPrivate())
307 if (return_valobj_sp)
308 return return_valobj_sp;
321 if (expression_variable_sp)
322 return expression_variable_sp;
345 if (plan.get() == in_plan)
354 if (plan.get() == in_plan)
362 if (current_plan ==
nullptr)
368 for (
int i = stack_size - 1; i > 0; i--) {
381 for (
int i = stack_size - 1; i > 0; i--) {
382 if (current_plan ==
m_plans[i].get())
390 int stack_size =
m_plans.size();
392 for (
int i = stack_size - 1; i > 0; i--) {
402 thread_plan_sp->ClearThreadCache();
413 bool check_for_new) {
417 "thread list is stale");
420 for (
auto thread : current_threads.
Threads()) {
422 if (!
Find(cur_tid)) {
424 thread->QueueBasePlan(
true);
436 std::unordered_set<lldb::tid_t> live_tids;
437 live_tids.reserve(current_threads.
GetSize(
false));
438 for (
const auto &thread : current_threads.
Threads())
439 live_tids.insert(thread->GetID());
441 std::vector<lldb::tid_t> missing_threads;
446 if (live_tids.find(cur_tid) == live_tids.end())
447 missing_threads.push_back(cur_tid);
456 bool internal,
bool condense_if_trivial,
457 bool skip_unreported) {
461 uint32_t index_id = 0;
464 if (skip_unreported) {
469 index_id = thread_sp->GetIndexID();
471 if (condense_if_trivial) {
472 if (!elem.second.AnyPlans() && !elem.second.AnyCompletedPlans() &&
473 !elem.second.AnyDiscardedPlans()) {
474 strm.
Printf(
"thread #%u: tid = 0x%4.4" PRIx64
"\n", index_id, tid);
484 strm.
Printf(
"thread #%u: tid = 0x%4.4" PRIx64
":\n", index_id, tid);
486 elem.second.DumpThreadPlans(strm, desc_level, internal);
493 bool condense_if_trivial,
494 bool skip_unreported) {
496 uint32_t index_id = 0;
499 if (skip_unreported) {
501 strm.
Format(
"Unknown TID: {0}", tid);
507 index_id = thread_sp->GetIndexID();
510 strm.
Format(
"Unknown TID: {0}\n", tid);
514 if (condense_if_trivial) {
517 strm.
Printf(
"thread #%u: tid = 0x%4.4" PRIx64
"\n", index_id, tid);
527 strm.
Printf(
"thread #%u: tid = 0x%4.4" PRIx64
":\n", index_id, tid);
uint32_t GetKind(uint32_t data)
Return the type kind encoded in the given data.
static void PrintPlanElement(Stream &s, const ThreadPlanSP &plan, lldb::DescriptionLevel desc_level, int32_t elem_idx)
A stream class that can stream formatted output to a file.
void Format(const char *format, Args &&... args)
Forwards the arguments to llvm::formatv and writes to the stream.
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
void IndentLess(unsigned amount=2)
Decrement the current indentation level.
void IndentMore(unsigned amount=2)
Increment the current indentation level.
virtual ThreadIterable Threads()
uint32_t GetStopID() const
uint32_t GetSize(bool can_update=true)
bool RemoveTID(lldb::tid_t tid)
std::recursive_mutex m_stack_map_mutex
void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool ignore_boring, bool skip_unreported)
void AddThread(Thread &thread)
bool PrunePlansForTID(lldb::tid_t tid)
ThreadPlanStack * Find(lldb::tid_t tid)
void Update(ThreadList ¤t_threads, bool delete_missing, bool check_for_new=true)
bool DumpPlansForTID(Stream &strm, lldb::tid_t tid, lldb::DescriptionLevel desc_level, bool internal, bool ignore_boring, bool skip_unreported)
PlanStack m_discarded_plans
Plans that have been discarded by this stop.
size_t m_completed_plan_checkpoint
void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr)
lldb::ThreadPlanSP PopPlan()
bool AnyCompletedPlans() const
void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, bool include_internal) const
friend class lldb_private::Thread
lldb::ThreadPlanSP GetCompletedPlan(bool skip_private=true) const
lldb::ExpressionVariableSP GetExpressionVariable() const
PlanStack m_completed_plans
Plans that have been completed by this stop.
void ThreadDestroyed(Thread *thread)
ThreadPlanStack(const Thread &thread, bool make_empty=false)
llvm::sys::RWMutex m_stack_mutex
bool AnyDiscardedPlans() const
lldb::ThreadPlanSP GetCurrentPlanNoLock() const
bool IsPlanDone(ThreadPlan *plan) const
void RestoreCompletedPlanCheckpoint(size_t checkpoint)
lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx, bool skip_private=true) const
lldb::ValueObjectSP GetReturnValueObject() const
void PushPlan(lldb::ThreadPlanSP new_plan_sp)
lldb::ThreadPlanSP DiscardPlanNoLock()
void DiscardConsultingControllingPlans()
lldb::ThreadPlanSP DiscardPlan()
std::unordered_map< size_t, PlanStack > m_completed_plan_store
bool WasPlanDiscarded(ThreadPlan *plan) const
void ClearThreadCache()
Clear the Thread* cache that each ThreadPlan contains.
void DiscardCompletedPlanCheckpoint(size_t checkpoint)
void PrintOneStackNoLock(Stream &s, llvm::StringRef stack_name, const PlanStack &stack, lldb::DescriptionLevel desc_level, bool include_internal) const
size_t CheckpointCompletedPlans()
ThreadPlan * GetInnermostExpression() const
PlanStack m_plans
The stack of plans this thread is executing.
lldb::ThreadPlanSP GetCurrentPlan() const
ThreadPlan * GetPreviousPlan(ThreadPlan *current_plan) const
std::vector< lldb::ThreadPlanSP > PlanStack
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ThreadPlan > ThreadPlanSP
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
std::shared_ptr< lldb_private::Thread > ThreadSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP