[Lldb-commits] [lldb] [lldb] Avoid data race when clearing an OptionValue (PR #208471)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 10 05:55:29 PDT 2026
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 <e_ezike at apple.com>
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();
More information about the lldb-commits
mailing list