[Lldb-commits] [lldb] 0adf9b6 - [lldb-dap] Address a race condition in server mode. (#191062)

via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 10 08:48:48 PDT 2026


Author: John Harrison
Date: 2026-04-10T08:48:42-07:00
New Revision: 0adf9b6f33d12e99284db70a1aef485fa6cabe3c

URL: https://github.com/llvm/llvm-project/commit/0adf9b6f33d12e99284db70a1aef485fa6cabe3c
DIFF: https://github.com/llvm/llvm-project/commit/0adf9b6f33d12e99284db70a1aef485fa6cabe3c.diff

LOG: [lldb-dap] Address a race condition in server mode. (#191062)

While running in server mode, multiple clients can be connected at the
same time. In LLDBUtils we had a static mutex that can cause other
clients to hang due to the single static lock.

Instead, I adjusted the logic to take the existing SBMutex as a paremter
and guard that mutex during command handling.

Added: 
    

Modified: 
    lldb/tools/lldb-dap/DAP.cpp
    lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
    lldb/tools/lldb-dap/LLDBUtils.cpp
    lldb/tools/lldb-dap/LLDBUtils.h

Removed: 
    


################################################################################
diff  --git a/lldb/tools/lldb-dap/DAP.cpp b/lldb/tools/lldb-dap/DAP.cpp
index f1ebe9b316496..7b58fca0f8163 100644
--- a/lldb/tools/lldb-dap/DAP.cpp
+++ b/lldb/tools/lldb-dap/DAP.cpp
@@ -704,7 +704,7 @@ bool DAP::RunLLDBCommands(llvm::StringRef prefix,
                           llvm::ArrayRef<String> commands) {
   bool required_command_failed = false;
   std::string output = ::RunLLDBCommands(
-      debugger, prefix, commands, required_command_failed,
+      debugger, GetAPIMutex(), prefix, commands, required_command_failed,
       /*parse_command_directives*/ true, /*echo_commands*/ true);
   SendOutput(OutputType::Console, output);
   return !required_command_failed;

diff  --git a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
index 906f262779e1d..7537eca72ec25 100644
--- a/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
+++ b/lldb/tools/lldb-dap/Handler/EvaluateRequestHandler.cpp
@@ -93,7 +93,8 @@ EvaluateRequestHandler::Run(const EvaluateArguments &arguments) const {
 
     bool required_command_failed = false;
     body.result = RunLLDBCommands(
-        dap.debugger, llvm::StringRef(), {expression}, required_command_failed,
+        dap.debugger, dap.GetAPIMutex(), llvm::StringRef(), {expression},
+        required_command_failed,
         /*parse_command_directives=*/false, /*echo_commands=*/false);
     return body;
   }

diff  --git a/lldb/tools/lldb-dap/LLDBUtils.cpp b/lldb/tools/lldb-dap/LLDBUtils.cpp
index 95eb85b7f2226..826598f260ef5 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.cpp
+++ b/lldb/tools/lldb-dap/LLDBUtils.cpp
@@ -13,6 +13,7 @@
 #include "lldb/API/SBCommandReturnObject.h"
 #include "lldb/API/SBDebugger.h"
 #include "lldb/API/SBFrame.h"
+#include "lldb/API/SBMutex.h"
 #include "lldb/API/SBStringList.h"
 #include "lldb/API/SBStructuredData.h"
 #include "lldb/API/SBThread.h"
@@ -31,10 +32,10 @@
 
 namespace lldb_dap {
 
-bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
-                     const llvm::ArrayRef<protocol::String> &commands,
-                     llvm::raw_ostream &strm, bool parse_command_directives,
-                     bool echo_commands) {
+static bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
+                            const llvm::ArrayRef<protocol::String> &commands,
+                            llvm::raw_ostream &strm,
+                            bool parse_command_directives, bool echo_commands) {
   if (commands.empty())
     return true;
 
@@ -74,15 +75,8 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
       }
     }
 
-    {
-      // Prevent simultaneous calls to HandleCommand, e.g. EventThreadFunction
-      // may asynchronously call RunExitCommands when we are already calling
-      // RunTerminateCommands.
-      static std::mutex handle_command_mutex;
-      std::lock_guard<std::mutex> locker(handle_command_mutex);
-      interp.HandleCommand(command.str().c_str(), result,
-                           /*add_to_history=*/true);
-    }
+    interp.HandleCommand(command.str().c_str(), result,
+                         /*add_to_history=*/true);
 
     const bool got_error = !result.Succeeded();
     // The if statement below is assuming we always print out `!` prefixed
@@ -114,10 +108,13 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
   return true;
 }
 
-std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
+std::string RunLLDBCommands(lldb::SBDebugger &debugger, lldb::SBMutex mutex,
+                            llvm::StringRef prefix,
                             const llvm::ArrayRef<protocol::String> &commands,
                             bool &required_command_failed,
                             bool parse_command_directives, bool echo_commands) {
+  // Ensure a single command is evaluated at a time.
+  std::lock_guard<lldb::SBMutex> guard(mutex);
   required_command_failed = false;
   std::string s;
   llvm::raw_string_ostream strm(s);

diff  --git a/lldb/tools/lldb-dap/LLDBUtils.h b/lldb/tools/lldb-dap/LLDBUtils.h
index 3565b398160e7..30882b75fa359 100644
--- a/lldb/tools/lldb-dap/LLDBUtils.h
+++ b/lldb/tools/lldb-dap/LLDBUtils.h
@@ -28,46 +28,6 @@
 
 namespace lldb_dap {
 
-/// Run a list of LLDB commands in the LLDB command interpreter.
-///
-/// All output from every command, including the prompt + the command
-/// is placed into the "strm" argument.
-///
-/// Each individual command can be prefixed with \b ! and/or \b ? in no
-/// particular order. If \b ? is provided, then the output of that command is
-/// only emitted if it fails, and if \b ! is provided, then the output is
-/// emitted regardless, and \b false is returned without executing the
-/// remaining commands.
-///
-/// \param[in] debugger
-///     The debugger that will execute the lldb commands.
-///
-/// \param[in] prefix
-///     A string that will be printed into \a strm prior to emitting
-///     the prompt + command and command output. Can be NULL.
-///
-/// \param[in] commands
-///     An array of LLDB commands to execute.
-///
-/// \param[in] strm
-///     The stream that will receive the prefix, prompt + command and
-///     all command output.
-///
-/// \param[in] parse_command_directives
-///     If \b false, then command prefixes like \b ! or \b ? are not parsed and
-///     each command is executed verbatim.
-///
-/// \param[in] echo_commands
-///     If \b true, the command are echoed to the stream.
-///
-/// \return
-///     \b true, unless a command prefixed with \b ! fails and parsing of
-///     command directives is enabled.
-bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
-                     const llvm::ArrayRef<protocol::String> &commands,
-                     llvm::raw_ostream &strm, bool parse_command_directives,
-                     bool echo_commands);
-
 /// Run a list of LLDB commands in the LLDB command interpreter.
 ///
 /// All output from every command, including the prompt + the command
@@ -76,6 +36,9 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
 /// \param[in] debugger
 ///     The debugger that will execute the lldb commands.
 ///
+/// \param[in] mutex
+///     The mutex protecting this target.
+///
 /// \param[in] prefix
 ///     A string that will be printed into \a strm prior to emitting
 ///     the prompt + command and command output. Can be NULL.
@@ -97,7 +60,8 @@ bool RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
 /// \return
 ///     A std::string that contains the prefix and all commands and
 ///     command output.
-std::string RunLLDBCommands(lldb::SBDebugger &debugger, llvm::StringRef prefix,
+std::string RunLLDBCommands(lldb::SBDebugger &debugger, lldb::SBMutex mutex,
+                            llvm::StringRef prefix,
                             const llvm::ArrayRef<protocol::String> &commands,
                             bool &required_command_failed,
                             bool parse_command_directives = true,


        


More information about the lldb-commits mailing list