Skip to content

[lldb-dap] Protect SetBreakpoint with the API mutex - #134030

Merged
JDevlieghere merged 1 commit into
llvm:mainfrom
JDevlieghere:lldb-dap-race
Apr 3, 2025
Merged

[lldb-dap] Protect SetBreakpoint with the API mutex#134030
JDevlieghere merged 1 commit into
llvm:mainfrom
JDevlieghere:lldb-dap-race

Conversation

@JDevlieghere

Copy link
Copy Markdown
Member

Protect the various SetBreakpoint functions with the API mutex. This fixes a race condition between the breakpoint being created and the DAP label getting added. This was causing TestDAP_breakpointEvents.py to be flaky.

Fixes #131242.

Protect the various SetBreakpoint functions with the API mutex. This
fixes a race condition between the breakpoint being created and the DAP
label getting added. This was causing `TestDAP_breakpointEvents.py` to
be flaky.

Fixes llvm#131242.
@llvmbot

llvmbot commented Apr 2, 2025

Copy link
Copy Markdown
Member

@llvm/pr-subscribers-lldb

Author: Jonas Devlieghere (JDevlieghere)

Changes

Protect the various SetBreakpoint functions with the API mutex. This fixes a race condition between the breakpoint being created and the DAP label getting added. This was causing TestDAP_breakpointEvents.py to be flaky.

Fixes #131242.


Full diff: https://github.com/llvm/llvm-project/pull/134030.diff

5 Files Affected:

  • (modified) lldb/tools/lldb-dap/Breakpoint.cpp (+6)
  • (modified) lldb/tools/lldb-dap/DAP.h (+3)
  • (modified) lldb/tools/lldb-dap/ExceptionBreakpoint.cpp (+5)
  • (modified) lldb/tools/lldb-dap/FunctionBreakpoint.cpp (+5)
  • (modified) lldb/tools/lldb-dap/SourceBreakpoint.cpp (+5)
diff --git a/lldb/tools/lldb-dap/Breakpoint.cpp b/lldb/tools/lldb-dap/Breakpoint.cpp
index e02f62076f935..5679fd545d53f 100644
--- a/lldb/tools/lldb-dap/Breakpoint.cpp
+++ b/lldb/tools/lldb-dap/Breakpoint.cpp
@@ -7,14 +7,17 @@
 //===----------------------------------------------------------------------===//
 
 #include "Breakpoint.h"
+#include "DAP.h"
 #include "JSONUtils.h"
 #include "lldb/API/SBAddress.h"
 #include "lldb/API/SBBreakpointLocation.h"
 #include "lldb/API/SBLineEntry.h"
+#include "lldb/API/SBMutex.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/JSON.h"
 #include <cstddef>
 #include <cstdint>
+#include <mutex>
 #include <string>
 
 using namespace lldb_dap;
@@ -74,6 +77,9 @@ bool Breakpoint::MatchesName(const char *name) {
 }
 
 void Breakpoint::SetBreakpoint() {
+  lldb::SBMutex lock = m_dap.GetAPIMutex();
+  std::lock_guard<lldb::SBMutex> guard(lock);
+
   m_bp.AddName(kDAPBreakpointLabel);
   if (!m_condition.empty())
     SetCondition();
diff --git a/lldb/tools/lldb-dap/DAP.h b/lldb/tools/lldb-dap/DAP.h
index 4357bdd5cc80f..3ce6498632479 100644
--- a/lldb/tools/lldb-dap/DAP.h
+++ b/lldb/tools/lldb-dap/DAP.h
@@ -27,6 +27,7 @@
 #include "lldb/API/SBFile.h"
 #include "lldb/API/SBFormat.h"
 #include "lldb/API/SBFrame.h"
+#include "lldb/API/SBMutex.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBValue.h"
@@ -404,6 +405,8 @@ struct DAP {
   InstructionBreakpoint *GetInstructionBreakpoint(const lldb::break_id_t bp_id);
 
   InstructionBreakpoint *GetInstructionBPFromStopReason(lldb::SBThread &thread);
+
+  lldb::SBMutex GetAPIMutex() const { return target.GetAPIMutex(); }
 };
 
 } // namespace lldb_dap
diff --git a/lldb/tools/lldb-dap/ExceptionBreakpoint.cpp b/lldb/tools/lldb-dap/ExceptionBreakpoint.cpp
index d8109daf89129..9772e7344ced6 100644
--- a/lldb/tools/lldb-dap/ExceptionBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/ExceptionBreakpoint.cpp
@@ -9,11 +9,16 @@
 #include "ExceptionBreakpoint.h"
 #include "BreakpointBase.h"
 #include "DAP.h"
+#include "lldb/API/SBMutex.h"
 #include "lldb/API/SBTarget.h"
+#include <mutex>
 
 namespace lldb_dap {
 
 void ExceptionBreakpoint::SetBreakpoint() {
+  lldb::SBMutex lock = m_dap.GetAPIMutex();
+  std::lock_guard<lldb::SBMutex> guard(lock);
+
   if (m_bp.IsValid())
     return;
   bool catch_value = m_filter.find("_catch") != std::string::npos;
diff --git a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
index 2fb6e8fafc2fa..d87723f7557bd 100644
--- a/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/FunctionBreakpoint.cpp
@@ -9,6 +9,8 @@
 #include "FunctionBreakpoint.h"
 #include "DAP.h"
 #include "JSONUtils.h"
+#include "lldb/API/SBMutex.h"
+#include <mutex>
 
 namespace lldb_dap {
 
@@ -17,6 +19,9 @@ FunctionBreakpoint::FunctionBreakpoint(DAP &d, const llvm::json::Object &obj)
       m_function_name(std::string(GetString(obj, "name").value_or(""))) {}
 
 void FunctionBreakpoint::SetBreakpoint() {
+  lldb::SBMutex lock = m_dap.GetAPIMutex();
+  std::lock_guard<lldb::SBMutex> guard(lock);
+
   if (m_function_name.empty())
     return;
   m_bp = m_dap.target.BreakpointCreateByName(m_function_name.c_str());
diff --git a/lldb/tools/lldb-dap/SourceBreakpoint.cpp b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
index 150fa6af44d3a..6d8d3470668c8 100644
--- a/lldb/tools/lldb-dap/SourceBreakpoint.cpp
+++ b/lldb/tools/lldb-dap/SourceBreakpoint.cpp
@@ -13,6 +13,7 @@
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBFileSpecList.h"
 #include "lldb/API/SBFrame.h"
+#include "lldb/API/SBMutex.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
 #include "lldb/API/SBValue.h"
@@ -20,6 +21,7 @@
 #include <cassert>
 #include <cctype>
 #include <cstdlib>
+#include <mutex>
 #include <utility>
 
 namespace lldb_dap {
@@ -33,6 +35,9 @@ SourceBreakpoint::SourceBreakpoint(DAP &dap, const llvm::json::Object &obj)
                    .value_or(LLDB_INVALID_COLUMN_NUMBER)) {}
 
 void SourceBreakpoint::SetBreakpoint(const llvm::StringRef source_path) {
+  lldb::SBMutex lock = m_dap.GetAPIMutex();
+  std::lock_guard<lldb::SBMutex> guard(lock);
+
   lldb::SBFileSpecList module_list;
   m_bp = m_dap.target.BreakpointCreateByLocation(
       source_path.str().c_str(), m_line, m_column, 0, module_list);

@ashgti ashgti left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@JDevlieghere
JDevlieghere merged commit bec5cfd into llvm:main Apr 3, 2025
@JDevlieghere
JDevlieghere deleted the lldb-dap-race branch April 3, 2025 16:08
JDevlieghere added a commit to swiftlang/llvm-project that referenced this pull request Apr 8, 2025
…ckport)

Protect the various SetBreakpoint functions with the API mutex. This
fixes a race condition between the breakpoint being created and the DAP
label getting added. This was causing `TestDAP_breakpointEvents.py` to
be flaky.

Fixes llvm#131242.
DrSergei added a commit that referenced this pull request Jun 1, 2026
Added mutex like in other breakpoints
([PR](#134030)). Also removed
unused `m_offset` field.
llvm-upstreamsync Bot pushed a commit to qualcomm/cpullvm-toolchain that referenced this pull request Jun 1, 2026
Added mutex like in other breakpoints
([PR](llvm/llvm-project#134030)). Also removed
unused `m_offset` field.
llvm-sync Bot pushed a commit to arm/arm-toolchain that referenced this pull request Jun 1, 2026
Added mutex like in other breakpoints
([PR](llvm/llvm-project#134030)). Also removed
unused `m_offset` field.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[lldb-dap] Race condition in the event handler thread

3 participants