LLDB  mainline
ThreadPlanStack.h
Go to the documentation of this file.
1 //===-- ThreadPlanStack.h ---------------------------------------*- C++ -*-===//
2 //
3 // 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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_TARGET_THREADPLANSTACK_H
10 #define LLDB_TARGET_THREADPLANSTACK_H
11 
12 #include <mutex>
13 #include <string>
14 #include <unordered_map>
15 #include <vector>
16 
17 #include "lldb/Target/Target.h"
18 #include "lldb/Target/Thread.h"
20 #include "lldb/lldb-private.h"
21 
22 namespace lldb_private {
23 
24 // The ThreadPlans have a thread for use when they are asked all the ThreadPlan
25 // state machine questions, but they should never cache any pointers from their
26 // owning lldb_private::Thread. That's because we want to be able to detach
27 // them from an owning thread, then reattach them by TID.
28 // The ThreadPlanStack holds the ThreadPlans for a given TID. All its methods
29 // are private, and it should only be accessed through the owning thread. When
30 // it is detached from a thread, all you can do is reattach it or delete it.
32  friend class lldb_private::Thread;
33 
34 public:
35  ThreadPlanStack(const Thread &thread, bool make_empty = false);
37 
39 
40  using PlanStack = std::vector<lldb::ThreadPlanSP>;
41 
42  void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level,
43  bool include_internal) const;
44 
45  size_t CheckpointCompletedPlans();
46 
47  void RestoreCompletedPlanCheckpoint(size_t checkpoint);
48 
49  void DiscardCompletedPlanCheckpoint(size_t checkpoint);
50 
51  void ThreadDestroyed(Thread *thread);
52 
53  void EnableTracer(bool value, bool single_stepping);
54 
55  void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp);
56 
57  void PushPlan(lldb::ThreadPlanSP new_plan_sp);
58 
59  lldb::ThreadPlanSP PopPlan();
60 
61  lldb::ThreadPlanSP DiscardPlan();
62 
63  // If the input plan is nullptr, discard all plans. Otherwise make sure this
64  // plan is in the stack, and if so discard up to and including it.
65  void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr);
66 
67  void DiscardAllPlans();
68 
70 
71  lldb::ThreadPlanSP GetCurrentPlan() const;
72 
73  lldb::ThreadPlanSP GetCompletedPlan(bool skip_private = true) const;
74 
75  lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx,
76  bool skip_private = true) const;
77 
78  lldb::ValueObjectSP GetReturnValueObject() const;
79 
80  lldb::ExpressionVariableSP GetExpressionVariable() const;
81 
82  bool AnyPlans() const;
83 
84  bool AnyCompletedPlans() const;
85 
86  bool AnyDiscardedPlans() const;
87 
88  bool IsPlanDone(ThreadPlan *plan) const;
89 
90  bool WasPlanDiscarded(ThreadPlan *plan) const;
91 
92  ThreadPlan *GetPreviousPlan(ThreadPlan *current_plan) const;
93 
95 
96  void WillResume();
97 
98 private:
100 
101  void PrintOneStack(Stream &s, llvm::StringRef stack_name,
102  const PlanStack &stack, lldb::DescriptionLevel desc_level,
103  bool include_internal) const;
104 
105  PlanStack m_plans; ///< The stack of plans this thread is executing.
106  PlanStack m_completed_plans; ///< Plans that have been completed by this
107  /// stop. They get deleted when the thread
108  /// resumes.
109  PlanStack m_discarded_plans; ///< Plans that have been discarded by this
110  /// stop. They get deleted when the thread
111  /// resumes.
112  size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for
113  // completed plan checkpoints.
114  std::unordered_map<size_t, PlanStack> m_completed_plan_store;
115 };
116 
118 public:
119  ThreadPlanStackMap(Process &process) : m_process(process) {}
121 
122  // Prune the map using the current_threads list.
123  void Update(ThreadList &current_threads, bool delete_missing,
124  bool check_for_new = true);
125 
126  void AddThread(Thread &thread) {
127  lldb::tid_t tid = thread.GetID();
128  m_plans_list.emplace(tid, thread);
129  }
130 
131  bool RemoveTID(lldb::tid_t tid) {
132  auto result = m_plans_list.find(tid);
133  if (result == m_plans_list.end())
134  return false;
135  result->second.ThreadDestroyed(nullptr);
136  m_plans_list.erase(result);
137  return true;
138  }
139 
141  auto result = m_plans_list.find(tid);
142  if (result == m_plans_list.end())
143  return nullptr;
144  else
145  return &result->second;
146  }
147 
148  void Clear() {
149  for (auto plan : m_plans_list)
150  plan.second.ThreadDestroyed(nullptr);
151  m_plans_list.clear();
152  }
153 
154  // Implements Process::DumpThreadPlans
155  void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal,
156  bool ignore_boring, bool skip_unreported);
157 
158  // Implements Process::DumpThreadPlansForTID
159  bool DumpPlansForTID(Stream &strm, lldb::tid_t tid,
160  lldb::DescriptionLevel desc_level, bool internal,
161  bool ignore_boring, bool skip_unreported);
162 
163  bool PrunePlansForTID(lldb::tid_t tid);
164 
165 private:
167  using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>;
169 };
170 
171 } // namespace lldb_private
172 
173 #endif // LLDB_TARGET_THREADPLANSTACK_H
PlanStack m_discarded_plans
Plans that have been discarded by this stop.
A class that represents a running process on the host machine.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
bool WasPlanDiscarded(ThreadPlan *plan) const
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
ThreadPlan * GetInnermostExpression() const
void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, bool include_internal) const
void DiscardCompletedPlanCheckpoint(size_t checkpoint)
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx, bool skip_private=true) const
bool RemoveTID(lldb::tid_t tid)
ThreadPlanStack(const Thread &thread, bool make_empty=false)
ThreadPlanStack * Find(lldb::tid_t tid)
const PlanStack & GetStackOfKind(ThreadPlanStack::StackKind kind) const
lldb::ExpressionVariableSP GetExpressionVariable() const
std::unordered_map< lldb::tid_t, ThreadPlanStack > PlansList
PlanStack m_plans
The stack of plans this thread is executing.
lldb::ThreadPlanSP GetCompletedPlan(bool skip_private=true) const
uint64_t tid_t
Definition: lldb-types.h:86
lldb::ThreadPlanSP DiscardPlan()
A plug-in interface definition class for debugging a process.
Definition: Process.h:362
lldb::ValueObjectSP GetReturnValueObject() const
ThreadPlan * GetPreviousPlan(ThreadPlan *current_plan) const
void SetTracer(lldb::ThreadPlanTracerSP &tracer_sp)
lldb::ThreadPlanSP GetCurrentPlan() const
PlanStack m_completed_plans
Plans that have been completed by this stop.
bool IsPlanDone(ThreadPlan *plan) const
std::unordered_map< size_t, PlanStack > m_completed_plan_store
void RestoreCompletedPlanCheckpoint(size_t checkpoint)
std::vector< lldb::ThreadPlanSP > PlanStack
void ThreadDestroyed(Thread *thread)
void PrintOneStack(Stream &s, llvm::StringRef stack_name, const PlanStack &stack, lldb::DescriptionLevel desc_level, bool include_internal) const
void EnableTracer(bool value, bool single_stepping)
void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr)
void PushPlan(lldb::ThreadPlanSP new_plan_sp)