263 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H11 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 and19/// RegisterContext of the thread, those may query the OS plugin that created20/// the thread.21class ThreadMemory : public lldb_private::Thread {22public: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::RegisterContextSP32 CreateRegisterContextForFrame(lldb_private::StackFrame *frame) override;33 34 bool CalculateStopInfo() override;35 36 const char *GetInfo() override {37 if (m_backing_thread_sp)38 return m_backing_thread_sp->GetInfo();39 return nullptr;40 }41 42 const char *GetName() override {43 if (m_backing_thread_sp)44 return m_backing_thread_sp->GetName();45 return nullptr;46 }47 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 56 void SetQueueName(const char *name) override {57 if (m_backing_thread_sp)58 m_backing_thread_sp->SetQueueName(name);59 }60 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 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 72 lldb::QueueKind GetQueueKind() override {73 if (m_backing_thread_sp)74 return m_backing_thread_sp->GetQueueKind();75 return lldb::eQueueKindUnknown;76 }77 78 void SetQueueKind(lldb::QueueKind kind) override {79 if (m_backing_thread_sp)80 m_backing_thread_sp->SetQueueKind(kind);81 }82 83 lldb::QueueSP GetQueue() override {84 if (m_backing_thread_sp)85 return m_backing_thread_sp->GetQueue();86 return lldb::QueueSP();87 }88 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 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 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 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 113 bool ThreadHasQueueInformation() const override {114 if (m_backing_thread_sp)115 return m_backing_thread_sp->ThreadHasQueueInformation();116 return false;117 }118 119 void DidResume() override {120 if (m_backing_thread_sp)121 m_backing_thread_sp->DidResume();122 }123 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 134 void ClearBackingThread() override {135 if (m_backing_thread_sp)136 m_backing_thread_sp->ClearBackedThread();137 m_backing_thread_sp.reset();138 }139 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 146 lldb::ThreadSP GetBackingThread() const override {147 return m_backing_thread_sp;148 }149 150 bool IsOperatingSystemPluginThread() const override { return true; }151 152private: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.161class ThreadMemoryProvidingName : public ThreadMemory {162public: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 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 176private:177 std::string m_name;178};179 180/// A ThreadMemoryProvidingName that optionally overrides queue information.181class ThreadMemoryProvidingNameAndQueue : public ThreadMemoryProvidingName {182public: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 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.201 void SetQueueName(const char *name) override { Thread::SetQueueName(name); }202 203 /// TODO: this method should take into account the queue override.204 lldb::queue_id_t GetQueueID() override { return Thread::GetQueueID(); }205 206 /// TODO: this method should take into account the queue override.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.212 lldb::QueueKind GetQueueKind() override { return Thread::GetQueueKind(); }213 214 /// TODO: this method should take into account the queue override.215 void SetQueueKind(lldb::QueueKind kind) override {216 Thread::SetQueueKind(kind);217 }218 219 /// TODO: this method should take into account the queue override.220 lldb::QueueSP GetQueue() override { return Thread::GetQueue(); }221 222 /// TODO: this method should take into account the queue override.223 lldb::addr_t GetQueueLibdispatchQueueAddress() override {224 return Thread::GetQueueLibdispatchQueueAddress();225 }226 227 /// TODO: this method should take into account the queue override.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.233 bool ThreadHasQueueInformation() const override {234 return Thread::ThreadHasQueueInformation();235 }236 237 /// TODO: this method should take into account the queue override.238 lldb_private::LazyBool GetAssociatedWithLibdispatchQueue() override {239 return Thread::GetAssociatedWithLibdispatchQueue();240 }241 242 /// TODO: this method should take into account the queue override.243 void SetAssociatedWithLibdispatchQueue(244 lldb_private::LazyBool associated_with_libdispatch_queue) override {245 Thread::SetAssociatedWithLibdispatchQueue(246 associated_with_libdispatch_queue);247 }248 249 lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }250 251protected:252 lldb::ValueObjectSP m_thread_info_valobj_sp;253 std::string m_queue;254 255private:256 ThreadMemoryProvidingNameAndQueue(const ThreadMemoryProvidingNameAndQueue &) =257 delete;258 const ThreadMemoryProvidingNameAndQueue &259 operator=(const ThreadMemoryProvidingNameAndQueue &) = delete;260};261 262#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H263