Skip to content

Commit ff67b68

Browse files
[lldb] On POSIX, check for duplicate interpreter modules without loading them (#69932)
Fixes #68987 Early on we load the interpreter (most commonly ld-linux) in LoadInterpreterModule. Then later when we get the first DYLD rendezvous we get a list of libraries that commonly includes ld-linux again. Previously we would load this duplicate, see that it was a duplicate, and unload it. Problem was that this unloaded the section information of the first copy of ld-linux. On platforms where you can place a breakpoint using only an address, this wasn't an issue. On ARM you have ARM and Thumb modes. We must know which one the section we're breaking in is, otherwise we'll go there in the wrong mode and SIGILL. This happened on ARM when lldb tried to call mmap during expression evaluation. To fix this, I am making the assumption that the base address we see in the module prior to loading can be compared with what we know the interpreter base address is. Then we don't have to load the module to know we can ignore it. This fixes the lldb test suite on Ubuntu versions where https://bugs.launchpad.net/ubuntu/+source/gdb/+bug/1927192 has been fixed. Which was recently done on Jammy.
1 parent e7012ba commit ff67b68

File tree

1 file changed

+8
-9
lines changed

1 file changed

+8
-9
lines changed

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

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,14 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
437437
m_initial_modules_added = true;
438438
}
439439
for (; I != E; ++I) {
440+
// Don't load a duplicate copy of ld.so if we have already loaded it
441+
// earlier in LoadInterpreterModule. If we instead loaded then unloaded it
442+
// later, the section information for ld.so would be removed. That
443+
// information is required for placing breakpoints on Arm/Thumb systems.
444+
if ((m_interpreter_module.lock() != nullptr) &&
445+
(I->base_addr == m_interpreter_base))
446+
continue;
447+
440448
ModuleSP module_sp =
441449
LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
442450
if (!module_sp.get())
@@ -450,15 +458,6 @@ void DynamicLoaderPOSIXDYLD::RefreshModules() {
450458
} else if (module_sp == interpreter_sp) {
451459
// Module already loaded.
452460
continue;
453-
} else {
454-
// If this is a duplicate instance of ld.so, unload it. We may end
455-
// up with it if we load it via a different path than before
456-
// (symlink vs real path).
457-
// TODO: remove this once we either fix library matching or avoid
458-
// loading the interpreter when setting the rendezvous breakpoint.
459-
UnloadSections(module_sp);
460-
loaded_modules.Remove(module_sp);
461-
continue;
462461
}
463462
}
464463

0 commit comments

Comments
 (0)