[Lldb-commits] [PATCH] D40470: DWZ 07/12: Protect DWARFCompileUnit::m_die_array by a new mutex

Jan Kratochvil via Phabricator via lldb-commits lldb-commits at lists.llvm.org
Sun Nov 26 05:12:20 PST 2017


jankratochvil created this revision.
Herald added subscribers: JDevlieghere, aprantl.

Multiple DW_TAG_compile_unit being indexed in a multithreaded way can request reading of the same DW_TAG_partial_unit.

Unfortunately one cannot detect DWZ file ahead of time to disable such locking overhead as DWARFCompileUnit::Extract does not read the first DIE which is the only place one could find early enough if the DWARF file is using any DW_TAG_partial_unit.

All DWZ patches are also applied in: git clone -b dwz git://git.jankratochvil.net/lldb


https://reviews.llvm.org/D40470

Files:
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h


Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -70,6 +70,9 @@
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
   dw_offset_t m_file_offset;
 
+  std::mutex m_extractdies_mutex;
+  bool m_die_array_finished;
+
 private:
   static uint8_t g_default_addr_size;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -91,6 +91,8 @@
 
 void DWARFCompileUnit::ClearDIEs(bool keep_compile_unit_die) {
   if (m_data->m_die_array.size() > 1) {
+    std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+
     // std::vectors never get any smaller when resized to a smaller size,
     // or when clear() or erase() are called, the size will report that it
     // is smaller, but the memory allocated remains intact (call capacity()
@@ -118,9 +120,21 @@
 // done.
 //----------------------------------------------------------------------
 size_t DWARFCompileUnit::ExtractDIEsIfNeeded(bool cu_die_only) {
-  const size_t initial_die_array_size = m_data->m_die_array.size();
-  if ((cu_die_only && initial_die_array_size > 0) || initial_die_array_size > 1)
-    return 0; // Already parsed
+  size_t initial_die_array_size;
+  auto already_parsed = [cu_die_only, &initial_die_array_size]() -> bool {
+    return (cu_die_only && initial_die_array_size > 0)
+        || initial_die_array_size > 1;
+  };
+  if (already_parsed() && m_data->m_die_array_finished)
+    return 0;
+  std::lock_guard<std::mutex> guard(m_data->m_extractdies_mutex);
+  if (already_parsed()) {
+    lldbassert(m_data->m_die_array_finished);
+    return 0;
+  }
+  m_data->m_die_array_finished = false;
+  std::shared_ptr<void> m_die_array_finished_set(nullptr,
+      [&](void*){ m_data->m_die_array_finished = true; });
 
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
   Timer scoped_timer(


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40470.124296.patch
Type: text/x-patch
Size: 2167 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20171126/5aea9f1c/attachment-0001.bin>


More information about the lldb-commits mailing list