Skip to content

Commit 5535582

Browse files
committed
[lldb/dyld-posix] Avoid reading the module list in inconsistent states
New glibc versions (since 2.34 or including this <bminor/glibc@ed3ce71> patch) trigger the rendezvous breakpoint after they have already added some modules to the list. This did not play well with our dynamic loader plugin which was doing a diff of the the reported modules in the before (RT_ADD) and after (RT_CONSISTENT) states. Specifically, it caused us to miss some of the modules. While I think the old behavior makes more sense, I don't think that lldb is doing the right thing either, as the documentation states that we should not be expecting a consistent view in the RT_ADD (and RT_DELETE) states. Therefore, this patch changes the lldb algorithm to compare the module list against the previous consistent snapshot. This fixes the previous issue, and I believe it is more correct in general. It also reduces the number of times we are fetching the module info, which should speed up the debugging of processes with many shared libraries. The change in RefreshModules ensures we don't broadcast the loaded notification for the dynamic loader (ld.so) module more than once. Differential Revision: https://reviews.llvm.org/D128264
1 parent c0702ac commit 5535582

File tree

2 files changed

+28
-31
lines changed

2 files changed

+28
-31
lines changed

lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -210,14 +210,7 @@ DYLDRendezvous::RendezvousAction DYLDRendezvous::GetAction() const {
210210

211211
case eAdd:
212212
case eDelete:
213-
// Some versions of the android dynamic linker might send two
214-
// notifications with state == eAdd back to back. Ignore them until we
215-
// get an eConsistent notification.
216-
if (!(m_previous.state == eConsistent ||
217-
(m_previous.state == eAdd && m_current.state == eDelete)))
218-
return eNoAction;
219-
220-
return eTakeSnapshot;
213+
return eNoAction;
221214
}
222215

223216
return eNoAction;
@@ -229,9 +222,9 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
229222
if (action == eNoAction)
230223
return false;
231224

225+
m_added_soentries.clear();
226+
m_removed_soentries.clear();
232227
if (action == eTakeSnapshot) {
233-
m_added_soentries.clear();
234-
m_removed_soentries.clear();
235228
// We already have the loaded list from the previous update so no need to
236229
// find all the modules again.
237230
if (!m_loaded_modules.m_list.empty())
@@ -260,11 +253,11 @@ bool DYLDRendezvous::UpdateSOEntriesFromRemote() {
260253
}
261254

262255
bool DYLDRendezvous::UpdateSOEntries() {
256+
m_added_soentries.clear();
257+
m_removed_soentries.clear();
263258
switch (GetAction()) {
264259
case eTakeSnapshot:
265260
m_soentries.clear();
266-
m_added_soentries.clear();
267-
m_removed_soentries.clear();
268261
return TakeSnapshot(m_soentries);
269262
case eAddModules:
270263
return AddSOEntries();

lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -433,27 +433,31 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
433433
for (; I != E; ++I) {
434434
ModuleSP module_sp =
435435
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
436-
if (module_sp.get()) {
437-
if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
438-
&m_process->GetTarget()) == m_interpreter_base &&
439-
module_sp != m_interpreter_module.lock()) {
440-
if (m_interpreter_module.lock() == nullptr) {
441-
m_interpreter_module = module_sp;
442-
} else {
443-
// If this is a duplicate instance of ld.so, unload it. We may end
444-
// up with it if we load it via a different path than before
445-
// (symlink vs real path).
446-
// TODO: remove this once we either fix library matching or avoid
447-
// loading the interpreter when setting the rendezvous breakpoint.
448-
UnloadSections(module_sp);
449-
loaded_modules.Remove(module_sp);
450-
continue;
451-
}
436+
if (!module_sp.get())
437+
continue;
438+
439+
if (module_sp->GetObjectFile()->GetBaseAddress().GetLoadAddress(
440+
&m_process->GetTarget()) == m_interpreter_base) {
441+
ModuleSP interpreter_sp = m_interpreter_module.lock();
442+
if (m_interpreter_module.lock() == nullptr) {
443+
m_interpreter_module = module_sp;
444+
} else if (module_sp == interpreter_sp) {
445+
// Module already loaded.
446+
continue;
447+
} else {
448+
// If this is a duplicate instance of ld.so, unload it. We may end
449+
// up with it if we load it via a different path than before
450+
// (symlink vs real path).
451+
// TODO: remove this once we either fix library matching or avoid
452+
// loading the interpreter when setting the rendezvous breakpoint.
453+
UnloadSections(module_sp);
454+
loaded_modules.Remove(module_sp);
455+
continue;
452456
}
453-
454-
loaded_modules.AppendIfNeeded(module_sp);
455-
new_modules.Append(module_sp);
456457
}
458+
459+
loaded_modules.AppendIfNeeded(module_sp);
460+
new_modules.Append(module_sp);
457461
}
458462
m_process->GetTarget().ModulesDidLoad(new_modules);
459463
}

0 commit comments

Comments
 (0)