https://github.com/JDevlieghere created 
https://github.com/llvm/llvm-project/pull/134030

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.

>From 156738dda4441e511ce4cff65fab3d0225b4c39c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Tue, 1 Apr 2025 22:19:09 -0700
Subject: [PATCH] [lldb-dap] Protect SetBreakpoint with the API mutex

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.
---
 lldb/tools/lldb-dap/Breakpoint.cpp          | 6 ++++++
 lldb/tools/lldb-dap/DAP.h                   | 3 +++
 lldb/tools/lldb-dap/ExceptionBreakpoint.cpp | 5 +++++
 lldb/tools/lldb-dap/FunctionBreakpoint.cpp  | 5 +++++
 lldb/tools/lldb-dap/SourceBreakpoint.cpp    | 5 +++++
 5 files changed, 24 insertions(+)

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

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to