Skip to content

Commit 13f7249

Browse files
committed
[lldb-dap] Client expects initial threads request not empty
1 parent 4f0ac25 commit 13f7249

File tree

6 files changed

+40
-7
lines changed

6 files changed

+40
-7
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,10 @@ 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):

lldb/tools/lldb-dap/DAP.h

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

214+
/// The initial thread list upon attaching
215+
std::optional<llvm::json::Array> initial_thread_list;
216+
214217
/// Creates a new DAP sessions.
215218
///
216219
/// \param[in] log

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ namespace lldb_dap {
4444
// just an acknowledgement, so no body field is required."
4545
// }]
4646
// },
47+
4748
void ConfigurationDoneRequestHandler::operator()(
4849
const llvm::json::Object &request) const {
4950
llvm::json::Object response;
@@ -52,8 +53,15 @@ void ConfigurationDoneRequestHandler::operator()(
5253
dap.configuration_done_sent = true;
5354
if (dap.stop_at_entry)
5455
SendThreadStoppedEvent(dap);
55-
else
56+
else {
57+
// Client requests the baseline of currently existing threads after
58+
// a successful launch or attach by sending a 'threads' request
59+
// right after receiving the configurationDone response.
60+
// Obtain the list of threads before we resume the process
61+
dap.initial_thread_list =
62+
GetThreads(dap.target.GetProcess(), dap.thread_format);
5663
dap.target.GetProcess().Continue();
64+
}
5765
}
5866

5967
} // namespace lldb_dap

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,22 @@ 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));
62-
}
57+
// Client requests the baseline of currently existing threads after
58+
// a successful launch or attach by sending a 'threads' request
59+
// right after receiving the configurationDone response.
60+
// If no thread has reported to the client, it prevents something
61+
// like the pause request from working in the running state.
62+
// Return the cache of initial threads as the process might have resumed
63+
if (dap.initial_thread_list) {
64+
threads = dap.initial_thread_list.value();
65+
dap.initial_thread_list.reset();
66+
} else
67+
threads = GetThreads(dap.target.GetProcess(), dap.thread_format);
68+
6369
if (threads.size() == 0) {
6470
response["success"] = llvm::json::Value(false);
6571
}

lldb/tools/lldb-dap/JSONUtils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,16 @@ llvm::json::Value CreateThread(lldb::SBThread &thread, lldb::SBFormat &format) {
870870
return llvm::json::Value(std::move(object));
871871
}
872872

873+
llvm::json::Array GetThreads(lldb::SBProcess process, lldb::SBFormat &format) {
874+
llvm::json::Array threads;
875+
const uint32_t num_threads = process.GetNumThreads();
876+
for (uint32_t thread_idx = 0; thread_idx < num_threads; ++thread_idx) {
877+
lldb::SBThread thread = process.GetThreadAtIndex(thread_idx);
878+
threads.emplace_back(CreateThread(thread, format));
879+
}
880+
return threads;
881+
}
882+
873883
// "StoppedEvent": {
874884
// "allOf": [ { "$ref": "#/definitions/Event" }, {
875885
// "type": "object",

lldb/tools/lldb-dap/JSONUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ llvm::json::Value CreateExtendedStackFrameLabel(lldb::SBThread &thread,
414414
/// definition outlined by Microsoft.
415415
llvm::json::Value CreateThread(lldb::SBThread &thread, lldb::SBFormat &format);
416416

417+
llvm::json::Array GetThreads(lldb::SBProcess process, lldb::SBFormat &format);
418+
417419
/// Create a "StoppedEvent" object for a LLDB thread object.
418420
///
419421
/// This function will fill in the following keys in the returned

0 commit comments

Comments
 (0)