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 "llvm/Support/RWMutex.h"
18
19#include "lldb/Target/Target.h"
20#include "lldb/Target/Thread.h"
22#include "lldb/lldb-private.h"
23
24namespace lldb_private {
25
26// The ThreadPlans have a thread for use when they are asked all the ThreadPlan
27// state machine questions, but they should never cache any pointers from their
28// owning lldb_private::Thread. That's because we want to be able to detach
29// them from an owning thread, then reattach them by TID.
30// The ThreadPlanStack holds the ThreadPlans for a given TID. All its methods
31// are private, and it should only be accessed through the owning thread. When
32// it is detached from a thread, all you can do is reattach it or delete it.
35
36public:
37 ThreadPlanStack(const Thread &thread, bool make_empty = false);
38 ~ThreadPlanStack() = default;
39
40 using PlanStack = std::vector<lldb::ThreadPlanSP>;
41
43 bool include_internal) const;
44
46
47 void RestoreCompletedPlanCheckpoint(size_t checkpoint);
48
49 void DiscardCompletedPlanCheckpoint(size_t checkpoint);
50
51 void ThreadDestroyed(Thread *thread);
52
53 void PushPlan(lldb::ThreadPlanSP new_plan_sp);
54
56
58
59 // If the input plan is nullptr, discard all plans. Otherwise make sure this
60 // plan is in the stack, and if so discard up to and including it.
61 void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr);
62
63 void DiscardAllPlans();
64
66
68
69 lldb::ThreadPlanSP GetCompletedPlan(bool skip_private = true) const;
70
71 lldb::ThreadPlanSP GetPlanByIndex(uint32_t plan_idx,
72 bool skip_private = true) const;
73
75
77
78 bool AnyPlans() const;
79
80 bool AnyCompletedPlans() const;
81
82 bool AnyDiscardedPlans() const;
83
84 bool IsPlanDone(ThreadPlan *plan) const;
85
86 bool WasPlanDiscarded(ThreadPlan *plan) const;
87
88 ThreadPlan *GetPreviousPlan(ThreadPlan *current_plan) const;
89
91
92 void WillResume();
93
94 /// Clear the Thread* cache that each ThreadPlan contains.
95 ///
96 /// This is useful in situations like when a new Thread list is being
97 /// generated.
98 void ClearThreadCache();
99
100private:
103 void PrintOneStackNoLock(Stream &s, llvm::StringRef stack_name,
104 const PlanStack &stack,
105 lldb::DescriptionLevel desc_level,
106 bool include_internal) const;
107
108 PlanStack m_plans; ///< The stack of plans this thread is executing.
109 PlanStack m_completed_plans; ///< Plans that have been completed by this
110 /// stop. They get deleted when the thread
111 /// resumes.
112 PlanStack m_discarded_plans; ///< Plans that have been discarded by this
113 /// stop. They get deleted when the thread
114 /// resumes.
115 size_t m_completed_plan_checkpoint = 0; // Monotonically increasing token for
116 // completed plan checkpoints.
117 std::unordered_map<size_t, PlanStack> m_completed_plan_store;
118 mutable llvm::sys::RWMutex m_stack_mutex;
119};
120
122public:
123 ThreadPlanStackMap(Process &process) : m_process(process) {}
125
126 // Prune the map using the current_threads list. The caller must have updated
127 // the list, because this runs as part of the update and therefore cannot
128 // recursively do the same.
129 void Update(ThreadList &current_threads, bool delete_missing,
130 bool check_for_new = true);
131
132 void AddThread(Thread &thread) {
133 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
134 lldb::tid_t tid = thread.GetID();
135 m_plans_list.emplace(tid, thread);
136 }
137
139 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
140 auto result = m_plans_list.find(tid);
141 if (result == m_plans_list.end())
142 return false;
143 result->second.ThreadDestroyed(nullptr);
144 m_plans_list.erase(result);
145 return true;
146 }
147
149 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
150 auto result = m_plans_list.find(tid);
151 if (result == m_plans_list.end())
152 return nullptr;
153 else
154 return &result->second;
155 }
156
157 /// Clear the Thread* cache that each ThreadPlan contains.
158 ///
159 /// This is useful in situations like when a new Thread list is being
160 /// generated.
162 for (auto &plan_list : m_plans_list)
163 plan_list.second.ClearThreadCache();
164 }
165
166 void Clear() {
167 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
168 for (auto &plan : m_plans_list)
169 plan.second.ThreadDestroyed(nullptr);
170 m_plans_list.clear();
171 }
172
173 // Implements Process::DumpThreadPlans
174 void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal,
175 bool ignore_boring, bool skip_unreported);
176
177 // Implements Process::DumpThreadPlansForTID
178 bool DumpPlansForTID(Stream &strm, lldb::tid_t tid,
179 lldb::DescriptionLevel desc_level, bool internal,
180 bool ignore_boring, bool skip_unreported);
181
183
184private:
186 mutable std::recursive_mutex m_stack_map_mutex;
187 using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>;
189
190};
191
192} // namespace lldb_private
193
194#endif // LLDB_TARGET_THREADPLANSTACK_H
A plug-in interface definition class for debugging a process.
Definition Process.h:368
A stream class that can stream formatted output to a file.
Definition Stream.h:28
void ClearThreadCache()
Clear the Thread* cache that each ThreadPlan contains.
std::recursive_mutex m_stack_map_mutex
void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal, bool ignore_boring, bool skip_unreported)
bool PrunePlansForTID(lldb::tid_t tid)
ThreadPlanStack * Find(lldb::tid_t tid)
void Update(ThreadList &current_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)
std::unordered_map< lldb::tid_t, ThreadPlanStack > PlansList
PlanStack m_discarded_plans
Plans that have been discarded by this stop.
void DiscardPlansUpToPlan(ThreadPlan *up_to_plan_ptr)
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)
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()
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
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::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
uint64_t tid_t
Definition lldb-types.h:85