aboutsummaryrefslogtreecommitdiff
path: root/lldb/tools/lldb-dap/DAP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/lldb-dap/DAP.cpp')
-rw-r--r--lldb/tools/lldb-dap/DAP.cpp52
1 files changed, 33 insertions, 19 deletions
diff --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index 61226cc..3c4f225 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -26,6 +26,7 @@
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBLanguageRuntime.h"
#include "lldb/API/SBListener.h"
+#include "lldb/API/SBMutex.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/Host/JSONTransport.h"
@@ -266,40 +267,49 @@ void DAP::SendJSON(const llvm::json::Value &json) {
Send(message);
}
-void DAP::Send(const Message &message) {
- if (const protocol::Event *event = std::get_if<protocol::Event>(&message)) {
+Id DAP::Send(const Message &message) {
+ std::lock_guard<std::mutex> guard(call_mutex);
+ Message msg = std::visit(
+ [this](auto &&msg) -> Message {
+ if (msg.seq == kCalculateSeq)
+ msg.seq = seq++;
+ return msg;
+ },
+ Message(message));
+
+ if (const protocol::Event *event = std::get_if<protocol::Event>(&msg)) {
if (llvm::Error err = transport.Send(*event))
DAP_LOG_ERROR(log, std::move(err), "({0}) sending event failed",
m_client_name);
- return;
+ return event->seq;
}
- if (const Request *req = std::get_if<Request>(&message)) {
+ if (const Request *req = std::get_if<Request>(&msg)) {
if (llvm::Error err = transport.Send(*req))
DAP_LOG_ERROR(log, std::move(err), "({0}) sending request failed",
m_client_name);
- return;
+ return req->seq;
}
- if (const Response *resp = std::get_if<Response>(&message)) {
+ if (const Response *resp = std::get_if<Response>(&msg)) {
// FIXME: After all the requests have migrated from LegacyRequestHandler >
// RequestHandler<> this should be handled in RequestHandler<>::operator().
// If the debugger was interrupted, convert this response into a
// 'cancelled' response because we might have a partial result.
- llvm::Error err =
- (debugger.InterruptRequested())
- ? transport.Send({/*request_seq=*/resp->request_seq,
- /*command=*/resp->command,
- /*success=*/false,
- /*message=*/eResponseMessageCancelled,
- /*body=*/std::nullopt})
- : transport.Send(*resp);
- if (err) {
+ llvm::Error err = (debugger.InterruptRequested())
+ ? transport.Send({
+ /*request_seq=*/resp->request_seq,
+ /*command=*/resp->command,
+ /*success=*/false,
+ /*message=*/eResponseMessageCancelled,
+ /*body=*/std::nullopt,
+ /*seq=*/resp->seq,
+ })
+ : transport.Send(*resp);
+ if (err)
DAP_LOG_ERROR(log, std::move(err), "({0}) sending response failed",
m_client_name);
- return;
- }
- return;
+ return resp->seq;
}
llvm_unreachable("Unexpected message type");
@@ -1443,7 +1453,11 @@ void DAP::EventThread() {
const bool remove_module =
event_mask & lldb::SBTarget::eBroadcastBitModulesUnloaded;
- std::lock_guard<std::mutex> guard(modules_mutex);
+ // NOTE: Both mutexes must be acquired to prevent deadlock when
+ // handling `modules_request`, which also requires both locks.
+ lldb::SBMutex api_mutex = GetAPIMutex();
+ const std::scoped_lock<lldb::SBMutex, std::mutex> guard(
+ api_mutex, modules_mutex);
for (uint32_t i = 0; i < num_modules; ++i) {
lldb::SBModule module =
lldb::SBTarget::GetModuleAtIndexFromEvent(i, event);