Skip to content

Commit 2da05a0

Browse files
Merge pull request #10342 from felipepiovezan/felipe/cherrypick_missing_mem
[cherry-pick][lldb] Implement missing queue overloads from ThreadMemory
2 parents 62b5a0f + 16733ed commit 2da05a0

File tree

7 files changed

+254
-42
lines changed

7 files changed

+254
-42
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/OperatingSystem/SwiftTasks/OperatingSystemSwiftTasks.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,9 @@ OperatingSystemSwiftTasks::FindOrCreateSwiftThread(ThreadList &old_thread_list,
9393
return old_thread;
9494

9595
std::string name = llvm::formatv("Swift Task {0}", task_id);
96-
llvm::StringRef queue_name = "";
97-
return std::make_shared<ThreadMemory>(*m_process, masked_task_id, name,
98-
queue_name,
99-
/*register_data_addr*/ 0);
96+
return std::make_shared<ThreadMemoryProvidingName>(*m_process, masked_task_id,
97+
/*register_data_addr*/ 0,
98+
name);
10099
}
101100

102101
bool OperatingSystemSwiftTasks::UpdateThreadList(ThreadList &old_thread_list,

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: 174 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,23 +40,82 @@ 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;
5452
}
5553

5654
void WillResume(lldb::StateType resume_state) override;
5755

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+
58119
void DidResume() override {
59120
if (m_backing_thread_sp)
60121
m_backing_thread_sp->DidResume();
@@ -68,8 +129,6 @@ class ThreadMemory : public lldb_private::Thread {
68129

69130
void RefreshStateAfterStop() override;
70131

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

75134
void ClearBackingThread() override {
@@ -79,34 +138,125 @@ class ThreadMemory : public lldb_private::Thread {
79138
}
80139

81140
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());
84141
m_backing_thread_sp = thread_sp;
85142
thread_sp->SetBackedThread(*this);
86-
return (bool)thread_sp;
143+
return thread_sp.get();
87144
}
88145

89146
lldb::ThreadSP GetBackingThread() const override {
90147
return m_backing_thread_sp;
91148
}
92149

93-
protected:
94150
bool IsOperatingSystemPluginThread() const override { return true; }
95151

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.
152+
private:
153+
lldb::addr_t m_register_data_addr;
101154
lldb::ThreadSP m_backing_thread_sp;
102-
lldb::ValueObjectSP m_thread_info_valobj_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:
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+
176+
private:
103177
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+
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+
251+
protected:
252+
lldb::ValueObjectSP m_thread_info_valobj_sp;
104253
std::string m_queue;
105-
lldb::addr_t m_register_data_addr;
106254

107255
private:
108-
ThreadMemory(const ThreadMemory &) = delete;
109-
const ThreadMemory &operator=(const ThreadMemory &) = delete;
256+
ThreadMemoryProvidingNameAndQueue(const ThreadMemoryProvidingNameAndQueue &) =
257+
delete;
258+
const ThreadMemoryProvidingNameAndQueue &
259+
operator=(const ThreadMemoryProvidingNameAndQueue &) = delete;
110260
};
111261

112262
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_THREADMEMORY_H
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -parse-as-library
3+
include Makefile.rules
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
import re
6+
7+
8+
class TestCase(lldbtest.TestBase):
9+
@swiftTest
10+
@skipIf(oslist=["windows", "linux"])
11+
def test(self):
12+
"""Test `frame variable` in async functions"""
13+
self.build()
14+
15+
self.runCmd("settings set target.experimental.swift-tasks-plugin-enabled true")
16+
17+
source_file = lldb.SBFileSpec("main.swift")
18+
target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(
19+
self, "BREAK HERE", source_file
20+
)
21+
22+
self.assertIn("Swift Task", thread.GetName())
23+
24+
queue_plugin = self.get_queue_from_thread_info_command(False)
25+
queue_backing = self.get_queue_from_thread_info_command(True)
26+
self.assertEqual(queue_plugin, queue_backing)
27+
self.assertEqual(queue_plugin, thread.GetQueueName())
28+
29+
num_queues = process.GetNumQueues()
30+
self.assertEqual(num_queues, 1)
31+
32+
queue_regex = re.compile(r"queue = '([^']+)'")
33+
34+
def get_queue_from_thread_info_command(self, use_backing_thread):
35+
interp = self.dbg.GetCommandInterpreter()
36+
result = lldb.SBCommandReturnObject()
37+
38+
backing_thread_arg = ""
39+
if use_backing_thread:
40+
backing_thread_arg = "--backing-thread"
41+
42+
interp.HandleCommand(
43+
"thread info {0}".format(backing_thread_arg),
44+
result,
45+
True,
46+
)
47+
self.assertTrue(result.Succeeded(), "failed to run thread info")
48+
match = self.queue_regex.search(result.GetOutput())
49+
self.assertNotEqual(match, None)
50+
return match.group(1)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
func async_foo() async -> Int {
2+
var myvar = 111; // BREAK HERE
3+
return myvar
4+
}
5+
6+
@main struct Main {
7+
static func main() async {
8+
let result = await async_foo()
9+
print(result)
10+
}
11+
}

0 commit comments

Comments
 (0)