Skip to content

Commit 65ad02b

Browse files
[lldb][NFC] Break ThreadMemory into smaller abstractions (llvm#132905)
ThreadMemory attempts to be a class abstracting the notion of a "fake" Thread that is backed by a "real" thread. According to its documentation, it is meant to be a class forwarding most methods to the backing thread, but it does so only for a handful of methods. Along the way, it also tries to represent a Thread that may or may not have a different name, and may or may not have a different queue from the backing thread. This can be problematic for a couple of reasons: 1. It forces all users into this optional behavior. 2. The forwarding behavior is incomplete: not all methods are currently being forwarded properly. Some of them involve queues and seem to have been intentionally left unimplemented. This commit creates the following separation: ThreadMemory <- ThreadMemoryProvidingName <- ThreadMemoryProvidingNameAndQueue ThreadMemory captures the notion of a backed thread that _really_ forwards all methods to the backing thread. (Missing methods should be implemented in a later commit, and allowing them to be implemented without changing behavior of other derived classes is the main purpose of this refactor). ThreadMemoryProvidingNameAndQueue is a ThreadMemory that allows users to override the thread name. If a name is present, it is used; otherwise the forwarding behavior is used. ThreadMemoryProvidingNameAndQueue is a ThreadMemoryProvidingName that allows users to override queue information. If queue information is present, it is used; otherwise, the forwarding behavior is used. With this separation, we can more explicitly implement missing methods of the base class and override them, if needed, in ThreadMemoryProvidingNameAndQueue. But this commit really is NFC, no new methods are implemented and no method implementation is changed.
1 parent e6e8252 commit 65ad02b

File tree

3 files changed

+75
-38
lines changed

3 files changed

+75
-38
lines changed

lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,8 @@ ThreadSP OperatingSystemPython::CreateThreadFromThreadInfo(
259259
if (!thread_sp) {
260260
if (did_create_ptr)
261261
*did_create_ptr = true;
262-
thread_sp = std::make_shared<ThreadMemory>(*m_process, tid, name, queue,
263-
reg_data_addr);
262+
thread_sp = std::make_shared<ThreadMemoryProvidingNameAndQueue>(
263+
*m_process, tid, name, queue, reg_data_addr);
264264
}
265265

266266
if (core_number < core_thread_list.GetSize(false)) {

lldb/source/Plugins/Process/Utility/ThreadMemory.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,17 @@
2020
using namespace lldb;
2121
using namespace lldb_private;
2222

23-
ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid,
24-
const ValueObjectSP &thread_info_valobj_sp)
25-
: Thread(process, tid), m_backing_thread_sp(),
26-
m_thread_info_valobj_sp(thread_info_valobj_sp), m_name(), m_queue(),
27-
m_register_data_addr(LLDB_INVALID_ADDRESS) {}
28-
29-
ThreadMemory::ThreadMemory(Process &process, lldb::tid_t tid,
30-
llvm::StringRef name, llvm::StringRef queue,
31-
lldb::addr_t register_data_addr)
32-
: Thread(process, tid), m_backing_thread_sp(), m_thread_info_valobj_sp(),
33-
m_name(std::string(name)), m_queue(std::string(queue)),
34-
m_register_data_addr(register_data_addr) {}
23+
ThreadMemoryProvidingNameAndQueue::ThreadMemoryProvidingNameAndQueue(
24+
Process &process, lldb::tid_t tid,
25+
const ValueObjectSP &thread_info_valobj_sp)
26+
: ThreadMemoryProvidingName(process, tid, LLDB_INVALID_ADDRESS, ""),
27+
m_thread_info_valobj_sp(thread_info_valobj_sp), m_queue() {}
28+
29+
ThreadMemoryProvidingNameAndQueue::ThreadMemoryProvidingNameAndQueue(
30+
Process &process, lldb::tid_t tid, llvm::StringRef name,
31+
llvm::StringRef queue, lldb::addr_t register_data_addr)
32+
: ThreadMemoryProvidingName(process, tid, register_data_addr, name),
33+
m_thread_info_valobj_sp(), m_queue(std::string(queue)) {}
3534

3635
ThreadMemory::~ThreadMemory() { DestroyThread(); }
3736

lldb/source/Plugins/Process/Utility/ThreadMemory.h

Lines changed: 62 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@
1313

1414
#include "lldb/Target/Thread.h"
1515

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.
1621
class ThreadMemory : public lldb_private::Thread {
1722
public:
1823
ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
19-
const lldb::ValueObjectSP &thread_info_valobj_sp);
20-
21-
ThreadMemory(lldb_private::Process &process, lldb::tid_t tid,
22-
llvm::StringRef name, llvm::StringRef queue,
23-
lldb::addr_t register_data_addr);
24+
lldb::addr_t register_data_addr)
25+
: Thread(process, tid), m_register_data_addr(register_data_addr) {}
2426

2527
~ThreadMemory() override;
2628

@@ -38,16 +40,12 @@ class ThreadMemory : public lldb_private::Thread {
3840
}
3941

4042
const char *GetName() override {
41-
if (!m_name.empty())
42-
return m_name.c_str();
4343
if (m_backing_thread_sp)
4444
return m_backing_thread_sp->GetName();
4545
return nullptr;
4646
}
4747

4848
const char *GetQueueName() override {
49-
if (!m_queue.empty())
50-
return m_queue.c_str();
5149
if (m_backing_thread_sp)
5250
return m_backing_thread_sp->GetQueueName();
5351
return nullptr;
@@ -68,8 +66,6 @@ class ThreadMemory : public lldb_private::Thread {
6866

6967
void RefreshStateAfterStop() override;
7068

71-
lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }
72-
7369
void ClearStackFrames() override;
7470

7571
void ClearBackingThread() override {
@@ -79,34 +75,76 @@ class ThreadMemory : public lldb_private::Thread {
7975
}
8076

8177
bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
82-
// printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(),
83-
// thread_sp->GetID());
8478
m_backing_thread_sp = thread_sp;
8579
thread_sp->SetBackedThread(*this);
86-
return (bool)thread_sp;
80+
return thread_sp.get();
8781
}
8882

8983
lldb::ThreadSP GetBackingThread() const override {
9084
return m_backing_thread_sp;
9185
}
9286

93-
protected:
9487
bool IsOperatingSystemPluginThread() const override { return true; }
9588

96-
// If this memory thread is actually represented by a thread from the
97-
// lldb_private::Process subclass, then fill in the thread here and
98-
// all APIs will be routed through this thread object. If m_backing_thread_sp
99-
// is empty, then this thread is simply in memory with no representation
100-
// through the process plug-in.
89+
private:
90+
lldb::addr_t m_register_data_addr;
10191
lldb::ThreadSP m_backing_thread_sp;
102-
lldb::ValueObjectSP m_thread_info_valobj_sp;
92+
93+
ThreadMemory(const ThreadMemory &) = delete;
94+
const ThreadMemory &operator=(const ThreadMemory &) = delete;
95+
};
96+
97+
/// A ThreadMemory that optionally overrides the thread name.
98+
class ThreadMemoryProvidingName : public ThreadMemory {
99+
public:
100+
ThreadMemoryProvidingName(lldb_private::Process &process, lldb::tid_t tid,
101+
lldb::addr_t register_data_addr,
102+
llvm::StringRef name)
103+
: ThreadMemory(process, tid, register_data_addr), m_name(name) {}
104+
105+
const char *GetName() override {
106+
if (!m_name.empty())
107+
return m_name.c_str();
108+
return ThreadMemory::GetName();
109+
}
110+
111+
~ThreadMemoryProvidingName() override = default;
112+
113+
private:
103114
std::string m_name;
115+
};
116+
117+
/// A ThreadMemoryProvidingName that optionally overrides queue information.
118+
class ThreadMemoryProvidingNameAndQueue : public ThreadMemoryProvidingName {
119+
public:
120+
ThreadMemoryProvidingNameAndQueue(
121+
lldb_private::Process &process, lldb::tid_t tid,
122+
const lldb::ValueObjectSP &thread_info_valobj_sp);
123+
124+
ThreadMemoryProvidingNameAndQueue(lldb_private::Process &process,
125+
lldb::tid_t tid, llvm::StringRef name,
126+
llvm::StringRef queue,
127+
lldb::addr_t register_data_addr);
128+
129+
~ThreadMemoryProvidingNameAndQueue() override = default;
130+
131+
const char *GetQueueName() override {
132+
if (!m_queue.empty())
133+
return m_queue.c_str();
134+
return ThreadMemory::GetQueueName();
135+
}
136+
137+
lldb::ValueObjectSP &GetValueObject() { return m_thread_info_valobj_sp; }
138+
139+
protected:
140+
lldb::ValueObjectSP m_thread_info_valobj_sp;
104141
std::string m_queue;
105-
lldb::addr_t m_register_data_addr;
106142

107143
private:
108-
ThreadMemory(const ThreadMemory &) = delete;
109-
const ThreadMemory &operator=(const ThreadMemory &) = delete;
144+
ThreadMemoryProvidingNameAndQueue(const ThreadMemoryProvidingNameAndQueue &) =
145+
delete;
146+
const ThreadMemoryProvidingNameAndQueue &
147+
operator=(const ThreadMemoryProvidingNameAndQueue &) = delete;
110148
};
111149

112150
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H

0 commit comments

Comments
 (0)