[Lldb-commits] [lldb] aff601a - [lldb][windows] fix duplicate OnLoadModule events (#189376)
via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 2 06:46:06 PDT 2026
Author: Charles Zablit
Date: 2026-04-02T14:46:00+01:00
New Revision: aff601aed894dadd71ae8049502f964d0554173f
URL: https://github.com/llvm/llvm-project/commit/aff601aed894dadd71ae8049502f964d0554173f
DIFF: https://github.com/llvm/llvm-project/commit/aff601aed894dadd71ae8049502f964d0554173f.diff
LOG: [lldb][windows] fix duplicate OnLoadModule events (#189376)
Added:
Modified:
lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
index 44d671f843b74..79fb4d46eff41 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp
@@ -64,7 +64,6 @@ DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process,
void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
const ModuleSpec module_spec,
lldb::addr_t module_addr) {
-
// Resolve the module unless we already have one.
if (!module_sp) {
Status error;
@@ -74,7 +73,7 @@ void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
return;
}
- m_loaded_modules[module_sp] = module_addr;
+ m_loaded_modules.insert({module_addr, lldb::ModuleWP(module_sp)});
UpdateLoadedSectionsCommon(module_sp, module_addr, false);
ModuleList module_list;
module_list.Append(module_sp);
@@ -82,13 +81,26 @@ void DynamicLoaderWindowsDYLD::OnLoadModule(lldb::ModuleSP module_sp,
}
void DynamicLoaderWindowsDYLD::OnUnloadModule(lldb::addr_t module_addr) {
- Address resolved_addr;
- if (!m_process->GetTarget().ResolveLoadAddress(module_addr, resolved_addr))
+ auto it = m_loaded_modules.find(module_addr);
+ if (it == m_loaded_modules.end())
+ return;
+
+ ModuleSP module_sp = it->second.lock();
+ m_loaded_modules.erase(it);
+
+ if (!module_sp)
return;
- ModuleSP module_sp = resolved_addr.GetModule();
- if (module_sp) {
- m_loaded_modules.erase(module_sp);
+ bool full_unload = true;
+ for (const auto &entry : m_loaded_modules) {
+ ModuleSP other_sp = entry.second.lock();
+ if (other_sp == module_sp) {
+ UpdateLoadedSectionsCommon(module_sp, entry.first, false);
+ full_unload = false;
+ }
+ }
+
+ if (full_unload) {
UnloadSectionsCommon(module_sp);
ModuleList module_list;
module_list.Append(module_sp);
@@ -98,9 +110,11 @@ void DynamicLoaderWindowsDYLD::OnUnloadModule(lldb::addr_t module_addr) {
lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
// First, see if the load address is already cached.
- auto it = m_loaded_modules.find(executable);
- if (it != m_loaded_modules.end() && it->second != LLDB_INVALID_ADDRESS)
- return it->second;
+ for (const auto &entry : m_loaded_modules) {
+ ModuleSP mod = entry.second.lock();
+ if (mod == executable && entry.first != LLDB_INVALID_ADDRESS)
+ return entry.first;
+ }
lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
@@ -112,7 +126,7 @@ lldb::addr_t DynamicLoaderWindowsDYLD::GetLoadAddress(ModuleSP executable) {
m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr);
// Servers other than lldb server could respond with a bogus address.
if (status.Success() && is_loaded && load_addr != LLDB_INVALID_ADDRESS) {
- m_loaded_modules[executable] = load_addr;
+ m_loaded_modules.insert({load_addr, lldb::ModuleWP(executable)});
return load_addr;
}
diff --git a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
index 8b1c3c3f467f4..eebb5117b30c5 100644
--- a/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
+++ b/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h
@@ -12,8 +12,6 @@
#include "lldb/Target/DynamicLoader.h"
#include "lldb/lldb-forward.h"
-#include <map>
-
namespace lldb_private {
class DynamicLoaderWindowsDYLD : public DynamicLoader {
@@ -42,11 +40,38 @@ class DynamicLoaderWindowsDYLD : public DynamicLoader {
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
protected:
+ /// Returns the load address for the given executable module.
+ ///
+ /// The lookup proceeds in two stages:
+ ///
+ /// 1. **Cache lookup** – \c m_loaded_modules is scanned for an existing
+ /// entry whose \c ModuleSP matches \p executable. Because the same
+ /// \c ModuleSP can be inserted more than once under
diff erent base
+ /// addresses (e.g. a DLL loaded into several processes, or a module
+ /// that was unloaded and reloaded at a
diff erent address), the scan
+ /// returns the *first* valid (non-LLDB_INVALID_ADDRESS) entry it
+ /// finds.
+ ///
+ /// 2. **Process / platform query** – If no cached entry is found,
+ /// \c Process::GetFileLoadAddress is called. On a remote target the
+ /// remote platform is responsible for resolving the address. A
+ /// successful result is inserted into \c m_loaded_modules so that
+ /// subsequent calls hit the cache.
+ ///
+ /// \param executable The module whose load address is requested.
+ /// \return The load address, or \c LLDB_INVALID_ADDRESS if it
+ /// could not be determined.
lldb::addr_t GetLoadAddress(lldb::ModuleSP executable);
-private:
- std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
- m_loaded_modules;
+ /// Maps load addresses to their corresponding modules.
+ ///
+ /// Weak pointers are used intentionally: on Windows, a Module holds a
+ /// memory-mapped view of the DLL file, and an open memory mapping locks
+ /// the file on disk. Holding a strong reference (ModuleSP) here would
+ /// prevent the mapping from being released even after the Target drops
+ /// its own reference, keeping the file locked and blocking recompilation
+ /// during an active debug session.
+ llvm::DenseMap<lldb::addr_t, lldb::ModuleWP> m_loaded_modules;
};
} // namespace lldb_private
More information about the lldb-commits
mailing list