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);
36  ~ThreadPlanStack() = default;
37 
38  using PlanStack = std::vector<lldb::ThreadPlanSP>;
39 
40  void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level,
41  bool include_internal) const;
42 
43  size_t CheckpointCompletedPlans();
44 
45  void RestoreCompletedPlanCheckpoint(size_t checkpoint);
46 
47  void DiscardCompletedPlanCheckpoint(size_t checkpoint);
48 
49  void ThreadDestroyed(Thread *thread);
50 
51  void PushPlan(lldb::ThreadPlanSP new_plan_sp);
52 
53  lldb::ThreadPlanSP PopPlan();
54 
55  lldb::ThreadPlanSP DiscardPlan();
56 
57  // If the input plan is nullptr, discard all plans. Otherwise make sure this
58  // plan is in the stack, and if so discard up to and including it.
59  void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr);
60 
61  void DiscardAllPlans();
62 
64 
65  lldb::ThreadPlanSP GetCurrentPlan() const;
66 
67  lldb::ThreadPlanSP GetCompletedPlan(bool skip_private = true) const;
68 
69  lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx,
70  bool skip_private = true) const;
71 
72  lldb::ValueObjectSP GetReturnValueObject() const;
73 
74  lldb::ExpressionVariableSP GetExpressionVariable() const;
75 
76  bool AnyPlans() const;
77 
78  bool AnyCompletedPlans() const;
79 
80  bool AnyDiscardedPlans() const;
81 
82  bool IsPlanDone(ThreadPlan *plan) const;
83 
84  bool WasPlanDiscarded(ThreadPlan *plan) const;
85 
86  ThreadPlan *GetPreviousPlan(ThreadPlan *current_plan) const;
87 
89 
90  void WillResume();
91 
92  /// Clear the Thread* cache that each ThreadPlan contains.
93  ///
94  /// This is useful in situations like when a new Thread list is being
95  /// generated.
96  void ClearThreadCache();
97 
98 private:
99  void PrintOneStack(Stream &s, llvm::StringRef stack_name,
100  const PlanStack &stack, lldb::DescriptionLevel desc_level,
101  bool include_internal) const;
102 
103  PlanStack m_plans; ///< The stack of plans this thread is executing.
104  PlanStack m_completed_plans; ///< Plans that have been completed by this
105  /// stop. They get deleted when the thread
106  /// resumes.
107  PlanStack m_discarded_plans; ///< Plans that have been discarded by this
108  /// stop. They get deleted when the thread
109  /// resumes.
110  size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for
111  // completed plan checkpoints.
112  std::unordered_map<size_t, PlanStack> m_completed_plan_store;
113  mutable std::recursive_mutex m_stack_mutex;
114 };
115 
117 public:
118  ThreadPlanStackMap(Process &process) : m_process(process) {}
119  ~ThreadPlanStackMap() = default;
120 
121  // Prune the map using the current_threads list.
122  void Update(ThreadList &current_threads, bool delete_missing,
123  bool check_for_new = true);
124 
125  void AddThread(Thread &thread) {
126  lldb::tid_t tid = thread.GetID();
127  m_plans_list.emplace(tid, thread);
128  }
129 
130  bool RemoveTID(lldb::tid_t tid) {
131  auto result = m_plans_list.find(tid);
132  if (result == m_plans_list.end())
133  return false;
134  result->second.ThreadDestroyed(nullptr);
135  m_plans_list.erase(result);
136  return true;
137  }
138 
140  auto result = m_plans_list.find(tid);
141  if (result == m_plans_list.end())
142  return nullptr;
143  else
144  return &result->second;
145  }
146 
147  /// Clear the Thread* cache that each ThreadPlan contains.
148  ///
149  /// This is useful in situations like when a new Thread list is being
150  /// generated.
152  for (auto &plan_list : m_plans_list)
153  plan_list.second.ClearThreadCache();
154  }
155 
156  void Clear() {
157  for (auto &plan : m_plans_list)
158  plan.second.ThreadDestroyed(nullptr);
159  m_plans_list.clear();
160  }
161 
162  // Implements Process::DumpThreadPlans
163  void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal,
164  bool ignore_boring, bool skip_unreported);
165 
166  // Implements Process::DumpThreadPlansForTID
167  bool DumpPlansForTID(Stream &strm, lldb::tid_t tid,
168  lldb::DescriptionLevel desc_level, bool internal,
169  bool ignore_boring, bool skip_unreported);
170 
171  bool PrunePlansForTID(lldb::tid_t tid);
172 
173 private:
175  using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>;
177 };
178 
179 } // namespace lldb_private
180 
181 #endif // LLDB_TARGET_THREADPLANSTACK_H
lldb_private::ThreadPlanStackMap::DumpPlans
void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool ignore_boring, bool skip_unreported)
Definition: ThreadPlanStack.cpp:434
lldb_private::ThreadPlanStack::AnyPlans
bool AnyPlans() const
Definition: ThreadPlanStack.cpp:315
lldb_private::ThreadPlanStackMap::~ThreadPlanStackMap
~ThreadPlanStackMap()=default
lldb_private::ThreadPlanStackMap::AddThread
void AddThread(Thread &thread)
Definition: ThreadPlanStack.h:125
lldb_private::ThreadPlanStack::GetCompletedPlan
lldb::ThreadPlanSP GetCompletedPlan(bool skip_private=true) const
Definition: ThreadPlanStack.cpp:256
lldb_private::ThreadPlanStack::GetCurrentPlan
lldb::ThreadPlanSP GetCurrentPlan() const
Definition: ThreadPlanStack.cpp:250
lldb_private::ThreadPlanStack::PrintOneStack
void PrintOneStack(Stream &s, llvm::StringRef stack_name, const PlanStack &stack, lldb::DescriptionLevel desc_level, bool include_internal) const
Definition: ThreadPlanStack.cpp:52
lldb_private::ThreadPlanStack::m_completed_plans
PlanStack m_completed_plans
Plans that have been completed by this stop.
Definition: ThreadPlanStack.h:104
lldb_private::Process
Definition: Process.h:340
lldb_private::ThreadPlanStack::DiscardPlan
lldb::ThreadPlanSP DiscardPlan()
Definition: ThreadPlanStack.cpp:163
lldb_private::ThreadPlanStack::RestoreCompletedPlanCheckpoint
void RestoreCompletedPlanCheckpoint(size_t checkpoint)
Definition: ThreadPlanStack.cpp:92
lldb_private::ThreadPlanStack::IsPlanDone
bool IsPlanDone(ThreadPlan *plan) const
Definition: ThreadPlanStack.cpp:331
lldb_private::ThreadPlanStack::m_plans
PlanStack m_plans
The stack of plans this thread is executing.
Definition: ThreadPlanStack.h:103
lldb_private::ThreadPlanStack::GetPlanByIndex
lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx, bool skip_private=true) const
Definition: ThreadPlanStack.cpp:273
lldb_private::ThreadPlanStackMap::ClearThreadCache
void ClearThreadCache()
Clear the Thread* cache that each ThreadPlan contains.
Definition: ThreadPlanStack.h:151
lldb_private::Stream
Definition: Stream.h:28
lldb_private::ThreadPlanStack::~ThreadPlanStack
~ThreadPlanStack()=default
lldb_private::ThreadPlanStack::PushPlan
void PushPlan(lldb::ThreadPlanSP new_plan_sp)
Definition: ThreadPlanStack.cpp:133
lldb_private::ThreadPlanStack::GetReturnValueObject
lldb::ValueObjectSP GetReturnValueObject() const
Definition: ThreadPlanStack.cpp:288
lldb_private::ThreadPlanStack::m_completed_plan_store
std::unordered_map< size_t, PlanStack > m_completed_plan_store
Definition: ThreadPlanStack.h:112
lldb_private::ThreadPlanStack::ThreadDestroyed
void ThreadDestroyed(Thread *thread)
Definition: ThreadPlanStack.cpp:106
Target.h
lldb_private::ThreadPlan
Definition: ThreadPlan.h:282
lldb_private::ThreadPlanStackMap::PlansList
std::unordered_map< lldb::tid_t, ThreadPlanStack > PlansList
Definition: ThreadPlanStack.h:175
lldb-private-forward.h
lldb_private::ThreadPlanStack::CheckpointCompletedPlans
size_t CheckpointCompletedPlans()
Definition: ThreadPlanStack.cpp:84
lldb_private::ThreadPlanStack::m_completed_plan_checkpoint
size_t m_completed_plan_checkpoint
Definition: ThreadPlanStack.h:110
lldb_private::ThreadPlanStack::DiscardConsultingMasterPlans
void DiscardConsultingMasterPlans()
Definition: ThreadPlanStack.cpp:216
lldb_private::Thread
Definition: Thread.h:60
lldb_private::ThreadPlanStack::WillResume
void WillResume()
Definition: ThreadPlanStack.cpp:394
lldb_private::ThreadPlanStack::GetPreviousPlan
ThreadPlan * GetPreviousPlan(ThreadPlan *current_plan) const
Definition: ThreadPlanStack.cpp:349
lldb_private::ThreadPlanStack::PlanStack
std::vector< lldb::ThreadPlanSP > PlanStack
Definition: ThreadPlanStack.h:38
lldb_private::ThreadPlanStackMap
Definition: ThreadPlanStack.h:116
lldb_private::ThreadPlanStack::GetInnermostExpression
ThreadPlan * GetInnermostExpression() const
Definition: ThreadPlanStack.cpp:377
lldb_private::ThreadList
Definition: ThreadList.h:26
lldb_private::ThreadPlanStack::m_stack_mutex
std::recursive_mutex m_stack_mutex
Definition: ThreadPlanStack.h:113
lldb_private::ThreadPlanStackMap::ThreadPlanStackMap
ThreadPlanStackMap(Process &process)
Definition: ThreadPlanStack.h:118
lldb_private::ThreadPlanStackMap::PrunePlansForTID
bool PrunePlansForTID(lldb::tid_t tid)
Definition: ThreadPlanStack.cpp:511
Thread.h
lldb_private::UserID::GetID
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47
lldb-private.h
lldb_private::ThreadPlanStack::ClearThreadCache
void ClearThreadCache()
Clear the Thread* cache that each ThreadPlan contains.
Definition: ThreadPlanStack.cpp:388
uint32_t
lldb_private::ThreadPlanStack::AnyDiscardedPlans
bool AnyDiscardedPlans() const
Definition: ThreadPlanStack.cpp:326
lldb_private::ThreadPlanStack::ThreadPlanStack
ThreadPlanStack(const Thread &thread, bool make_empty=false)
Definition: ThreadPlanStack.cpp:30
lldb_private::ThreadPlanStack::m_discarded_plans
PlanStack m_discarded_plans
Plans that have been discarded by this stop.
Definition: ThreadPlanStack.h:107
lldb_private::ThreadPlanStack::DumpThreadPlans
void DumpThreadPlans(Stream &s, lldb::DescriptionLevel desc_level, bool include_internal) const
Definition: ThreadPlanStack.cpp:39
lldb_private::ThreadPlanStackMap::m_process
Process & m_process
Definition: ThreadPlanStack.h:174
lldb_private::ThreadPlanStackMap::RemoveTID
bool RemoveTID(lldb::tid_t tid)
Definition: ThreadPlanStack.h:130
lldb_private::ThreadPlanStackMap::Find
ThreadPlanStack * Find(lldb::tid_t tid)
Definition: ThreadPlanStack.h:139
lldb_private::ThreadPlanStackMap::m_plans_list
PlansList m_plans_list
Definition: ThreadPlanStack.h:176
lldb_private::ThreadPlanStack::AnyCompletedPlans
bool AnyCompletedPlans() const
Definition: ThreadPlanStack.cpp:321
lldb_private::ThreadPlanStack::DiscardPlansUpToPlan
void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr)
Definition: ThreadPlanStack.cpp:179
lldb_private::ThreadPlanStackMap::Clear
void Clear()
Definition: ThreadPlanStack.h:156
lldb_private::ThreadPlanStack
Definition: ThreadPlanStack.h:31
lldb_private::ThreadPlanStackMap::DumpPlansForTID
bool DumpPlansForTID(Stream &strm, lldb::tid_t tid, lldb::DescriptionLevel desc_level, bool internal, bool ignore_boring, bool skip_unreported)
Definition: ThreadPlanStack.cpp:469
lldb_private::ThreadPlanStack::PopPlan
lldb::ThreadPlanSP PopPlan()
Definition: ThreadPlanStack.cpp:149
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::ThreadPlanStackMap::Update
void Update(ThreadList &current_threads, bool delete_missing, bool check_for_new=true)
Definition: ThreadPlanStack.cpp:400
lldb_private::ThreadPlanStack::GetExpressionVariable
lldb::ExpressionVariableSP GetExpressionVariable() const
Definition: ThreadPlanStack.cpp:302
lldb_private::ThreadPlanStack::DiscardAllPlans
void DiscardAllPlans()
Definition: ThreadPlanStack.cpp:207
lldb_private::ThreadPlanStack::DiscardCompletedPlanCheckpoint
void DiscardCompletedPlanCheckpoint(size_t checkpoint)
Definition: ThreadPlanStack.cpp:101
lldb_private::ThreadPlanStack::WasPlanDiscarded
bool WasPlanDiscarded(ThreadPlan *plan) const
Definition: ThreadPlanStack.cpp:340
lldb::DescriptionLevel
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
Definition: lldb-enumerations.h:207
lldb::tid_t
uint64_t tid_t
Definition: lldb-types.h:86