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.
127 void Update(ThreadList &current_threads, bool delete_missing,
128 bool check_for_new = true);
129
130 void AddThread(Thread &thread) {
131 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
132 lldb::tid_t tid = thread.GetID();
133 m_plans_list.emplace(tid, thread);
134 }
135
137 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
138 auto result = m_plans_list.find(tid);
139 if (result == m_plans_list.end())
140 return false;
141 result->second.ThreadDestroyed(nullptr);
142 m_plans_list.erase(result);
143 return true;
144 }
145
147 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
148 auto result = m_plans_list.find(tid);
149 if (result == m_plans_list.end())
150 return nullptr;
151 else
152 return &result->second;
153 }
154
155 /// Clear the Thread* cache that each ThreadPlan contains.
156 ///
157 /// This is useful in situations like when a new Thread list is being
158 /// generated.
160 for (auto &plan_list : m_plans_list)
161 plan_list.second.ClearThreadCache();
162 }
163
164 void Clear() {
165 std::lock_guard<std::recursive_mutex> guard(m_stack_map_mutex);
166 for (auto &plan : m_plans_list)
167 plan.second.ThreadDestroyed(nullptr);
168 m_plans_list.clear();
169 }
170
171 // Implements Process::DumpThreadPlans
172 void DumpPlans(Stream &strm, lldb::DescriptionLevel desc_level, bool internal,
173 bool ignore_boring, bool skip_unreported);
174
175 // Implements Process::DumpThreadPlansForTID
176 bool DumpPlansForTID(Stream &strm, lldb::tid_t tid,
177 lldb::DescriptionLevel desc_level, bool internal,
178 bool ignore_boring, bool skip_unreported);
179
181
182private:
184 mutable std::recursive_mutex m_stack_map_mutex;
185 using PlansList = std::unordered_map<lldb::tid_t, ThreadPlanStack>;
187
188};
189
190} // namespace lldb_private
191
192#endif // LLDB_TARGET_THREADPLANSTACK_H
A plug-in interface definition class for debugging a process.
Definition: Process.h:343
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.
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)
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
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)
llvm::sys::RWMutex m_stack_mutex
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()
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
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
Definition: lldb-forward.h:453
DescriptionLevel
Description levels for "void GetDescription(Stream *, DescriptionLevel)" calls.
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:484
std::shared_ptr< lldb_private::ExpressionVariable > ExpressionVariableSP
Definition: lldb-forward.h:351
uint64_t tid_t
Definition: lldb-types.h:84
lldb::user_id_t GetID() const
Get accessor for the user ID.
Definition: UserID.h:47