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