https://github.com/da-viper updated 
https://github.com/llvm/llvm-project/pull/208471

>From ca792bf4a256048f6912d940a131b162b887f971 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <[email protected]>
Date: Thu, 9 Jul 2026 15:03:29 +0100
Subject: [PATCH] [lldb-dap] Avoid data race when clearing an OptionValue

The clear function guarded by the internal mutex.
This happens when we have to threads one trying to set a value and the
other reseting the value.
---
 lldb/include/lldb/Interpreter/OptionValue.h              | 4 ++--
 lldb/include/lldb/Interpreter/OptionValueArch.h          | 2 ++
 lldb/include/lldb/Interpreter/OptionValueArray.h         | 1 +
 lldb/include/lldb/Interpreter/OptionValueBoolean.h       | 1 +
 lldb/include/lldb/Interpreter/OptionValueChar.h          | 1 +
 lldb/include/lldb/Interpreter/OptionValueDictionary.h    | 1 +
 lldb/include/lldb/Interpreter/OptionValueEnumeration.h   | 1 +
 lldb/include/lldb/Interpreter/OptionValueFileColonLine.h | 1 +
 lldb/include/lldb/Interpreter/OptionValueFileSpec.h      | 1 +
 lldb/include/lldb/Interpreter/OptionValueFormat.h        | 1 +
 lldb/include/lldb/Interpreter/OptionValueLanguage.h      | 1 +
 lldb/include/lldb/Interpreter/OptionValuePathMappings.h  | 1 +
 lldb/include/lldb/Interpreter/OptionValueRegex.h         | 1 +
 lldb/include/lldb/Interpreter/OptionValueSInt64.h        | 1 +
 lldb/include/lldb/Interpreter/OptionValueString.h        | 1 +
 lldb/include/lldb/Interpreter/OptionValueUInt64.h        | 1 +
 lldb/include/lldb/Interpreter/OptionValueUUID.h          | 1 +
 lldb/source/Interpreter/OptionValueFormatEntity.cpp      | 1 +
 lldb/source/Interpreter/OptionValueProperties.cpp        | 1 +
 19 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/lldb/include/lldb/Interpreter/OptionValue.h 
b/lldb/include/lldb/Interpreter/OptionValue.h
index 193f2e44aca1b..e364fc0817754 100644
--- a/lldb/include/lldb/Interpreter/OptionValue.h
+++ b/lldb/include/lldb/Interpreter/OptionValue.h
@@ -372,6 +372,8 @@ class OptionValue {
                                 // set from the command line or as a setting,
                                 // versus if we just have the default value 
that
                                 // was already populated in the option value.
+  mutable std::recursive_mutex m_mutex;
+
 private:
   std::optional<ArchSpec> GetArchSpecValue() const;
   bool SetArchSpecValue(ArchSpec arch_spec);
@@ -412,8 +414,6 @@ class OptionValue {
   bool SetFormatEntityValue(const FormatEntity::Entry &entry);
 
   const RegularExpression *GetRegexValue() const;
-
-  mutable std::mutex m_mutex;
 };
 
 } // namespace lldb_private
diff --git a/lldb/include/lldb/Interpreter/OptionValueArch.h 
b/lldb/include/lldb/Interpreter/OptionValueArch.h
index 8b6954f03dd29..d5092fe788691 100644
--- a/lldb/include/lldb/Interpreter/OptionValueArch.h
+++ b/lldb/include/lldb/Interpreter/OptionValueArch.h
@@ -12,6 +12,7 @@
 #include "lldb/Interpreter/OptionValue.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/CompletionRequest.h"
+#include <mutex>
 
 namespace lldb_private {
 
@@ -45,6 +46,7 @@ class OptionValueArch : public Cloneable<OptionValueArch, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueArray.h 
b/lldb/include/lldb/Interpreter/OptionValueArray.h
index 34170ef06a188..38ec01bdf51fc 100644
--- a/lldb/include/lldb/Interpreter/OptionValueArray.h
+++ b/lldb/include/lldb/Interpreter/OptionValueArray.h
@@ -36,6 +36,7 @@ class OptionValueArray : public Cloneable<OptionValueArray, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_values.clear();
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueBoolean.h 
b/lldb/include/lldb/Interpreter/OptionValueBoolean.h
index 72c1ce446b8a0..e9ac654ed5e3e 100644
--- a/lldb/include/lldb/Interpreter/OptionValueBoolean.h
+++ b/lldb/include/lldb/Interpreter/OptionValueBoolean.h
@@ -38,6 +38,7 @@ class OptionValueBoolean : public 
Cloneable<OptionValueBoolean, OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueChar.h 
b/lldb/include/lldb/Interpreter/OptionValueChar.h
index c1f83a3daf846..e6a2ed31063a1 100644
--- a/lldb/include/lldb/Interpreter/OptionValueChar.h
+++ b/lldb/include/lldb/Interpreter/OptionValueChar.h
@@ -39,6 +39,7 @@ class OptionValueChar : public Cloneable<OptionValueChar, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueDictionary.h 
b/lldb/include/lldb/Interpreter/OptionValueDictionary.h
index 800b7fc687640..8a28ee81585a4 100644
--- a/lldb/include/lldb/Interpreter/OptionValueDictionary.h
+++ b/lldb/include/lldb/Interpreter/OptionValueDictionary.h
@@ -41,6 +41,7 @@ class OptionValueDictionary
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_values.clear();
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h 
b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
index e8566934d9fc5..6536d1e900487 100644
--- a/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
+++ b/lldb/include/lldb/Interpreter/OptionValueEnumeration.h
@@ -48,6 +48,7 @@ class OptionValueEnumeration
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h 
b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h
index e2b84f9b81e65..e7dd0f9011078 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFileColonLine.h
@@ -36,6 +36,7 @@ class OptionValueFileColonLine :
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_file_spec.Clear();
     m_line_number = LLDB_INVALID_LINE_NUMBER;
     m_column_number = LLDB_INVALID_COLUMN_NUMBER;
diff --git a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h 
b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
index 66f2b2a04ff53..dd643703912e7 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFileSpec.h
@@ -44,6 +44,7 @@ class OptionValueFileSpec : public 
Cloneable<OptionValueFileSpec, OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
     m_data_sp.reset();
diff --git a/lldb/include/lldb/Interpreter/OptionValueFormat.h 
b/lldb/include/lldb/Interpreter/OptionValueFormat.h
index 661e8b507d64f..c5e593ff107e2 100644
--- a/lldb/include/lldb/Interpreter/OptionValueFormat.h
+++ b/lldb/include/lldb/Interpreter/OptionValueFormat.h
@@ -38,6 +38,7 @@ class OptionValueFormat
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueLanguage.h 
b/lldb/include/lldb/Interpreter/OptionValueLanguage.h
index 41ddb2a13f15e..50c57ac2d32f7 100644
--- a/lldb/include/lldb/Interpreter/OptionValueLanguage.h
+++ b/lldb/include/lldb/Interpreter/OptionValueLanguage.h
@@ -40,6 +40,7 @@ class OptionValueLanguage : public 
Cloneable<OptionValueLanguage, OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h 
b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
index e0aac2fd44484..0b523e7c8a7ff 100644
--- a/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
+++ b/lldb/include/lldb/Interpreter/OptionValuePathMappings.h
@@ -36,6 +36,7 @@ class OptionValuePathMappings
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_path_mappings.Clear(m_notify_changes);
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueRegex.h 
b/lldb/include/lldb/Interpreter/OptionValueRegex.h
index 2799fea1538dc..4f544d086ac96 100644
--- a/lldb/include/lldb/Interpreter/OptionValueRegex.h
+++ b/lldb/include/lldb/Interpreter/OptionValueRegex.h
@@ -37,6 +37,7 @@ class OptionValueRegex : public Cloneable<OptionValueRegex, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_regex = RegularExpression(m_default_regex_str);
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueSInt64.h 
b/lldb/include/lldb/Interpreter/OptionValueSInt64.h
index f19f3f8ab875e..b5295c20bcc8c 100644
--- a/lldb/include/lldb/Interpreter/OptionValueSInt64.h
+++ b/lldb/include/lldb/Interpreter/OptionValueSInt64.h
@@ -44,6 +44,7 @@ class OptionValueSInt64 : public Cloneable<OptionValueSInt64, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueString.h 
b/lldb/include/lldb/Interpreter/OptionValueString.h
index e199443fa8b49..8b4fc6c635839 100644
--- a/lldb/include/lldb/Interpreter/OptionValueString.h
+++ b/lldb/include/lldb/Interpreter/OptionValueString.h
@@ -78,6 +78,7 @@ class OptionValueString : public Cloneable<OptionValueString, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueUInt64.h 
b/lldb/include/lldb/Interpreter/OptionValueUInt64.h
index 2a87c19c54bbf..678c3e035541d 100644
--- a/lldb/include/lldb/Interpreter/OptionValueUInt64.h
+++ b/lldb/include/lldb/Interpreter/OptionValueUInt64.h
@@ -47,6 +47,7 @@ class OptionValueUInt64 : public Cloneable<OptionValueUInt64, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_current_value = m_default_value;
     m_value_was_set = false;
   }
diff --git a/lldb/include/lldb/Interpreter/OptionValueUUID.h 
b/lldb/include/lldb/Interpreter/OptionValueUUID.h
index 2b7d9e41bcf77..7d4e6385f27f3 100644
--- a/lldb/include/lldb/Interpreter/OptionValueUUID.h
+++ b/lldb/include/lldb/Interpreter/OptionValueUUID.h
@@ -38,6 +38,7 @@ class OptionValueUUID : public Cloneable<OptionValueUUID, 
OptionValue> {
                      VarSetOperationType op = eVarSetOperationAssign) override;
 
   void Clear() override {
+    std::lock_guard<std::recursive_mutex> lock(m_mutex);
     m_uuid.Clear();
     m_value_was_set = false;
   }
diff --git a/lldb/source/Interpreter/OptionValueFormatEntity.cpp 
b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
index b31dd4e475878..60b7b52badc9d 100644
--- a/lldb/source/Interpreter/OptionValueFormatEntity.cpp
+++ b/lldb/source/Interpreter/OptionValueFormatEntity.cpp
@@ -29,6 +29,7 @@ OptionValueFormatEntity::OptionValueFormatEntity(const char 
*default_format) {
 }
 
 void OptionValueFormatEntity::Clear() {
+  std::lock_guard<std::recursive_mutex> lock(m_mutex);
   m_current_entry = m_default_entry;
   m_current_format = m_default_format;
   m_value_was_set = false;
diff --git a/lldb/source/Interpreter/OptionValueProperties.cpp 
b/lldb/source/Interpreter/OptionValueProperties.cpp
index e62c15ec36da3..705e53d50cb58 100644
--- a/lldb/source/Interpreter/OptionValueProperties.cpp
+++ b/lldb/source/Interpreter/OptionValueProperties.cpp
@@ -304,6 +304,7 @@ OptionValueString 
*OptionValueProperties::GetPropertyAtIndexAsOptionValueString(
 }
 
 void OptionValueProperties::Clear() {
+  std::lock_guard<std::recursive_mutex> lock(m_mutex);
   const size_t num_properties = m_properties.size();
   for (size_t i = 0; i < num_properties; ++i)
     m_properties[i].GetValue()->Clear();

_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to