[Lldb-commits] [lldb] d6a906b - [LLDB] Acquire the module mutex at the start of SetLoadAddress (#227149)

via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 1 11:53:42 PDT 2026


Author: Jacob Lalonde
Date: 2026-10-01T11:53:36-07:00
New Revision: d6a906b6d5c3708edf68faf90ebdf1371e03c89b

URL: https://github.com/llvm/llvm-project/commit/d6a906b6d5c3708edf68faf90ebdf1371e03c89b
DIFF: https://github.com/llvm/llvm-project/commit/d6a906b6d5c3708edf68faf90ebdf1371e03c89b.diff

LOG: [LLDB] Acquire the module mutex at the start of SetLoadAddress (#227149)

Fixes a potential dead-lock from parallel module loading. 

I received a quick-stack of LLDB hung loading a core with parallel
module loading enabled, where two threads were trying to mutate a given
module and an object file, but having acquired the module mutex first in
one case, and the object file's section mutex first in the second case,
which each trying to subsequently acquire the other lock.

In the update case, [SetLoadAddress acquires the section list mutex and
then tries to acquire the module
mutex](https://github.com/llvm/llvm-project/blob/60f717946cb5ca911b6be22169b9bd646225c59f/lldb/source/Symbol/ObjectFile.cpp#L614)

```
SectionList *ObjectFile::GetSectionList(bool update_module_section_list) {
  std::lock_guard<std::recursive_mutex> guard(m_sections_mutex);
  if (m_sections_up)
    return m_sections_up.get();
  if (update_module_section_list) {
    if (ModuleSP module_sp = GetModule()) {
      std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
      CreateSections(*module_sp->GetUnifiedSectionList());
    }
  } else {
    SectionList unified_section_list;
    CreateSections(unified_section_list);
  }
  return m_sections_up.get();
}
```

While in the other thread, `GetUUID` in `ObjectFileELF` [ultimately
calls
into](https://github.com/llvm/llvm-project/blob/6fee55d8425e735e652968007ee0d6bc35aa6f26/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp#L1039)
`GetSectionList()` [which tries to acquire the section list
mutex](https://github.com/llvm/llvm-project/blob/6fee55d8425e735e652968007ee0d6bc35aa6f26/lldb/source/Symbol/ObjectFile.cpp#L614).
Causing us to deadlock.

To fix this I have module acquire it's own mutex when calling into a
method which may subsequently try to acquire the mutex again in the
object file's critical section. This also fits with my mental module of
accessing object files, which starts in the module and then calls into
the object file. I do find it a bit weird the object file acquires the
lock, but I haven't actually looked at any old commits to figure out
why.

Added: 
    

Modified: 
    lldb/source/Core/Module.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 989410b23c997..2d7cffb7b4398 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1447,6 +1447,10 @@ bool Module::SetArchitecture(const ArchSpec &new_arch) {
 
 bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
                             bool value_is_offset, bool &changed) {
+  // Acquire the module mutex so that any re-entrant calls in
+  // ObjectFile::SetLoadAddress already own the recurisve mutex before
+  // acquiring a second lock.
+  std::lock_guard<std::recursive_mutex> guard(m_mutex);
   ObjectFile *object_file = GetObjectFile();
   if (object_file != nullptr) {
     changed = object_file->SetLoadAddress(target, value, value_is_offset);


        


More information about the lldb-commits mailing list