Skip to content

Commit 9618197

Browse files
committed
[lldb-dap] Client expects initial threads request not empty
1 parent 2f8dc76 commit 9618197

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,13 +649,17 @@ def request_configurationDone(self):
649649
response = self.send_recv(command_dict)
650650
if response:
651651
self.configuration_done_sent = True
652+
# Client requests the baseline of currently existing threads after
653+
# a successful launch or attach.
654+
# Kick off the threads request that follows
655+
self.request_threads()
652656
return response
653657

654658
def _process_stopped(self):
655659
self.threads = None
656660
self.frame_scopes = {}
657661

658-
def request_continue(self, threadId=None):
662+
def request_continue(self, threadId=None):
659663
if self.exit_status is not None:
660664
raise ValueError("request_continue called after process exited")
661665
# If we have launched or attached, then the first continue is done by

lldb/tools/lldb-dap/DAP.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ struct DAP {
207207
/// The set of features supported by the connected client.
208208
llvm::DenseSet<ClientFeature> clientFeatures;
209209

210+
/// The initial thread list upon attaching
211+
std::optional<llvm::json::Array> initial_thread_list;
212+
210213
/// Creates a new DAP sessions.
211214
///
212215
/// \param[in] log

lldb/tools/lldb-dap/Handler/ConfigurationDoneRequestHandler.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,18 @@ namespace lldb_dap {
4444
// just an acknowledgement, so no body field is required."
4545
// }]
4646
// },
47+
48+
llvm::json::Array CacheInitialThreads(DAP &dap) {
49+
llvm::json::Array threads;
50+
lldb::SBProcess process = dap.target.GetProcess();
51+
const uint32_t num_threads = process.GetNumThreads();
52+
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
53+
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
54+
threads.emplace_back(CreateThread(thread, dap.thread_format));
55+
}
56+
return threads;
57+
}
58+
4759
void ConfigurationDoneRequestHandler::operator()(
4860
const llvm::json::Object &request) const {
4961
llvm::json::Object response;
@@ -52,8 +64,14 @@ void ConfigurationDoneRequestHandler::operator()(
5264
dap.configuration_done_sent = true;
5365
if (dap.stop_at_entry)
5466
SendThreadStoppedEvent(dap);
55-
else
67+
else {
68+
// Client requests the baseline of currently existing threads after
69+
// a successful launch or attach.
70+
// A 'threads' request will be sent after configurationDone response
71+
// Obtain the list of threads before we resume the process
72+
dap.initial_thread_list = CacheInitialThreads(dap);
5673
dap.target.GetProcess().Continue();
74+
}
5775
}
5876

5977
} // namespace lldb_dap

lldb/tools/lldb-dap/Handler/ThreadsRequestHandler.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,26 @@ namespace lldb_dap {
5050
// }
5151
void ThreadsRequestHandler::operator()(
5252
const llvm::json::Object &request) const {
53-
lldb::SBProcess process = dap.target.GetProcess();
5453
llvm::json::Object response;
5554
FillResponse(request, response);
5655

57-
const uint32_t num_threads = process.GetNumThreads();
5856
llvm::json::Array threads;
59-
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
60-
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
61-
threads.emplace_back(CreateThread(thread, dap.thread_format));
57+
// Client requests the baseline of currently existing threads after
58+
// a successful launch or attach.
59+
// A 'threads' request will be sent after configurationDone response.
60+
// Return the cache of initial threads as process might have resumed
61+
if (dap.initial_thread_list) {
62+
threads = dap.initial_thread_list.value();
63+
dap.initial_thread_list.reset();
64+
} else {
65+
lldb::SBProcess process = dap.target.GetProcess();
66+
const uint32_t num_threads = process.GetNumThreads();
67+
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
68+
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
69+
threads.emplace_back(CreateThread(thread, dap.thread_format));
70+
}
6271
}
72+
6373
if (threads.size() == 0) {
6474
response["success"] = llvm::json::Value(false);
6575
}

0 commit comments

Comments
 (0)