xref: /freebsd/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ThreadMemory.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- ThreadMemory.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_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
10 #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
11 
12 #include <string>
13 
14 #include "lldb/Target/Thread.h"
15 
16 /// A memory thread with its own ID, optionally backed by a real thread.
17 /// Most methods of this class dispatch to the real thread if it is not null.
18 /// Notable exceptions are the methods calculating the StopInfo and
19 /// RegisterContext of the thread, those may query the OS plugin that created
20 /// the thread.
21 class ThreadMemory : public lldb_private::Thread {
22 public:
ThreadMemory(lldb_private::Process & process,lldb::tid_t tid,lldb::addr_t register_data_addr)23   ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
24                lldb::addr_t register_data_addr)
25       : Thread(process, tid), m_register_data_addr(register_data_addr) {}
26 
27   ~ThreadMemory() override;
28 
29   lldb::RegisterContextSP GetRegisterContext() override;
30 
31   lldb::RegisterContextSP
32   CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;
33 
34   bool CalculateStopInfo() override;
35 
GetInfo()36   const char *GetInfo() override {
37     if (m_backing_thread_sp)
38       return m_backing_thread_sp->GetInfo();
39     return nullptr;
40   }
41 
GetName()42   const char *GetName() override {
43     if (m_backing_thread_sp)
44       return m_backing_thread_sp->GetName();
45     return nullptr;
46   }
47 
GetQueueName()48   const char *GetQueueName() override {
49     if (m_backing_thread_sp)
50       return m_backing_thread_sp->GetQueueName();
51     return nullptr;
52   }
53 
54   void WillResume(lldb::StateType resume_state) override;
55 
SetQueueName(const char * name)56   void SetQueueName(const char *name) override {
57     if (m_backing_thread_sp)
58       m_backing_thread_sp->SetQueueName(name);
59   }
60 
GetQueueID()61   lldb::queue_id_t GetQueueID() override {
62     if (m_backing_thread_sp)
63       return m_backing_thread_sp->GetQueueID();
64     return LLDB_INVALID_QUEUE_ID;
65   }
66 
SetQueueID(lldb::queue_id_t new_val)67   void SetQueueID(lldb::queue_id_t new_val) override {
68     if (m_backing_thread_sp)
69       m_backing_thread_sp->SetQueueID(new_val);
70   }
71 
GetQueueKind()72   lldb::QueueKind GetQueueKind() override {
73     if (m_backing_thread_sp)
74       return m_backing_thread_sp->GetQueueKind();
75     return lldb::eQueueKindUnknown;
76   }
77 
SetQueueKind(lldb::QueueKind kind)78   void SetQueueKind(lldb::QueueKind kind) override {
79     if (m_backing_thread_sp)
80       m_backing_thread_sp->SetQueueKind(kind);
81   }
82 
GetQueue()83   lldb::QueueSP GetQueue() override {
84     if (m_backing_thread_sp)
85       return m_backing_thread_sp->GetQueue();
86     return lldb::QueueSP();
87   }
88 
GetQueueLibdispatchQueueAddress()89   lldb::addr_t GetQueueLibdispatchQueueAddress() override {
90     if (m_backing_thread_sp)
91       return m_backing_thread_sp->GetQueueLibdispatchQueueAddress();
92     return LLDB_INVALID_ADDRESS;
93   }
94 
SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t)95   void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override {
96     if (m_backing_thread_sp)
97       m_backing_thread_sp->SetQueueLibdispatchQueueAddress(dispatch_queue_t);
98   }
99 
GetAssociatedWithLibdispatchQueue()100   lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override {
101     if (m_backing_thread_sp)
102       return m_backing_thread_sp->GetAssociatedWithLibdispatchQueue();
103     return lldb_private::eLazyBoolNo;
104   }
105 
SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue)106   void SetAssociatedWithLibdispatchQueue(
107       lldb_private::LazyBool associated_with_libdispatch_queue) override {
108     if (m_backing_thread_sp)
109       m_backing_thread_sp->SetAssociatedWithLibdispatchQueue(
110           associated_with_libdispatch_queue);
111   }
112 
ThreadHasQueueInformation()113   bool ThreadHasQueueInformation() const override {
114     if (m_backing_thread_sp)
115       return m_backing_thread_sp->ThreadHasQueueInformation();
116     return false;
117   }
118 
DidResume()119   void DidResume() override {
120     if (m_backing_thread_sp)
121       m_backing_thread_sp->DidResume();
122   }
123 
GetProtocolID()124   lldb::user_id_t GetProtocolID() const override {
125     if (m_backing_thread_sp)
126       return m_backing_thread_sp->GetProtocolID();
127     return Thread::GetProtocolID();
128   }
129 
130   void RefreshStateAfterStop() override;
131 
132   void ClearStackFrames() override;
133 
ClearBackingThread()134   void ClearBackingThread() override {
135     if (m_backing_thread_sp)
136       m_backing_thread_sp->ClearBackedThread();
137     m_backing_thread_sp.reset();
138   }
139 
SetBackingThread(const lldb::ThreadSP & thread_sp)140   bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
141     m_backing_thread_sp = thread_sp;
142     thread_sp->SetBackedThread(*this);
143     return thread_sp.get();
144   }
145 
GetBackingThread()146   lldb::ThreadSP GetBackingThread() const override {
147     return m_backing_thread_sp;
148   }
149 
IsOperatingSystemPluginThread()150   bool IsOperatingSystemPluginThread() const override { return true; }
151 
152 private:
153   lldb::addr_t m_register_data_addr;
154   lldb::ThreadSP m_backing_thread_sp;
155 
156   ThreadMemory(const ThreadMemory &) = delete;
157   const ThreadMemory &operator=(const ThreadMemory &) = delete;
158 };
159 
160 /// A ThreadMemory that optionally overrides the thread name.
161 class ThreadMemoryProvidingName : public ThreadMemory {
162 public:
ThreadMemoryProvidingName(lldb_private::Process & process,lldb::tid_t tid,lldb::addr_t register_data_addr,llvm::StringRef name)163   ThreadMemoryProvidingName(lldb_private::Process &process, lldb::tid_t tid,
164                             lldb::addr_t register_data_addr,
165                             llvm::StringRef name)
166       : ThreadMemory(process, tid, register_data_addr), m_name(name) {}
167 
GetName()168   const char *GetName() override {
169     if (!m_name.empty())
170       return m_name.c_str();
171     return ThreadMemory::GetName();
172   }
173 
174   ~ThreadMemoryProvidingName() override = default;
175 
176 private:
177   std::string m_name;
178 };
179 
180 /// A ThreadMemoryProvidingName that optionally overrides queue information.
181 class ThreadMemoryProvidingNameAndQueue : public ThreadMemoryProvidingName {
182 public:
183   ThreadMemoryProvidingNameAndQueue(
184       lldb_private::Process &process, lldb::tid_t tid,
185       const lldb::ValueObjectSP &thread_info_valobj_sp);
186 
187   ThreadMemoryProvidingNameAndQueue(lldb_private::Process &process,
188                                     lldb::tid_t tid, llvm::StringRef name,
189                                     llvm::StringRef queue,
190                                     lldb::addr_t register_data_addr);
191 
192   ~ThreadMemoryProvidingNameAndQueue() override = default;
193 
GetQueueName()194   const char *GetQueueName() override {
195     if (!m_queue.empty())
196       return m_queue.c_str();
197     return ThreadMemory::GetQueueName();
198   }
199 
200   /// TODO: this method should take into account the queue override.
SetQueueName(const char * name)201   void SetQueueName(const char *name) override { Thread::SetQueueName(name); }
202 
203   /// TODO: this method should take into account the queue override.
GetQueueID()204   lldb::queue_id_t GetQueueID() override { return Thread::GetQueueID(); }
205 
206   /// TODO: this method should take into account the queue override.
SetQueueID(lldb::queue_id_t new_val)207   void SetQueueID(lldb::queue_id_t new_val) override {
208     Thread::SetQueueID(new_val);
209   }
210 
211   /// TODO: this method should take into account the queue override.
GetQueueKind()212   lldb::QueueKind GetQueueKind() override { return Thread::GetQueueKind(); }
213 
214   /// TODO: this method should take into account the queue override.
SetQueueKind(lldb::QueueKind kind)215   void SetQueueKind(lldb::QueueKind kind) override {
216     Thread::SetQueueKind(kind);
217   }
218 
219   /// TODO: this method should take into account the queue override.
GetQueue()220   lldb::QueueSP GetQueue() override { return Thread::GetQueue(); }
221 
222   /// TODO: this method should take into account the queue override.
GetQueueLibdispatchQueueAddress()223   lldb::addr_t GetQueueLibdispatchQueueAddress() override {
224     return Thread::GetQueueLibdispatchQueueAddress();
225   }
226 
227   /// TODO: this method should take into account the queue override.
SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t)228   void SetQueueLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t) override {
229     Thread::SetQueueLibdispatchQueueAddress(dispatch_queue_t);
230   }
231 
232   /// TODO: this method should take into account the queue override.
ThreadHasQueueInformation()233   bool ThreadHasQueueInformation() const override {
234     return Thread::ThreadHasQueueInformation();
235   }
236 
237   /// TODO: this method should take into account the queue override.
GetAssociatedWithLibdispatchQueue()238   lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override {
239     return Thread::GetAssociatedWithLibdispatchQueue();
240   }
241 
242   /// TODO: this method should take into account the queue override.
SetAssociatedWithLibdispatchQueue(lldb_private::LazyBool associated_with_libdispatch_queue)243   void SetAssociatedWithLibdispatchQueue(
244       lldb_private::LazyBool associated_with_libdispatch_queue) override {
245     Thread::SetAssociatedWithLibdispatchQueue(
246         associated_with_libdispatch_queue);
247   }
248 
GetValueObject()249   lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }
250 
251 protected:
252   lldb::ValueObjectSP m_thread_info_valobj_sp;
253   std::string m_queue;
254 
255 private:
256   ThreadMemoryProvidingNameAndQueue(const ThreadMemoryProvidingNameAndQueue &) =
257       delete;
258   const ThreadMemoryProvidingNameAndQueue &
259   operator=(const ThreadMemoryProvidingNameAndQueue &) = delete;
260 };
261 
262 #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
263