[Lldb-commits] [lldb] 5752e31 - [lldb] fix dead lock in TypeCategoryMap.cpp (#87540)
via lldb-commits
lldb-commits at lists.llvm.org
Fri Apr 12 07:48:45 PDT 2024
Author: Vincent Belliard
Date: 2024-04-12T10:48:41-04:00
New Revision: 5752e3196bc52fdac70e3650abc703570ff6209b
URL: https://github.com/llvm/llvm-project/commit/5752e3196bc52fdac70e3650abc703570ff6209b
DIFF: https://github.com/llvm/llvm-project/commit/5752e3196bc52fdac70e3650abc703570ff6209b.diff
LOG: [lldb] fix dead lock in TypeCategoryMap.cpp (#87540)
FormatManager::GetCategoryForLanguage and
FormatManager::GetCategory(can_create = true) can be called concurrently
and they both take the TypeCategory::m_map_mutex and the
FormatManager::m_language_categories_mutex but in reverse order.
On one thread, GetCategoryForLanguage takes m_language_categories_mutex
and then ends calling TypeCategoryMap::Get which takes m_map_mutex
On another thread GetCategory calls TypeCategoryMap::Add which takes
m_map_mutex and then calls FormatManager::Changed() which takes
m_language_categories_mutex
If both threads are running concurrently, we have a dead lock.
The patch releases the m_map_mutex before calling Changed which avoids
the dead lock.
---------
Co-authored-by: Vincent Belliard <v-bulle at github.com>
Added:
Modified:
lldb/source/DataFormatters/TypeCategoryMap.cpp
Removed:
################################################################################
diff --git a/lldb/source/DataFormatters/TypeCategoryMap.cpp b/lldb/source/DataFormatters/TypeCategoryMap.cpp
index fd76bab95826af..ce2cf369b5be53 100644
--- a/lldb/source/DataFormatters/TypeCategoryMap.cpp
+++ b/lldb/source/DataFormatters/TypeCategoryMap.cpp
@@ -25,19 +25,31 @@ TypeCategoryMap::TypeCategoryMap(IFormatChangeListener *lst)
}
void TypeCategoryMap::Add(KeyType name, const TypeCategoryImplSP &entry) {
- std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- m_map[name] = entry;
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ m_map[name] = entry;
+ }
+ // Release the mutex to avoid a potential deadlock between
+ // TypeCategoryMap::m_map_mutex and
+ // FormatManager::m_language_categories_mutex which can be acquired in
+ // reverse order when calling FormatManager::Changed.
if (listener)
listener->Changed();
}
bool TypeCategoryMap::Delete(KeyType name) {
- std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- MapIterator iter = m_map.find(name);
- if (iter == m_map.end())
- return false;
- m_map.erase(name);
- Disable(name);
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ MapIterator iter = m_map.find(name);
+ if (iter == m_map.end())
+ return false;
+ m_map.erase(name);
+ Disable(name);
+ }
+ // Release the mutex to avoid a potential deadlock between
+ // TypeCategoryMap::m_map_mutex and
+ // FormatManager::m_language_categories_mutex which can be acquired in
+ // reverse order when calling FormatManager::Changed.
if (listener)
listener->Changed();
return true;
@@ -123,9 +135,15 @@ void TypeCategoryMap::DisableAllCategories() {
}
void TypeCategoryMap::Clear() {
- std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
- m_map.clear();
- m_active_categories.clear();
+ {
+ std::lock_guard<std::recursive_mutex> guard(m_map_mutex);
+ m_map.clear();
+ m_active_categories.clear();
+ }
+ // Release the mutex to avoid a potential deadlock between
+ // TypeCategoryMap::m_map_mutex and
+ // FormatManager::m_language_categories_mutex which can be acquired in
+ // reverse order when calling FormatManager::Changed.
if (listener)
listener->Changed();
}
More information about the lldb-commits
mailing list