Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 3, 2025

Conversation

JDevlieghere
Copy link
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
Copy link
Member

llvmbot commented Apr 2, 2025

@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);

Copy link
Contributor

@ashgti ashgti left a comment

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
13 checks passed
@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.
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