https://github.com/Teemperor created 
https://github.com/llvm/llvm-project/pull/220209

CompileUnit parses its line table, support files, language, debug macros and 
imported modules on demand. This lazy parsing logic currently doesn't use any 
synchronization mechanism. The result is that some common tasks that touch the 
same module end up randomly failing.

This patch locks all these data structures using the Module's lock.

assisted-by: claude

>From 1428e7c7da419badc1d541fbbb7087693e486223 Mon Sep 17 00:00:00 2001
From: Raphael Isemann <[email protected]>
Date: Fri, 14 Aug 2026 11:17:42 +0100
Subject: [PATCH] [lldb] Guard CompileUnit's lazily parsed data with the
 Module's lock

CompileUnit parses its line table, support files, language, debug
macros and imported modules on demand. This lazy parsing logic
currently doesn't use any synchronization mechanism. The result is that
some common tasks that touch the same module end up randomly failing.

This patch locks all these data structures using the Module's lock.

assisted-by: claude
---
 lldb/source/Symbol/CompileUnit.cpp | 45 ++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Symbol/CompileUnit.cpp 
b/lldb/source/Symbol/CompileUnit.cpp
index 703ef131ad6bf..e69915ec614bb 100644
--- a/lldb/source/Symbol/CompileUnit.cpp
+++ b/lldb/source/Symbol/CompileUnit.cpp
@@ -153,10 +153,16 @@ FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t 
func_uid) {
 }
 
 lldb::LanguageType CompileUnit::GetLanguage() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_language;
+
+  // See GetLineTable() for why this takes the Module's lock.
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_language == eLanguageTypeUnknown) {
     if (m_flags.IsClear(flagsParsedLanguage)) {
       m_flags.Set(flagsParsedLanguage);
-      if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+      if (SymbolFile *symfile = module_sp->GetSymbolFile())
         m_language = symfile->ParseLanguage(*this);
     }
   }
@@ -164,10 +170,17 @@ lldb::LanguageType CompileUnit::GetLanguage() {
 }
 
 LineTable *CompileUnit::GetLineTable() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_line_table_up.get();
+
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_line_table_up == nullptr) {
+    // The flag is set before parsing so that a SymbolFile that asks for the
+    // line table while parsing it doesn't recurse forever.
     if (m_flags.IsClear(flagsParsedLineTable)) {
       m_flags.Set(flagsParsedLineTable);
-      if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+      if (SymbolFile *symfile = module_sp->GetSymbolFile())
         symfile->ParseLineTable(*this);
     }
   }
@@ -183,10 +196,15 @@ void CompileUnit::SetLineTable(LineTable *line_table) {
 }
 
 DebugMacros *CompileUnit::GetDebugMacros() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_debug_macros_sp.get();
+
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_debug_macros_sp.get() == nullptr) {
     if (m_flags.IsClear(flagsParsedDebugMacros)) {
       m_flags.Set(flagsParsedDebugMacros);
-      if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+      if (SymbolFile *symfile = module_sp->GetSymbolFile())
         symfile->ParseDebugMacros(*this);
     }
   }
@@ -490,9 +508,14 @@ void CompileUnit::ResolveSymbolContext(
 }
 
 bool CompileUnit::GetIsOptimized() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_is_optimized == eLazyBoolYes;
+
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_is_optimized == eLazyBoolCalculate) {
     m_is_optimized = eLazyBoolNo;
-    if (SymbolFile *symfile = GetModule()->GetSymbolFile()) {
+    if (SymbolFile *symfile = module_sp->GetSymbolFile()) {
       if (symfile->ParseIsOptimized(*this))
         m_is_optimized = eLazyBoolYes;
     }
@@ -505,10 +528,15 @@ void CompileUnit::SetVariableList(VariableListSP 
&variables) {
 }
 
 const std::vector<SourceModule> &CompileUnit::GetImportedModules() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_imported_modules;
+
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_imported_modules.empty() &&
       m_flags.IsClear(flagsParsedImportedModules)) {
     m_flags.Set(flagsParsedImportedModules);
-    if (SymbolFile *symfile = GetModule()->GetSymbolFile()) {
+    if (SymbolFile *symfile = module_sp->GetSymbolFile()) {
       SymbolContext sc;
       CalculateSymbolContext(&sc);
       symfile->ParseImportedModules(sc, m_imported_modules);
@@ -526,10 +554,15 @@ bool CompileUnit::ForEachExternalModule(
 }
 
 const SupportFileList &CompileUnit::GetSupportFiles() {
+  ModuleSP module_sp = GetModule();
+  if (!module_sp)
+    return m_support_files;
+
+  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
   if (m_support_files.GetSize() == 0) {
     if (m_flags.IsClear(flagsParsedSupportFiles)) {
       m_flags.Set(flagsParsedSupportFiles);
-      if (SymbolFile *symfile = GetModule()->GetSymbolFile())
+      if (SymbolFile *symfile = module_sp->GetSymbolFile())
         symfile->ParseSupportFiles(*this, m_support_files);
     }
   }

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

Reply via email to